33#include < type_traits>
44
55#include " google/protobuf/any.pb.h"
6+ #include " google/protobuf/struct.pb.h"
7+ #include " google/protobuf/wrappers.pb.h"
8+ #include " google/protobuf/arena.h"
69#include " google/protobuf/map_field.h"
710#include " absl/status/status.h"
811#include " absl/strings/str_cat.h"
12+ #include " absl/strings/string_view.h"
913#include " absl/strings/substitute.h"
1014#include " eval/public/structs/cel_proto_wrapper.h"
11- #include " internal/proto_util.h"
1215
1316namespace google {
1417namespace api {
@@ -24,11 +27,8 @@ using ::google::protobuf::Message;
2427using ::google::protobuf::Reflection;
2528
2629// Well-known type protobuf type names which require special get / set behavior.
27- constexpr const char kProtobufDuration [] = " google.protobuf.Duration" ;
28- constexpr const char kProtobufTimestamp [] = " google.protobuf.Timestamp" ;
29- constexpr const char kProtobufAny [] = " google.protobuf.Any" ;
30-
31- const char kTypeGoogleApisComPrefix [] = " type.googleapis.com/" ;
30+ constexpr absl::string_view kProtobufAny = " google.protobuf.Any" ;
31+ constexpr absl::string_view kTypeGoogleApisComPrefix = " type.googleapis.com/" ;
3232
3333// Singular message fields and repeated message fields have similar access model
3434// To provide common approach, we implement accessor classes, based on CRTP.
@@ -197,6 +197,8 @@ class ScalarFieldAccessor : public FieldAccessor<ScalarFieldAccessor> {
197197 }
198198
199199 const Message* GetMessage () const {
200+ // TODO(issues/109): When the field descriptor is a wrapper type, check if
201+ // the field is set. If set, return the unwrapped value, else return 'null'.
200202 return &GetReflection ()->GetMessage (*msg_, field_desc_);
201203 }
202204
@@ -456,44 +458,13 @@ class FieldSetter {
456458 MessageRetrieverOp ());
457459
458460 if (!value.has_value ()) {
459- GOOGLE_LOG (ERROR ) << " Has No Value" ;
460461 return false ;
461462 }
462463
463464 static_cast <const Derived*>(this )->SetMessage (value.value ());
464465 return true ;
465466 }
466467
467- bool AssignDuration (const CelValue& cel_value) const {
468- absl::Duration d;
469- if (!cel_value.GetValue (&d)) {
470- GOOGLE_LOG (ERROR ) << " Unable to retrieve duration" ;
471- return false ;
472- }
473- google::protobuf::Duration duration;
474- auto status = google::api::expr::internal::EncodeDuration (d, &duration);
475- if (!status.ok ()) {
476- return false ;
477- }
478- static_cast <const Derived*>(this )->SetMessage (&duration);
479- return true ;
480- }
481-
482- bool AssignTimestamp (const CelValue& cel_value) const {
483- absl::Time t;
484- if (!cel_value.GetValue (&t)) {
485- GOOGLE_LOG (ERROR ) << " Unable to retrieve timestamp" ;
486- return false ;
487- }
488- google::protobuf::Timestamp timestamp;
489- auto status = google::api::expr::internal::EncodeTime (t, ×tamp);
490- if (!status.ok ()) {
491- return false ;
492- }
493- static_cast <const Derived*>(this )->SetMessage (×tamp);
494- return true ;
495- }
496-
497468 // This method provides message field content, wrapped in CelValue.
498469 // If value provided successfully, returns Ok.
499470 // arena Arena to use for allocations if needed.
@@ -534,16 +505,14 @@ class FieldSetter {
534505 break ;
535506 }
536507 case FieldDescriptor::CPPTYPE_MESSAGE : {
537- const std::string& type_name = field_desc_->message_type ()->full_name ();
508+ const absl::string_view type_name =
509+ field_desc_->message_type ()->full_name ();
538510 // When the field is a message, it might be a well-known type with a
539511 // non-proto representation that requires special handling before it
540512 // can be set on the field.
541- if (type_name == kProtobufTimestamp ) {
542- return AssignTimestamp (value);
543- } else if (type_name == kProtobufDuration ) {
544- return AssignDuration (value);
545- }
546- return AssignMessage (value);
513+ auto wrapped_value =
514+ CelProtoWrapper::MaybeWrapValue (type_name, value, arena_);
515+ return AssignMessage (wrapped_value.value_or (value));
547516 }
548517 case FieldDescriptor::CPPTYPE_ENUM : {
549518 return AssignEnum (value);
@@ -556,18 +525,20 @@ class FieldSetter {
556525 }
557526
558527 protected:
559- FieldSetter (Message* msg, const FieldDescriptor* field_desc)
560- : msg_(msg), field_desc_(field_desc) {}
528+ FieldSetter (Message* msg, const FieldDescriptor* field_desc, Arena* arena )
529+ : msg_(msg), field_desc_(field_desc), arena_(arena) {}
561530
562531 Message* msg_;
563532 const FieldDescriptor* field_desc_;
533+ Arena* arena_;
564534};
565535
566536// Accessor class, to work with singular fields
567537class ScalarFieldSetter : public FieldSetter <ScalarFieldSetter> {
568538 public:
569- ScalarFieldSetter (Message* msg, const FieldDescriptor* field_desc)
570- : FieldSetter(msg, field_desc) {}
539+ ScalarFieldSetter (Message* msg, const FieldDescriptor* field_desc,
540+ Arena* arena)
541+ : FieldSetter(msg, field_desc, arena) {}
571542
572543 bool SetBool (bool value) const {
573544 GetReflection ()->SetBool (msg_, field_desc_, value);
@@ -651,8 +622,9 @@ class ScalarFieldSetter : public FieldSetter<ScalarFieldSetter> {
651622// Appender class, to work with repeated fields
652623class RepeatedFieldSetter : public FieldSetter <RepeatedFieldSetter> {
653624 public:
654- RepeatedFieldSetter (Message* msg, const FieldDescriptor* field_desc)
655- : FieldSetter(msg, field_desc) {}
625+ RepeatedFieldSetter (Message* msg, const FieldDescriptor* field_desc,
626+ Arena* arena)
627+ : FieldSetter(msg, field_desc, arena) {}
656628
657629 bool SetBool (bool value) const {
658630 GetReflection ()->AddBool (msg_, field_desc_, value);
@@ -724,8 +696,9 @@ class RepeatedFieldSetter : public FieldSetter<RepeatedFieldSetter> {
724696// arena Arena to use for allocations if needed.
725697// result pointer to object to store value in.
726698absl::Status SetValueToSingleField (const CelValue& value,
727- const FieldDescriptor* desc, Message* msg) {
728- ScalarFieldSetter setter (msg, desc);
699+ const FieldDescriptor* desc, Message* msg,
700+ Arena* arena) {
701+ ScalarFieldSetter setter (msg, desc, arena);
729702 return (setter.SetFieldFromCelValue (value))
730703 ? absl::OkStatus ()
731704 : absl::InvalidArgumentError (absl::Substitute (
@@ -736,9 +709,9 @@ absl::Status SetValueToSingleField(const CelValue& value,
736709}
737710
738711absl::Status AddValueToRepeatedField (const CelValue& value,
739- const FieldDescriptor* desc,
740- Message* msg ) {
741- RepeatedFieldSetter setter (msg, desc);
712+ const FieldDescriptor* desc, Message* msg,
713+ Arena* arena ) {
714+ RepeatedFieldSetter setter (msg, desc, arena );
742715 return (setter.SetFieldFromCelValue (value))
743716 ? absl::OkStatus ()
744717 : absl::InvalidArgumentError (absl::Substitute (
@@ -748,32 +721,6 @@ absl::Status AddValueToRepeatedField(const CelValue& value,
748721 value.DebugString ()));
749722}
750723
751- absl::Status AddValueToMapField (const CelValue& key, const CelValue& value,
752- const FieldDescriptor* desc, Message* msg) {
753- auto entry_msg = msg->GetReflection ()->AddMessage (msg, desc);
754- auto key_field_desc = entry_msg->GetDescriptor ()->FindFieldByNumber (1 );
755- auto value_field_desc = entry_msg->GetDescriptor ()->FindFieldByNumber (2 );
756-
757- ScalarFieldSetter key_setter (entry_msg, key_field_desc);
758- ScalarFieldSetter value_setter (entry_msg, value_field_desc);
759-
760- if (!key_setter.SetFieldFromCelValue (key)) {
761- return absl::InvalidArgumentError (absl::Substitute (
762- " Could not assign supplied argument \" $2\" to message "
763- " \" $0\" field \" $1\" map key." ,
764- msg->GetDescriptor ()->name (), desc->name (), key.DebugString ()));
765- }
766-
767- if (!value_setter.SetFieldFromCelValue (value)) {
768- return absl::InvalidArgumentError (absl::Substitute (
769- " Could not assign supplied argument \" $2\" to message \" $0\" "
770- " field \" $1\" map value." ,
771- msg->GetDescriptor ()->name (), desc->name (), value.DebugString ()));
772- }
773-
774- return absl::OkStatus ();
775- }
776-
777724} // namespace runtime
778725} // namespace expr
779726} // namespace api
0 commit comments