Skip to content

Commit b34555d

Browse files
jnthntatumcopybara-github
authored andcommitted
Default opt-in to updated reflection implementation.
PiperOrigin-RevId: 968084026
1 parent 5053f46 commit b34555d

16 files changed

Lines changed: 1566 additions & 99 deletions

common/BUILD

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -793,10 +793,7 @@ cc_library(
793793
"//eval/internal:cel_value_equal",
794794
"//eval/public:cel_value",
795795
"//eval/public:message_wrapper",
796-
"//eval/public/containers:field_backed_list_impl",
797-
"//eval/public/containers:field_backed_map_impl",
798796
"//eval/public/structs:cel_proto_wrap_util",
799-
"//eval/public/structs:legacy_type_adapter",
800797
"//eval/public/structs:legacy_type_info_apis",
801798
"//eval/public/structs:proto_message_type_adapter",
802799
"//eval/public/structs:trivial_legacy_type_info_internal",
@@ -865,6 +862,8 @@ cc_test(
865862
":value_kind",
866863
":value_testing",
867864
"//base:attributes",
865+
"//eval/public:cel_value",
866+
"//eval/public/structs:proto_message_type_adapter",
868867
"//internal:parse_text_proto",
869868
"//internal:status_macros",
870869
"//internal:testing",

common/legacy_value.cc

Lines changed: 90 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,20 @@
4343
#include "common/unknown.h"
4444
#include "common/value.h"
4545
#include "common/value_kind.h"
46+
#include "common/values/legacy_list_value.h"
47+
#include "common/values/legacy_map_value.h"
4648
#include "common/values/list_value_builder.h"
4749
#include "common/values/map_value_builder.h"
4850
#include "common/values/values.h"
4951
#include "eval/internal/cel_value_equal.h"
5052
#include "eval/public/cel_value.h"
51-
#include "eval/public/containers/field_backed_list_impl.h"
52-
#include "eval/public/containers/field_backed_map_impl.h"
5353
#include "eval/public/message_wrapper.h"
5454
#include "eval/public/structs/cel_proto_wrap_util.h"
55-
#include "eval/public/structs/legacy_type_adapter.h"
5655
#include "eval/public/structs/legacy_type_info_apis.h"
5756
#include "eval/public/structs/proto_message_type_adapter.h"
5857
#include "eval/public/structs/trivial_legacy_type_info_internal.h"
5958
#include "internal/json.h"
6059
#include "internal/status_macros.h"
61-
#include "internal/well_known_types.h"
6260
#include "runtime/runtime_options.h"
6361
#include "google/protobuf/arena.h"
6462
#include "google/protobuf/descriptor.h"
@@ -76,13 +74,9 @@ using ::cel::interop_internal::TrivialTypeInfo;
7674
using ::google::api::expr::runtime::CelList;
7775
using ::google::api::expr::runtime::CelMap;
7876
using ::google::api::expr::runtime::CelValue;
79-
using ::google::api::expr::runtime::CreateCelValueFromField;
80-
using ::google::api::expr::runtime::FieldBackedListImpl;
81-
using ::google::api::expr::runtime::FieldBackedMapImpl;
8277
using ::google::api::expr::runtime::GetGenericProtoTypeInfoInstance;
8378
using ::google::api::expr::runtime::LegacyTypeInfoApis;
8479
using ::google::api::expr::runtime::MessageWrapper;
85-
using ::google::api::expr::runtime::internal::GetGenericProtoAccessApisInstance;
8680
using ::google::api::expr::runtime::internal::MaybeWrapValueToMessage;
8781

8882
absl::Status InvalidMapKeyTypeError(ValueKind kind) {
@@ -284,19 +278,17 @@ CelValue LegacyTrivialListValue(google::protobuf::Arena* absl_nonnull arena,
284278
}
285279
if (auto parsed_repeated_field_value = value.AsParsedRepeatedField();
286280
parsed_repeated_field_value) {
287-
auto maybe_cloned = parsed_repeated_field_value->Clone(arena);
288-
return CelValue::CreateList(google::protobuf::Arena::Create<FieldBackedListImpl>(
289-
arena, &maybe_cloned.message(), maybe_cloned.field(), arena));
281+
auto wrapped = common_internal::WrapLegacyParsedRepeatedField(
282+
*parsed_repeated_field_value, arena);
283+
return CelValue::CreateList(
284+
common_internal::AsLegacyListValue(wrapped)->cel_list());
290285
}
291286
if (auto parsed_json_list_value = value.AsParsedJsonList();
292287
parsed_json_list_value) {
293-
auto maybe_cloned = parsed_json_list_value->Clone(arena);
294-
return CelValue::CreateList(google::protobuf::Arena::Create<FieldBackedListImpl>(
295-
arena, cel::to_address(maybe_cloned),
296-
well_known_types::GetListValueReflectionOrDie(
297-
maybe_cloned->GetDescriptor())
298-
.GetValuesDescriptor(),
299-
arena));
288+
auto wrapped = common_internal::WrapLegacyParsedJsonList(
289+
*parsed_json_list_value, arena);
290+
return CelValue::CreateList(
291+
common_internal::AsLegacyListValue(wrapped)->cel_list());
300292
}
301293
if (auto custom_list_value = value.AsCustomList(); custom_list_value) {
302294
auto status_or_compat_list = common_internal::MakeCompatListValue(
@@ -322,19 +314,17 @@ CelValue LegacyTrivialMapValue(google::protobuf::Arena* absl_nonnull arena,
322314
}
323315
if (auto parsed_map_field_value = value.AsParsedMapField();
324316
parsed_map_field_value) {
325-
auto maybe_cloned = parsed_map_field_value->Clone(arena);
326-
return CelValue::CreateMap(google::protobuf::Arena::Create<FieldBackedMapImpl>(
327-
arena, &maybe_cloned.message(), maybe_cloned.field(), arena));
317+
auto wrapped = common_internal::WrapLegacyParsedMapField(
318+
*parsed_map_field_value, arena);
319+
return CelValue::CreateMap(
320+
common_internal::AsLegacyMapValue(wrapped)->cel_map());
328321
}
329322
if (auto parsed_json_map_value = value.AsParsedJsonMap();
330323
parsed_json_map_value) {
331-
auto maybe_cloned = parsed_json_map_value->Clone(arena);
332-
return CelValue::CreateMap(google::protobuf::Arena::Create<FieldBackedMapImpl>(
333-
arena, cel::to_address(maybe_cloned),
334-
well_known_types::GetStructReflectionOrDie(
335-
maybe_cloned->GetDescriptor())
336-
.GetFieldsDescriptor(),
337-
arena));
324+
auto wrapped =
325+
common_internal::WrapLegacyParsedJsonMap(*parsed_json_map_value, arena);
326+
return CelValue::CreateMap(
327+
common_internal::AsLegacyMapValue(wrapped)->cel_map());
338328
}
339329
if (auto custom_map_value = value.AsCustomMap(); custom_map_value) {
340330
auto status_or_compat_map = common_internal::MakeCompatMapValue(
@@ -352,6 +342,25 @@ CelValue LegacyTrivialMapValue(google::protobuf::Arena* absl_nonnull arena,
352342
value.GetRuntimeType().DebugString()))));
353343
}
354344

345+
LegacyStructValue ParsedMessageToLegacyStructValue(
346+
const ParsedMessageValue& parsed_message) {
347+
return LegacyStructValue(cel::to_address(parsed_message),
348+
&GetGenericProtoTypeInfoInstance());
349+
}
350+
351+
LegacyStructValue MakeLegacyStructValue(
352+
const google::protobuf::Message* absl_nonnull message,
353+
const LegacyTypeInfoApis* legacy_type_info) {
354+
// Guard against edge cases where a custom implementation of Message
355+
// misbehaves.
356+
// Modern value handles this with DCHECKs on value creation, legacy value
357+
// would allow it and just report an ErrorValue on accesses.
358+
if (message->GetReflection() == nullptr || legacy_type_info == nullptr) {
359+
legacy_type_info = TrivialTypeInfo::GetInstance();
360+
}
361+
return LegacyStructValue(message, legacy_type_info);
362+
}
363+
355364
} // namespace
356365

357366
google::api::expr::runtime::CelValue UnsafeLegacyValue(
@@ -394,10 +403,6 @@ google::api::expr::runtime::CelValue UnsafeLegacyValue(
394403
}
395404
}
396405

397-
} // namespace common_internal
398-
399-
namespace common_internal {
400-
401406
std::string LegacyListValue::DebugString() const {
402407
return CelValue::CreateList(impl_).DebugString();
403408
}
@@ -837,10 +842,8 @@ absl::Status LegacyStructValue::SerializeTo(
837842
ABSL_DCHECK(message_factory != nullptr);
838843
ABSL_DCHECK(output != nullptr);
839844

840-
auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_);
841845
if (ABSL_PREDICT_TRUE(
842-
message_wrapper.message_ptr()->SerializePartialToZeroCopyStream(
843-
output))) {
846+
message_ptr_->SerializePartialToZeroCopyStream(output))) {
844847
return absl::OkStatus();
845848
}
846849
return absl::UnknownError("failed to serialize protocol buffer message");
@@ -918,17 +921,26 @@ absl::Status LegacyStructValue::GetFieldByName(
918921
const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
919922
google::protobuf::MessageFactory* absl_nonnull message_factory,
920923
google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const {
921-
auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_);
922924
if (ABSL_PREDICT_FALSE(legacy_type_info_ == TrivialTypeInfo::GetInstance())) {
923925
*result = NoSuchFieldError(name);
924926
return absl::OkStatus();
925927
}
926-
CEL_ASSIGN_OR_RETURN(auto cel_value,
927-
GetGenericProtoAccessApisInstance().GetField(
928-
name, message_wrapper, unboxing_options,
929-
MemoryManagerRef::Pooling(arena)));
930-
CEL_RETURN_IF_ERROR(ModernValue(arena, cel_value, *result));
931-
return absl::OkStatus();
928+
929+
ParsedMessageValue parsed_message = UnsafeParsedMessageValue(message_ptr_);
930+
const auto* descriptor = parsed_message.GetDescriptor();
931+
const auto* field = descriptor->FindFieldByName(name);
932+
if (field == nullptr) {
933+
field = descriptor->file()->pool()->FindExtensionByPrintableName(descriptor,
934+
name);
935+
if (field == nullptr) {
936+
*result = NoSuchFieldError(name);
937+
return absl::OkStatus();
938+
}
939+
}
940+
941+
return interop_internal::WrapLegacyMessageField(
942+
message_ptr_, field, unboxing_options, descriptor_pool, message_factory,
943+
arena, result);
932944
}
933945

934946
absl::Status LegacyStructValue::GetFieldByNumber(
@@ -980,7 +992,6 @@ absl::Status LegacyStructValue::Qualify(
980992
if (ABSL_PREDICT_FALSE(qualifiers.empty())) {
981993
return absl::InvalidArgumentError("invalid select qualifier path.");
982994
}
983-
auto message_wrapper = AsMessageWrapper(message_ptr_, legacy_type_info_);
984995
if (ABSL_PREDICT_FALSE(legacy_type_info_ == TrivialTypeInfo::GetInstance())) {
985996
absl::string_view field_name = absl::visit(
986997
absl::Overload(
@@ -995,12 +1006,13 @@ absl::Status LegacyStructValue::Qualify(
9951006
*count = -1;
9961007
return absl::OkStatus();
9971008
}
998-
CEL_ASSIGN_OR_RETURN(auto legacy_result,
999-
GetGenericProtoAccessApisInstance().Qualify(
1000-
qualifiers, message_wrapper, presence_test,
1001-
MemoryManager::Pooling(arena)));
1002-
CEL_RETURN_IF_ERROR(ModernValue(arena, legacy_result.value, *result));
1003-
*count = legacy_result.qualifier_count;
1009+
1010+
ParsedMessageValue parsed_message = UnsafeParsedMessageValue(message_ptr_);
1011+
CEL_RETURN_IF_ERROR(parsed_message.Qualify(qualifiers, presence_test,
1012+
descriptor_pool, message_factory,
1013+
arena, result, count));
1014+
1015+
interop_internal::WrapLegacyFieldAccessResult(arena, result);
10041016
return absl::OkStatus();
10051017
}
10061018

@@ -1035,7 +1047,7 @@ absl::Status ModernValue(google::protobuf::Arena* arena,
10351047
return absl::OkStatus();
10361048
case CelValue::Type::kMessage: {
10371049
auto message_wrapper = legacy_value.MessageWrapperOrDie();
1038-
result = common_internal::LegacyStructValue(
1050+
result = common_internal::MakeLegacyStructValue(
10391051
google::protobuf::DownCastMessage<google::protobuf::Message>(
10401052
message_wrapper.message_ptr()),
10411053
message_wrapper.legacy_type_info());
@@ -1153,7 +1165,7 @@ absl::StatusOr<Value> FromLegacyValue(google::protobuf::Arena* arena,
11531165
legacy_value.BytesOrDie().value());
11541166
case CelValue::Type::kMessage: {
11551167
auto message_wrapper = legacy_value.MessageWrapperOrDie();
1156-
return common_internal::LegacyStructValue(
1168+
return common_internal::MakeLegacyStructValue(
11571169
google::protobuf::DownCastMessage<google::protobuf::Message>(
11581170
message_wrapper.message_ptr()),
11591171
message_wrapper.legacy_type_info());
@@ -1262,6 +1274,23 @@ google::api::expr::runtime::CelValue ModernValueToLegacyValueOrDie(
12621274
return std::move(*status_or_value);
12631275
}
12641276

1277+
void WrapLegacyFieldAccessResult(google::protobuf::Arena* absl_nonnull arena,
1278+
Value* absl_nonnull result) {
1279+
if (result->IsParsedMessage()) {
1280+
*result = common_internal::ParsedMessageToLegacyStructValue(
1281+
result->GetParsedMessage());
1282+
} else if (result->IsParsedRepeatedField()) {
1283+
*result =
1284+
WrapLegacyParsedRepeatedField(result->GetParsedRepeatedField(), arena);
1285+
} else if (result->IsParsedJsonList()) {
1286+
*result = WrapLegacyParsedJsonList(result->GetParsedJsonList(), arena);
1287+
} else if (result->IsParsedMapField()) {
1288+
*result = WrapLegacyParsedMapField(result->GetParsedMapField(), arena);
1289+
} else if (result->IsParsedJsonMap()) {
1290+
*result = WrapLegacyParsedJsonMap(result->GetParsedJsonMap(), arena);
1291+
}
1292+
}
1293+
12651294
TypeValue CreateTypeValueFromView(google::protobuf::Arena* arena,
12661295
absl::string_view input) {
12671296
return TypeValue(common_internal::LegacyRuntimeType(input));
@@ -1289,12 +1318,17 @@ const google::protobuf::Message* absl_nullable GetLegacyMessage(const Value& val
12891318
absl::Status WrapLegacyMessageField(
12901319
const google::protobuf::Message* absl_nonnull message,
12911320
const google::protobuf::FieldDescriptor* absl_nonnull field_descriptor,
1292-
ProtoWrapperTypeOptions unboxing_option, google::protobuf::Arena* arena,
1321+
ProtoWrapperTypeOptions unboxing_option,
1322+
const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
1323+
google::protobuf::MessageFactory* absl_nonnull message_factory, google::protobuf::Arena* arena,
12931324
Value* absl_nonnull out) {
1294-
CEL_ASSIGN_OR_RETURN(CelValue result,
1295-
CreateCelValueFromField(message, field_descriptor,
1296-
unboxing_option, arena));
1297-
return ModernValue(arena, result, *out);
1325+
ParsedMessageValue parsed_message = UnsafeParsedMessageValue(message);
1326+
CEL_RETURN_IF_ERROR(parsed_message.GetField(field_descriptor, unboxing_option,
1327+
descriptor_pool, message_factory,
1328+
arena, out));
1329+
WrapLegacyFieldAccessResult(arena, out);
1330+
1331+
return absl::OkStatus();
12981332
}
12991333

13001334
} // namespace interop_internal

common/legacy_value.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,32 @@ google::api::expr::runtime::CelValue UnsafeLegacyValue(
5959

6060
} // namespace cel
6161

62+
namespace proto2 {
63+
class MessageFactory;
64+
} // namespace proto2
65+
6266
namespace cel::interop_internal {
6367

6468
// Returns the underlying `google::protobuf::Message` of a `cel::Value` if it is a legacy
6569
// message with the default type info, or `nullptr` otherwise.
6670
const google::protobuf::Message* absl_nullable GetLegacyMessage(const Value& value);
6771

72+
// Helper for wrapping a field accesses for the legacy runtime.
73+
//
74+
// Adapts the output to avoid further allocations when converting to a legacy
75+
// value when possible.
76+
void WrapLegacyFieldAccessResult(google::protobuf::Arena* absl_nonnull arena,
77+
Value* absl_nonnull result);
78+
6879
// Access a field on a legacy message value, writing the result to `out`.
6980
// Prefers wrapping legacy values instead of using the modern value
7081
// representation.
7182
absl::Status WrapLegacyMessageField(
7283
const google::protobuf::Message* absl_nonnull message,
7384
const google::protobuf::FieldDescriptor* absl_nonnull field_descriptor,
74-
ProtoWrapperTypeOptions unboxing_option, google::protobuf::Arena* arena,
85+
ProtoWrapperTypeOptions unboxing_option,
86+
const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
87+
google::protobuf::MessageFactory* absl_nonnull message_factory, google::protobuf::Arena* arena,
7588
Value* absl_nonnull out);
7689

7790
absl::StatusOr<Value> FromLegacyValue(

0 commit comments

Comments
 (0)