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"
@@ -77,12 +76,9 @@ using ::google::api::expr::runtime::CelList;
7776using ::google::api::expr::runtime::CelMap;
7877using ::google::api::expr::runtime::CelValue;
7978using ::google::api::expr::runtime::CreateCelValueFromField;
80- using ::google::api::expr::runtime::FieldBackedListImpl;
81- using ::google::api::expr::runtime::FieldBackedMapImpl;
8279using ::google::api::expr::runtime::GetGenericProtoTypeInfoInstance;
8380using ::google::api::expr::runtime::LegacyTypeInfoApis;
8481using ::google::api::expr::runtime::MessageWrapper;
85- using ::google::api::expr::runtime::internal::GetGenericProtoAccessApisInstance;
8682using ::google::api::expr::runtime::internal::MaybeWrapValueToMessage;
8783
8884absl::Status InvalidMapKeyTypeError (ValueKind kind) {
@@ -284,19 +280,17 @@ CelValue LegacyTrivialListValue(google::protobuf::Arena* absl_nonnull arena,
284280 }
285281 if (auto parsed_repeated_field_value = value.AsParsedRepeatedField ();
286282 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));
283+ auto wrapped = common_internal::WrapLegacyParsedRepeatedField (
284+ *parsed_repeated_field_value, arena);
285+ return CelValue::CreateList (
286+ common_internal::AsLegacyListValue (wrapped)->cel_list ());
290287 }
291288 if (auto parsed_json_list_value = value.AsParsedJsonList ();
292289 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));
290+ auto wrapped = common_internal::WrapLegacyParsedJsonList (
291+ *parsed_json_list_value, arena);
292+ return CelValue::CreateList (
293+ common_internal::AsLegacyListValue (wrapped)->cel_list ());
300294 }
301295 if (auto custom_list_value = value.AsCustomList (); custom_list_value) {
302296 auto status_or_compat_list = common_internal::MakeCompatListValue (
@@ -322,19 +316,17 @@ CelValue LegacyTrivialMapValue(google::protobuf::Arena* absl_nonnull arena,
322316 }
323317 if (auto parsed_map_field_value = value.AsParsedMapField ();
324318 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));
319+ auto wrapped = common_internal::WrapLegacyParsedMapField (
320+ *parsed_map_field_value, arena);
321+ return CelValue::CreateMap (
322+ common_internal::AsLegacyMapValue (wrapped)->cel_map ());
328323 }
329324 if (auto parsed_json_map_value = value.AsParsedJsonMap ();
330325 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));
326+ auto wrapped =
327+ common_internal::WrapLegacyParsedJsonMap (*parsed_json_map_value, arena);
328+ return CelValue::CreateMap (
329+ common_internal::AsLegacyMapValue (wrapped)->cel_map ());
338330 }
339331 if (auto custom_map_value = value.AsCustomMap (); custom_map_value) {
340332 auto status_or_compat_map = common_internal::MakeCompatMapValue (
@@ -352,6 +344,25 @@ CelValue LegacyTrivialMapValue(google::protobuf::Arena* absl_nonnull arena,
352344 value.GetRuntimeType ().DebugString ()))));
353345}
354346
347+ LegacyStructValue ParsedMessageToLegacyStructValue (
348+ const ParsedMessageValue& parsed_message) {
349+ return LegacyStructValue (cel::to_address (parsed_message),
350+ &GetGenericProtoTypeInfoInstance ());
351+ }
352+
353+ LegacyStructValue MakeLegacyStructValue (
354+ const google::protobuf::Message* absl_nonnull message,
355+ const LegacyTypeInfoApis* legacy_type_info) {
356+ // Guard against edge cases where a custom implementation of Message
357+ // misbehaves.
358+ // Modern value handles this with DCHECKs on value creation, legacy value
359+ // would allow it and just report an ErrorValue on accesses.
360+ if (message->GetReflection () == nullptr || legacy_type_info == nullptr ) {
361+ legacy_type_info = TrivialTypeInfo::GetInstance ();
362+ }
363+ return LegacyStructValue (message, legacy_type_info);
364+ }
365+
355366} // namespace
356367
357368google::api::expr::runtime::CelValue UnsafeLegacyValue (
@@ -394,10 +405,6 @@ google::api::expr::runtime::CelValue UnsafeLegacyValue(
394405 }
395406}
396407
397- } // namespace common_internal
398-
399- namespace common_internal {
400-
401408std::string LegacyListValue::DebugString () const {
402409 return CelValue::CreateList (impl_).DebugString ();
403410}
@@ -837,10 +844,8 @@ absl::Status LegacyStructValue::SerializeTo(
837844 ABSL_DCHECK (message_factory != nullptr );
838845 ABSL_DCHECK (output != nullptr );
839846
840- auto message_wrapper = AsMessageWrapper (message_ptr_, legacy_type_info_);
841847 if (ABSL_PREDICT_TRUE (
842- message_wrapper.message_ptr ()->SerializePartialToZeroCopyStream (
843- output))) {
848+ message_ptr_->SerializePartialToZeroCopyStream (output))) {
844849 return absl::OkStatus ();
845850 }
846851 return absl::UnknownError (" failed to serialize protocol buffer message" );
@@ -918,16 +923,38 @@ absl::Status LegacyStructValue::GetFieldByName(
918923 const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
919924 google::protobuf::MessageFactory* absl_nonnull message_factory,
920925 google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const {
921- auto message_wrapper = AsMessageWrapper (message_ptr_, legacy_type_info_);
922926 if (ABSL_PREDICT_FALSE (legacy_type_info_ == TrivialTypeInfo::GetInstance ())) {
923927 *result = NoSuchFieldError (name);
924928 return absl::OkStatus ();
925929 }
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));
930+
931+ ParsedMessageValue parsed_message = UnsafeParsedMessageValue (message_ptr_);
932+ const auto * descriptor = parsed_message.GetDescriptor ();
933+ const auto * field = descriptor->FindFieldByName (name);
934+ if (field == nullptr ) {
935+ field = descriptor->file ()->pool ()->FindExtensionByPrintableName (descriptor,
936+ name);
937+ if (field == nullptr ) {
938+ *result = NoSuchFieldError (name);
939+ return absl::OkStatus ();
940+ }
941+ }
942+
943+ if (field->is_map ()) {
944+ *result = WrapLegacyParsedMapField (
945+ UnsafeParsedMapFieldValue (message_ptr_, field), arena);
946+ return absl::OkStatus ();
947+ }
948+ if (field->is_repeated ()) {
949+ *result = WrapLegacyParsedRepeatedField (
950+ UnsafeParsedRepeatedFieldValue (message_ptr_, field), arena);
951+ return absl::OkStatus ();
952+ }
953+
954+ CEL_RETURN_IF_ERROR (parsed_message.GetField (field, unboxing_options,
955+ descriptor_pool, message_factory,
956+ arena, result));
957+ interop_internal::WrapLegacyFieldAccessResult (arena, result);
931958 return absl::OkStatus ();
932959}
933960
@@ -980,7 +1007,6 @@ absl::Status LegacyStructValue::Qualify(
9801007 if (ABSL_PREDICT_FALSE (qualifiers.empty ())) {
9811008 return absl::InvalidArgumentError (" invalid select qualifier path." );
9821009 }
983- auto message_wrapper = AsMessageWrapper (message_ptr_, legacy_type_info_);
9841010 if (ABSL_PREDICT_FALSE (legacy_type_info_ == TrivialTypeInfo::GetInstance ())) {
9851011 absl::string_view field_name = absl::visit (
9861012 absl::Overload (
@@ -995,12 +1021,13 @@ absl::Status LegacyStructValue::Qualify(
9951021 *count = -1 ;
9961022 return absl::OkStatus ();
9971023 }
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 ;
1024+
1025+ ParsedMessageValue parsed_message = UnsafeParsedMessageValue (message_ptr_);
1026+ CEL_RETURN_IF_ERROR (parsed_message.Qualify (qualifiers, presence_test,
1027+ descriptor_pool, message_factory,
1028+ arena, result, count));
1029+
1030+ interop_internal::WrapLegacyFieldAccessResult (arena, result);
10041031 return absl::OkStatus ();
10051032}
10061033
@@ -1035,7 +1062,7 @@ absl::Status ModernValue(google::protobuf::Arena* arena,
10351062 return absl::OkStatus ();
10361063 case CelValue::Type::kMessage : {
10371064 auto message_wrapper = legacy_value.MessageWrapperOrDie ();
1038- result = common_internal::LegacyStructValue (
1065+ result = common_internal::MakeLegacyStructValue (
10391066 google::protobuf::DownCastMessage<google::protobuf::Message>(
10401067 message_wrapper.message_ptr ()),
10411068 message_wrapper.legacy_type_info ());
@@ -1153,7 +1180,7 @@ absl::StatusOr<Value> FromLegacyValue(google::protobuf::Arena* arena,
11531180 legacy_value.BytesOrDie ().value ());
11541181 case CelValue::Type::kMessage : {
11551182 auto message_wrapper = legacy_value.MessageWrapperOrDie ();
1156- return common_internal::LegacyStructValue (
1183+ return common_internal::MakeLegacyStructValue (
11571184 google::protobuf::DownCastMessage<google::protobuf::Message>(
11581185 message_wrapper.message_ptr ()),
11591186 message_wrapper.legacy_type_info ());
@@ -1262,6 +1289,33 @@ google::api::expr::runtime::CelValue ModernValueToLegacyValueOrDie(
12621289 return std::move (*status_or_value);
12631290}
12641291
1292+ void WrapLegacyFieldAccessResult (google::protobuf::Arena* absl_nonnull arena,
1293+ Value* absl_nonnull result) {
1294+ if (result->IsParsedMessage ()) {
1295+ *result = common_internal::ParsedMessageToLegacyStructValue (
1296+ result->GetParsedMessage ());
1297+ } else if (result->IsParsedRepeatedField ()) {
1298+ *result =
1299+ WrapLegacyParsedRepeatedField (result->GetParsedRepeatedField (), arena);
1300+ } else if (result->IsParsedJsonList ()) {
1301+ *result = WrapLegacyParsedJsonList (result->GetParsedJsonList (), arena);
1302+ } else if (result->IsParsedMapField ()) {
1303+ *result = WrapLegacyParsedMapField (result->GetParsedMapField (), arena);
1304+ } else if (result->IsParsedJsonMap ()) {
1305+ *result = WrapLegacyParsedJsonMap (result->GetParsedJsonMap (), arena);
1306+ } else if (result->IsList ()) {
1307+ auto is_empty = result->GetList ().IsEmpty ();
1308+ if (is_empty.ok () && *is_empty) {
1309+ *result = CustomListValue (common_internal::EmptyCompatListValue (), arena);
1310+ }
1311+ } else if (result->IsMap ()) {
1312+ auto is_empty = result->GetMap ().IsEmpty ();
1313+ if (is_empty.ok () && *is_empty) {
1314+ *result = CustomMapValue (common_internal::EmptyCompatMapValue (), arena);
1315+ }
1316+ }
1317+ }
1318+
12651319TypeValue CreateTypeValueFromView (google::protobuf::Arena* arena,
12661320 absl::string_view input) {
12671321 return TypeValue (common_internal::LegacyRuntimeType (input));
0 commit comments