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;
7674using ::google::api::expr::runtime::CelList;
7775using ::google::api::expr::runtime::CelMap;
7876using ::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;
8277using ::google::api::expr::runtime::GetGenericProtoTypeInfoInstance;
8378using ::google::api::expr::runtime::LegacyTypeInfoApis;
8479using ::google::api::expr::runtime::MessageWrapper;
85- using ::google::api::expr::runtime::internal::GetGenericProtoAccessApisInstance;
8680using ::google::api::expr::runtime::internal::MaybeWrapValueToMessage;
8781
8882absl::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
357366google::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-
401406std::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
934946absl::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+
12651294TypeValue 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
12891318absl::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
0 commit comments