1717#include < cstddef>
1818#include < cstdint>
1919#include < limits>
20+ #include < optional>
2021#include < string>
2122#include < type_traits>
2223#include < utility>
3132#include " absl/base/optimization.h"
3233#include " absl/functional/overload.h"
3334#include " absl/log/absl_check.h"
35+ #include " absl/log/absl_log.h"
3436#include " absl/status/status.h"
3537#include " absl/status/statusor.h"
3638#include " absl/strings/cord.h"
5052#include " internal/well_known_types.h"
5153#include " google/protobuf/arena.h"
5254#include " google/protobuf/descriptor.h"
55+ #include " google/protobuf/json/json.h"
5356#include " google/protobuf/message.h"
5457#include " google/protobuf/message_lite.h"
5558
@@ -79,6 +82,8 @@ using google::protobuf::Descriptor;
7982using google::protobuf::DescriptorPool;
8083using google::protobuf::Message;
8184using google::protobuf::MessageFactory;
85+ using google::protobuf::json::MessageToJsonString;
86+ using google::protobuf::json::PrintOptions;
8287
8388// kMaxIntJSON is defined as the Number.MAX_SAFE_INTEGER value per EcmaScript 6.
8489constexpr int64_t kMaxIntJSON = (1ll << 53 ) - 1 ;
@@ -98,6 +103,27 @@ static bool IsJSONSafe(uint64_t i) {
98103 return i <= static_cast <uint64_t >(kMaxIntJSON );
99104}
100105
106+ static std::optional<std::string> GetFieldMaskJsonString (
107+ const google::protobuf::Message& message) {
108+ // TODO(b/540507668): Refactor to pipe descriptor_pool through
109+ // ValueFromValue to use internal::MessageToJson.
110+ PrintOptions json_options;
111+ std::string json_str;
112+ auto status = MessageToJsonString (message, &json_str, json_options);
113+ if (!status.ok ()) {
114+ ABSL_LOG (ERROR ) << " Failed to convert FieldMask to JSON: " << status;
115+ return std::nullopt ;
116+ }
117+ // If JSON marshalling is correct, we know we'll always get a plain
118+ // JSON string value and it shouldn't contain any escapes that we need
119+ // to interpret.
120+ if (json_str.size () >= 2 && json_str.front () == ' "' &&
121+ json_str.back () == ' "' ) {
122+ return json_str.substr (1 , json_str.size () - 2 );
123+ }
124+ return json_str;
125+ }
126+
101127// Map implementation wrapping google.protobuf.ListValue
102128class DynamicList : public CelList {
103129 public:
@@ -1079,6 +1105,25 @@ google::protobuf::Message* ValueFromValue(google::protobuf::Message* message, co
10791105 return message;
10801106 }
10811107 } break ;
1108+ case CelValue::Type::kMessage : {
1109+ const google::protobuf::Message* message_ptr = value.MessageOrDie ();
1110+ if (message_ptr->GetDescriptor ()->full_name () ==
1111+ " google.protobuf.Empty" ) {
1112+ reflection.MutableStructValue (message);
1113+ return message;
1114+ }
1115+ if (message_ptr->GetDescriptor ()->full_name () ==
1116+ " google.protobuf.FieldMask" ) {
1117+ std::optional<std::string> fm_str =
1118+ GetFieldMaskJsonString (*message_ptr);
1119+ if (fm_str.has_value ()) {
1120+ reflection.SetStringValue (message, *fm_str);
1121+ return message;
1122+ }
1123+ return nullptr ;
1124+ }
1125+ return nullptr ;
1126+ } break ;
10821127 case CelValue::Type::kNullType :
10831128 reflection.SetNullValue (message);
10841129 return message;
@@ -1229,6 +1274,25 @@ bool ValueFromValue(Value* json, const CelValue& value, google::protobuf::Arena*
12291274 return ListFromValue (json->mutable_list_value (), value, arena);
12301275 case CelValue::Type::kMap :
12311276 return StructFromValue (json->mutable_struct_value (), value, arena);
1277+ case CelValue::Type::kMessage : {
1278+ const google::protobuf::Message* message_ptr = value.MessageOrDie ();
1279+ if (message_ptr->GetDescriptor ()->full_name () ==
1280+ " google.protobuf.Empty" ) {
1281+ json->mutable_struct_value ();
1282+ return true ;
1283+ }
1284+ if (message_ptr->GetDescriptor ()->full_name () ==
1285+ " google.protobuf.FieldMask" ) {
1286+ std::optional<std::string> fm_str =
1287+ GetFieldMaskJsonString (*message_ptr);
1288+ if (fm_str.has_value ()) {
1289+ json->set_string_value (*fm_str);
1290+ return true ;
1291+ }
1292+ return false ;
1293+ }
1294+ return false ;
1295+ }
12321296 case CelValue::Type::kNullType :
12331297 json->set_null_value (protobuf::NULL_VALUE );
12341298 return true ;
@@ -1254,7 +1318,7 @@ google::protobuf::Message* AnyFromValue(const google::protobuf::Message* prototy
12541318 case CelValue::Type::kBytes : {
12551319 BytesValue v;
12561320 type_name = v.GetTypeName ();
1257- v.set_value (std::string ( value.BytesOrDie ().value () ));
1321+ v.set_value (value.BytesOrDie ().value ());
12581322 payload = v.SerializeAsCord ();
12591323 } break ;
12601324 case CelValue::Type::kDouble : {
0 commit comments