/proc/self/cwd/internal/json.cc
Line | Count | Source |
1 | | // Copyright 2024 Google LLC |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include "internal/json.h" |
16 | | |
17 | | #include <cmath> |
18 | | #include <cstdint> |
19 | | #include <memory> |
20 | | #include <string> |
21 | | #include <tuple> |
22 | | #include <utility> |
23 | | #include <vector> |
24 | | |
25 | | #include "google/protobuf/duration.pb.h" |
26 | | #include "google/protobuf/struct.pb.h" |
27 | | #include "google/protobuf/timestamp.pb.h" |
28 | | #include "absl/base/attributes.h" |
29 | | #include "absl/base/no_destructor.h" |
30 | | #include "absl/base/nullability.h" |
31 | | #include "absl/base/optimization.h" |
32 | | #include "absl/functional/overload.h" |
33 | | #include "absl/log/absl_check.h" |
34 | | #include "absl/status/status.h" |
35 | | #include "absl/status/statusor.h" |
36 | | #include "absl/strings/ascii.h" |
37 | | #include "absl/strings/cord.h" |
38 | | #include "absl/strings/escaping.h" |
39 | | #include "absl/strings/match.h" |
40 | | #include "absl/strings/str_cat.h" |
41 | | #include "absl/strings/str_join.h" |
42 | | #include "absl/strings/string_view.h" |
43 | | #include "absl/types/variant.h" |
44 | | #include "extensions/protobuf/internal/map_reflection.h" |
45 | | #include "internal/status_macros.h" |
46 | | #include "internal/strings.h" |
47 | | #include "internal/well_known_types.h" |
48 | | #include "google/protobuf/descriptor.h" |
49 | | #include "google/protobuf/map_field.h" |
50 | | #include "google/protobuf/message.h" |
51 | | #include "google/protobuf/message_lite.h" |
52 | | #include "google/protobuf/util/time_util.h" |
53 | | |
54 | | #undef GetMessage |
55 | | |
56 | | namespace cel::internal { |
57 | | |
58 | | namespace { |
59 | | |
60 | | using ::cel::well_known_types::AsVariant; |
61 | | using ::cel::well_known_types::GetListValueReflection; |
62 | | using ::cel::well_known_types::GetRepeatedBytesField; |
63 | | using ::cel::well_known_types::GetRepeatedStringField; |
64 | | using ::cel::well_known_types::GetStructReflection; |
65 | | using ::cel::well_known_types::GetValueReflection; |
66 | | using ::cel::well_known_types::JsonReflection; |
67 | | using ::cel::well_known_types::ListValueReflection; |
68 | | using ::cel::well_known_types::Reflection; |
69 | | using ::cel::well_known_types::StructReflection; |
70 | | using ::cel::well_known_types::ValueReflection; |
71 | | using ::google::protobuf::Descriptor; |
72 | | using ::google::protobuf::FieldDescriptor; |
73 | | using ::google::protobuf::util::TimeUtil; |
74 | | |
75 | | // Yanked from the implementation `google::protobuf::util::TimeUtil`. |
76 | | template <typename Chars> |
77 | | absl::Status SnakeCaseToCamelCaseImpl(Chars input, |
78 | 0 | std::string* absl_nonnull output) { |
79 | 0 | output->clear(); |
80 | 0 | bool after_underscore = false; |
81 | 0 | for (char input_char : input) { |
82 | 0 | if (absl::ascii_isupper(input_char)) { |
83 | | // The field name must not contain uppercase letters. |
84 | 0 | return absl::InvalidArgumentError( |
85 | 0 | "field mask path name contains uppercase letters"); |
86 | 0 | } |
87 | 0 | if (after_underscore) { |
88 | 0 | if (absl::ascii_islower(input_char)) { |
89 | 0 | output->push_back(absl::ascii_toupper(input_char)); |
90 | 0 | after_underscore = false; |
91 | 0 | } else { |
92 | | // The character after a "_" must be a lowercase letter. |
93 | 0 | return absl::InvalidArgumentError( |
94 | 0 | "field mask path contains '_' not followed by a lowercase letter"); |
95 | 0 | } |
96 | 0 | } else if (input_char == '_') { |
97 | 0 | after_underscore = true; |
98 | 0 | } else { |
99 | 0 | output->push_back(input_char); |
100 | 0 | } |
101 | 0 | } |
102 | 0 | if (after_underscore) { |
103 | | // Trailing "_". |
104 | 0 | return absl::InvalidArgumentError("field mask path contains trailing '_'"); |
105 | 0 | } |
106 | 0 | return absl::OkStatus(); |
107 | 0 | } Unexecuted instantiation: json.cc:absl::lts_20260107::Status cel::internal::(anonymous namespace)::SnakeCaseToCamelCaseImpl<std::__1::basic_string_view<char, std::__1::char_traits<char> > >(std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) Unexecuted instantiation: json.cc:absl::lts_20260107::Status cel::internal::(anonymous namespace)::SnakeCaseToCamelCaseImpl<absl::lts_20260107::Cord::CharRange>(absl::lts_20260107::Cord::CharRange, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) |
108 | | |
109 | | absl::Status SnakeCaseToCamelCase(const well_known_types::StringValue& input, |
110 | 0 | std::string* absl_nonnull output) { |
111 | 0 | return absl::visit(absl::Overload( |
112 | 0 | [&](absl::string_view string) -> absl::Status { |
113 | 0 | return SnakeCaseToCamelCaseImpl(string, output); |
114 | 0 | }, |
115 | 0 | [&](const absl::Cord& cord) -> absl::Status { |
116 | 0 | return SnakeCaseToCamelCaseImpl(cord.Chars(), |
117 | 0 | output); |
118 | 0 | }), |
119 | 0 | AsVariant(input)); |
120 | 0 | } |
121 | | |
122 | | class MessageToJsonState; |
123 | | |
124 | | using MapFieldKeyToString = std::string (*)(const google::protobuf::MapKey&); |
125 | | |
126 | 0 | std::string BoolMapFieldKeyToString(const google::protobuf::MapKey& key) { |
127 | 0 | return key.GetBoolValue() ? "true" : "false"; |
128 | 0 | } |
129 | | |
130 | 0 | std::string Int32MapFieldKeyToString(const google::protobuf::MapKey& key) { |
131 | 0 | return absl::StrCat(key.GetInt32Value()); |
132 | 0 | } |
133 | | |
134 | 0 | std::string Int64MapFieldKeyToString(const google::protobuf::MapKey& key) { |
135 | 0 | return absl::StrCat(key.GetInt64Value()); |
136 | 0 | } |
137 | | |
138 | 0 | std::string UInt32MapFieldKeyToString(const google::protobuf::MapKey& key) { |
139 | 0 | return absl::StrCat(key.GetUInt32Value()); |
140 | 0 | } |
141 | | |
142 | 0 | std::string UInt64MapFieldKeyToString(const google::protobuf::MapKey& key) { |
143 | 0 | return absl::StrCat(key.GetUInt64Value()); |
144 | 0 | } |
145 | | |
146 | 0 | std::string StringMapFieldKeyToString(const google::protobuf::MapKey& key) { |
147 | 0 | return std::string(key.GetStringValue()); |
148 | 0 | } |
149 | | |
150 | | MapFieldKeyToString GetMapFieldKeyToString( |
151 | 0 | const google::protobuf::FieldDescriptor* absl_nonnull field) { |
152 | 0 | switch (field->cpp_type()) { |
153 | 0 | case FieldDescriptor::CPPTYPE_BOOL: |
154 | 0 | return &BoolMapFieldKeyToString; |
155 | 0 | case FieldDescriptor::CPPTYPE_INT32: |
156 | 0 | return &Int32MapFieldKeyToString; |
157 | 0 | case FieldDescriptor::CPPTYPE_INT64: |
158 | 0 | return &Int64MapFieldKeyToString; |
159 | 0 | case FieldDescriptor::CPPTYPE_UINT32: |
160 | 0 | return &UInt32MapFieldKeyToString; |
161 | 0 | case FieldDescriptor::CPPTYPE_UINT64: |
162 | 0 | return &UInt64MapFieldKeyToString; |
163 | 0 | case FieldDescriptor::CPPTYPE_STRING: |
164 | 0 | return &StringMapFieldKeyToString; |
165 | 0 | default: |
166 | 0 | ABSL_UNREACHABLE(); |
167 | 0 | } |
168 | 0 | } |
169 | | |
170 | | using MapFieldValueToValue = absl::Status (MessageToJsonState::*)( |
171 | | const google::protobuf::MapValueConstRef& value, |
172 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
173 | | google::protobuf::MessageLite* absl_nonnull result); |
174 | | |
175 | | using RepeatedFieldToValue = absl::Status (MessageToJsonState::*)( |
176 | | const google::protobuf::Reflection* absl_nonnull reflection, |
177 | | const google::protobuf::Message& message, |
178 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
179 | | google::protobuf::MessageLite* absl_nonnull result); |
180 | | |
181 | | class MessageToJsonState { |
182 | | public: |
183 | | MessageToJsonState(const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
184 | | google::protobuf::MessageFactory* absl_nonnull message_factory) |
185 | 0 | : descriptor_pool_(descriptor_pool), message_factory_(message_factory) {} |
186 | | |
187 | 0 | virtual ~MessageToJsonState() = default; |
188 | | |
189 | | absl::Status ToJson(const google::protobuf::Message& message, |
190 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
191 | 0 | const auto* descriptor = message.GetDescriptor(); |
192 | 0 | switch (descriptor->well_known_type()) { |
193 | 0 | case Descriptor::WELLKNOWNTYPE_DOUBLEVALUE: { |
194 | 0 | CEL_RETURN_IF_ERROR(reflection_.DoubleValue().Initialize(descriptor)); |
195 | 0 | SetNumberValue(result, reflection_.DoubleValue().GetValue(message)); |
196 | 0 | } break; |
197 | 0 | case Descriptor::WELLKNOWNTYPE_FLOATVALUE: { |
198 | 0 | CEL_RETURN_IF_ERROR(reflection_.FloatValue().Initialize(descriptor)); |
199 | 0 | SetNumberValue(result, reflection_.FloatValue().GetValue(message)); |
200 | 0 | } break; |
201 | 0 | case Descriptor::WELLKNOWNTYPE_INT64VALUE: { |
202 | 0 | CEL_RETURN_IF_ERROR(reflection_.Int64Value().Initialize(descriptor)); |
203 | 0 | SetNumberValue(result, reflection_.Int64Value().GetValue(message)); |
204 | 0 | } break; |
205 | 0 | case Descriptor::WELLKNOWNTYPE_UINT64VALUE: { |
206 | 0 | CEL_RETURN_IF_ERROR(reflection_.UInt64Value().Initialize(descriptor)); |
207 | 0 | SetNumberValue(result, reflection_.UInt64Value().GetValue(message)); |
208 | 0 | } break; |
209 | 0 | case Descriptor::WELLKNOWNTYPE_INT32VALUE: { |
210 | 0 | CEL_RETURN_IF_ERROR(reflection_.Int32Value().Initialize(descriptor)); |
211 | 0 | SetNumberValue(result, reflection_.Int32Value().GetValue(message)); |
212 | 0 | } break; |
213 | 0 | case Descriptor::WELLKNOWNTYPE_UINT32VALUE: { |
214 | 0 | CEL_RETURN_IF_ERROR(reflection_.UInt32Value().Initialize(descriptor)); |
215 | 0 | SetNumberValue(result, reflection_.UInt32Value().GetValue(message)); |
216 | 0 | } break; |
217 | 0 | case Descriptor::WELLKNOWNTYPE_STRINGVALUE: { |
218 | 0 | CEL_RETURN_IF_ERROR(reflection_.StringValue().Initialize(descriptor)); |
219 | 0 | StringValueToJson(reflection_.StringValue().GetValue(message, scratch_), |
220 | 0 | result); |
221 | 0 | } break; |
222 | 0 | case Descriptor::WELLKNOWNTYPE_BYTESVALUE: { |
223 | 0 | CEL_RETURN_IF_ERROR(reflection_.BytesValue().Initialize(descriptor)); |
224 | 0 | BytesValueToJson(reflection_.BytesValue().GetValue(message, scratch_), |
225 | 0 | result); |
226 | 0 | } break; |
227 | 0 | case Descriptor::WELLKNOWNTYPE_BOOLVALUE: { |
228 | 0 | CEL_RETURN_IF_ERROR(reflection_.BoolValue().Initialize(descriptor)); |
229 | 0 | SetBoolValue(result, reflection_.BoolValue().GetValue(message)); |
230 | 0 | } break; |
231 | 0 | case Descriptor::WELLKNOWNTYPE_ANY: { |
232 | 0 | CEL_ASSIGN_OR_RETURN(auto unpacked, |
233 | 0 | well_known_types::UnpackAnyFrom( |
234 | 0 | result->GetArena(), reflection_.Any(), message, |
235 | 0 | descriptor_pool_, message_factory_)); |
236 | 0 | auto* struct_result = MutableStructValue(result); |
237 | 0 | const auto* unpacked_descriptor = unpacked->GetDescriptor(); |
238 | 0 | SetStringValue(InsertField(struct_result, "@type"), |
239 | 0 | absl::StrCat("type.googleapis.com/", |
240 | 0 | unpacked_descriptor->full_name())); |
241 | 0 | switch (unpacked_descriptor->well_known_type()) { |
242 | 0 | case Descriptor::WELLKNOWNTYPE_DOUBLEVALUE: |
243 | 0 | ABSL_FALLTHROUGH_INTENDED; |
244 | 0 | case Descriptor::WELLKNOWNTYPE_FLOATVALUE: |
245 | 0 | ABSL_FALLTHROUGH_INTENDED; |
246 | 0 | case Descriptor::WELLKNOWNTYPE_INT64VALUE: |
247 | 0 | ABSL_FALLTHROUGH_INTENDED; |
248 | 0 | case Descriptor::WELLKNOWNTYPE_UINT64VALUE: |
249 | 0 | ABSL_FALLTHROUGH_INTENDED; |
250 | 0 | case Descriptor::WELLKNOWNTYPE_INT32VALUE: |
251 | 0 | ABSL_FALLTHROUGH_INTENDED; |
252 | 0 | case Descriptor::WELLKNOWNTYPE_UINT32VALUE: |
253 | 0 | ABSL_FALLTHROUGH_INTENDED; |
254 | 0 | case Descriptor::WELLKNOWNTYPE_STRINGVALUE: |
255 | 0 | ABSL_FALLTHROUGH_INTENDED; |
256 | 0 | case Descriptor::WELLKNOWNTYPE_BYTESVALUE: |
257 | 0 | ABSL_FALLTHROUGH_INTENDED; |
258 | 0 | case Descriptor::WELLKNOWNTYPE_BOOLVALUE: |
259 | 0 | ABSL_FALLTHROUGH_INTENDED; |
260 | 0 | case Descriptor::WELLKNOWNTYPE_FIELDMASK: |
261 | 0 | ABSL_FALLTHROUGH_INTENDED; |
262 | 0 | case Descriptor::WELLKNOWNTYPE_DURATION: |
263 | 0 | ABSL_FALLTHROUGH_INTENDED; |
264 | 0 | case Descriptor::WELLKNOWNTYPE_TIMESTAMP: |
265 | 0 | ABSL_FALLTHROUGH_INTENDED; |
266 | 0 | case Descriptor::WELLKNOWNTYPE_VALUE: |
267 | 0 | ABSL_FALLTHROUGH_INTENDED; |
268 | 0 | case Descriptor::WELLKNOWNTYPE_LISTVALUE: |
269 | 0 | ABSL_FALLTHROUGH_INTENDED; |
270 | 0 | case Descriptor::WELLKNOWNTYPE_STRUCT: |
271 | 0 | return ToJson(*unpacked, InsertField(struct_result, "value")); |
272 | 0 | default: |
273 | 0 | if (unpacked_descriptor->full_name() == "google.protobuf.Empty") { |
274 | 0 | MutableStructValue(InsertField(struct_result, "value")); |
275 | 0 | return absl::OkStatus(); |
276 | 0 | } else { |
277 | 0 | return MessageToJson(*unpacked, struct_result); |
278 | 0 | } |
279 | 0 | } |
280 | 0 | } |
281 | 0 | case Descriptor::WELLKNOWNTYPE_FIELDMASK: { |
282 | 0 | CEL_RETURN_IF_ERROR(reflection_.FieldMask().Initialize(descriptor)); |
283 | 0 | std::vector<std::string> paths; |
284 | 0 | const int paths_size = reflection_.FieldMask().PathsSize(message); |
285 | 0 | for (int i = 0; i < paths_size; ++i) { |
286 | 0 | CEL_RETURN_IF_ERROR(SnakeCaseToCamelCase( |
287 | 0 | reflection_.FieldMask().Paths(message, i, scratch_), |
288 | 0 | &paths.emplace_back())); |
289 | 0 | } |
290 | 0 | SetStringValue(result, absl::StrJoin(paths, ",")); |
291 | 0 | } break; |
292 | 0 | case Descriptor::WELLKNOWNTYPE_DURATION: { |
293 | 0 | CEL_RETURN_IF_ERROR(reflection_.Duration().Initialize(descriptor)); |
294 | 0 | google::protobuf::Duration duration; |
295 | 0 | duration.set_seconds(reflection_.Duration().GetSeconds(message)); |
296 | 0 | duration.set_nanos(reflection_.Duration().GetNanos(message)); |
297 | 0 | SetStringValue(result, TimeUtil::ToString(duration)); |
298 | 0 | } break; |
299 | 0 | case Descriptor::WELLKNOWNTYPE_TIMESTAMP: { |
300 | 0 | CEL_RETURN_IF_ERROR(reflection_.Timestamp().Initialize(descriptor)); |
301 | 0 | google::protobuf::Timestamp timestamp; |
302 | 0 | timestamp.set_seconds(reflection_.Timestamp().GetSeconds(message)); |
303 | 0 | timestamp.set_nanos(reflection_.Timestamp().GetNanos(message)); |
304 | 0 | SetStringValue(result, TimeUtil::ToString(timestamp)); |
305 | 0 | } break; |
306 | 0 | case Descriptor::WELLKNOWNTYPE_VALUE: { |
307 | 0 | absl::Cord serialized; |
308 | 0 | if (!message.SerializePartialToString(&serialized)) { |
309 | 0 | return absl::UnknownError( |
310 | 0 | "failed to serialize message google.protobuf.Value"); |
311 | 0 | } |
312 | 0 | if (!result->ParsePartialFromString(serialized)) { |
313 | 0 | return absl::UnknownError( |
314 | 0 | "failed to parsed message: google.protobuf.Value"); |
315 | 0 | } |
316 | 0 | } break; |
317 | 0 | case Descriptor::WELLKNOWNTYPE_LISTVALUE: { |
318 | 0 | absl::Cord serialized; |
319 | 0 | if (!message.SerializePartialToString(&serialized)) { |
320 | 0 | return absl::UnknownError( |
321 | 0 | "failed to serialize message google.protobuf.ListValue"); |
322 | 0 | } |
323 | 0 | if (!MutableListValue(result)->ParsePartialFromString(serialized)) { |
324 | 0 | return absl::UnknownError( |
325 | 0 | "failed to parsed message: google.protobuf.ListValue"); |
326 | 0 | } |
327 | 0 | } break; |
328 | 0 | case Descriptor::WELLKNOWNTYPE_STRUCT: { |
329 | 0 | absl::Cord serialized; |
330 | 0 | if (!message.SerializePartialToString(&serialized)) { |
331 | 0 | return absl::UnknownError( |
332 | 0 | "failed to serialize message google.protobuf.Struct"); |
333 | 0 | } |
334 | 0 | if (!MutableStructValue(result)->ParsePartialFromString(serialized)) { |
335 | 0 | return absl::UnknownError( |
336 | 0 | "failed to parsed message: google.protobuf.Struct"); |
337 | 0 | } |
338 | 0 | } break; |
339 | 0 | default: |
340 | 0 | return MessageToJson(message, MutableStructValue(result)); |
341 | 0 | } |
342 | 0 | return absl::OkStatus(); |
343 | 0 | } |
344 | | |
345 | | absl::Status ToJsonObject(const google::protobuf::Message& message, |
346 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
347 | 0 | return MessageToJson(message, result); |
348 | 0 | } |
349 | | |
350 | | absl::Status FieldToJson(const google::protobuf::Message& message, |
351 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
352 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
353 | 0 | return MessageFieldToJson(message, field, result); |
354 | 0 | } |
355 | | |
356 | | absl::Status FieldToJsonArray( |
357 | | const google::protobuf::Message& message, |
358 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
359 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
360 | 0 | return MessageRepeatedFieldToJson(message, field, result); |
361 | 0 | } |
362 | | |
363 | | absl::Status FieldToJsonObject( |
364 | | const google::protobuf::Message& message, |
365 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
366 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
367 | 0 | return MessageMapFieldToJson(message, field, result); |
368 | 0 | } |
369 | | |
370 | | virtual absl::Status Initialize( |
371 | | google::protobuf::MessageLite* absl_nonnull message) = 0; |
372 | | |
373 | | private: |
374 | | absl::StatusOr<MapFieldValueToValue> GetMapFieldValueToValue( |
375 | 0 | const google::protobuf::FieldDescriptor* absl_nonnull field) { |
376 | 0 | switch (field->type()) { |
377 | 0 | case FieldDescriptor::TYPE_DOUBLE: |
378 | 0 | return &MessageToJsonState::MapDoubleFieldToValue; |
379 | 0 | case FieldDescriptor::TYPE_FLOAT: |
380 | 0 | return &MessageToJsonState::MapFloatFieldToValue; |
381 | 0 | case FieldDescriptor::TYPE_FIXED64: |
382 | 0 | ABSL_FALLTHROUGH_INTENDED; |
383 | 0 | case FieldDescriptor::TYPE_UINT64: |
384 | 0 | return &MessageToJsonState::MapUInt64FieldToValue; |
385 | 0 | case FieldDescriptor::TYPE_BOOL: |
386 | 0 | return &MessageToJsonState::MapBoolFieldToValue; |
387 | 0 | case FieldDescriptor::TYPE_STRING: |
388 | 0 | return &MessageToJsonState::MapStringFieldToValue; |
389 | 0 | case FieldDescriptor::TYPE_GROUP: |
390 | 0 | ABSL_FALLTHROUGH_INTENDED; |
391 | 0 | case FieldDescriptor::TYPE_MESSAGE: |
392 | 0 | return &MessageToJsonState::MapMessageFieldToValue; |
393 | 0 | case FieldDescriptor::TYPE_BYTES: |
394 | 0 | return &MessageToJsonState::MapBytesFieldToValue; |
395 | 0 | case FieldDescriptor::TYPE_FIXED32: |
396 | 0 | ABSL_FALLTHROUGH_INTENDED; |
397 | 0 | case FieldDescriptor::TYPE_UINT32: |
398 | 0 | return &MessageToJsonState::MapUInt32FieldToValue; |
399 | 0 | case FieldDescriptor::TYPE_ENUM: { |
400 | 0 | const auto* enum_descriptor = field->enum_type(); |
401 | 0 | if (enum_descriptor->full_name() == "google.protobuf.NullValue") { |
402 | 0 | return &MessageToJsonState::MapNullFieldToValue; |
403 | 0 | } else { |
404 | 0 | return &MessageToJsonState::MapEnumFieldToValue; |
405 | 0 | } |
406 | 0 | } |
407 | 0 | case FieldDescriptor::TYPE_SFIXED32: |
408 | 0 | ABSL_FALLTHROUGH_INTENDED; |
409 | 0 | case FieldDescriptor::TYPE_SINT32: |
410 | 0 | ABSL_FALLTHROUGH_INTENDED; |
411 | 0 | case FieldDescriptor::TYPE_INT32: |
412 | 0 | return &MessageToJsonState::MapInt32FieldToValue; |
413 | 0 | case FieldDescriptor::TYPE_SFIXED64: |
414 | 0 | ABSL_FALLTHROUGH_INTENDED; |
415 | 0 | case FieldDescriptor::TYPE_SINT64: |
416 | 0 | ABSL_FALLTHROUGH_INTENDED; |
417 | 0 | case FieldDescriptor::TYPE_INT64: |
418 | 0 | return &MessageToJsonState::MapInt64FieldToValue; |
419 | 0 | default: |
420 | 0 | return absl::InvalidArgumentError(absl::StrCat( |
421 | 0 | "unexpected message field type: ", field->type_name())); |
422 | 0 | } |
423 | 0 | } |
424 | | |
425 | | absl::Status MapBoolFieldToValue( |
426 | | const google::protobuf::MapValueConstRef& value, |
427 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
428 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
429 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
430 | 0 | ABSL_DCHECK(!field->is_repeated()); |
431 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_BOOL); |
432 | 0 | SetBoolValue(result, value.GetBoolValue()); |
433 | 0 | return absl::OkStatus(); |
434 | 0 | } |
435 | | |
436 | | absl::Status MapInt32FieldToValue( |
437 | | const google::protobuf::MapValueConstRef& value, |
438 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
439 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
440 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
441 | 0 | ABSL_DCHECK(!field->is_repeated()); |
442 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_INT32); |
443 | 0 | SetNumberValue(result, value.GetInt32Value()); |
444 | 0 | return absl::OkStatus(); |
445 | 0 | } |
446 | | |
447 | | absl::Status MapInt64FieldToValue( |
448 | | const google::protobuf::MapValueConstRef& value, |
449 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
450 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
451 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
452 | 0 | ABSL_DCHECK(!field->is_repeated()); |
453 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_INT64); |
454 | 0 | SetNumberValue(result, value.GetInt64Value()); |
455 | 0 | return absl::OkStatus(); |
456 | 0 | } |
457 | | |
458 | | absl::Status MapUInt32FieldToValue( |
459 | | const google::protobuf::MapValueConstRef& value, |
460 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
461 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
462 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
463 | 0 | ABSL_DCHECK(!field->is_repeated()); |
464 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_UINT32); |
465 | 0 | SetNumberValue(result, value.GetUInt32Value()); |
466 | 0 | return absl::OkStatus(); |
467 | 0 | } |
468 | | |
469 | | absl::Status MapUInt64FieldToValue( |
470 | | const google::protobuf::MapValueConstRef& value, |
471 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
472 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
473 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
474 | 0 | ABSL_DCHECK(!field->is_repeated()); |
475 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_UINT64); |
476 | 0 | SetNumberValue(result, value.GetUInt64Value()); |
477 | 0 | return absl::OkStatus(); |
478 | 0 | } |
479 | | |
480 | | absl::Status MapFloatFieldToValue( |
481 | | const google::protobuf::MapValueConstRef& value, |
482 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
483 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
484 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
485 | 0 | ABSL_DCHECK(!field->is_repeated()); |
486 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_FLOAT); |
487 | 0 | SetNumberValue(result, value.GetFloatValue()); |
488 | 0 | return absl::OkStatus(); |
489 | 0 | } |
490 | | |
491 | | absl::Status MapDoubleFieldToValue( |
492 | | const google::protobuf::MapValueConstRef& value, |
493 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
494 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
495 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
496 | 0 | ABSL_DCHECK(!field->is_repeated()); |
497 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_DOUBLE); |
498 | 0 | SetNumberValue(result, value.GetDoubleValue()); |
499 | 0 | return absl::OkStatus(); |
500 | 0 | } |
501 | | |
502 | | absl::Status MapBytesFieldToValue( |
503 | | const google::protobuf::MapValueConstRef& value, |
504 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
505 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
506 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
507 | 0 | ABSL_DCHECK(!field->is_repeated()); |
508 | 0 | ABSL_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES); |
509 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_STRING); |
510 | 0 | SetStringValueFromBytes(result, value.GetStringValue()); |
511 | 0 | return absl::OkStatus(); |
512 | 0 | } |
513 | | |
514 | | absl::Status MapStringFieldToValue( |
515 | | const google::protobuf::MapValueConstRef& value, |
516 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
517 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
518 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
519 | 0 | ABSL_DCHECK(!field->is_repeated()); |
520 | 0 | ABSL_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_STRING); |
521 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_STRING); |
522 | 0 | SetStringValue(result, value.GetStringValue()); |
523 | 0 | return absl::OkStatus(); |
524 | 0 | } |
525 | | |
526 | | absl::Status MapMessageFieldToValue( |
527 | | const google::protobuf::MapValueConstRef& value, |
528 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
529 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
530 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
531 | 0 | ABSL_DCHECK(!field->is_repeated()); |
532 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_MESSAGE); |
533 | 0 | return ToJson(value.GetMessageValue(), result); |
534 | 0 | } |
535 | | |
536 | | absl::Status MapEnumFieldToValue( |
537 | | const google::protobuf::MapValueConstRef& value, |
538 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
539 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
540 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
541 | 0 | ABSL_DCHECK(!field->is_repeated()); |
542 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_ENUM); |
543 | 0 | ABSL_DCHECK_NE(field->enum_type()->full_name(), |
544 | 0 | "google.protobuf.NullValue"); |
545 | 0 | if (const auto* value_descriptor = |
546 | 0 | field->enum_type()->FindValueByNumber(value.GetEnumValue()); |
547 | 0 | value_descriptor != nullptr) { |
548 | 0 | SetStringValue(result, value_descriptor->name()); |
549 | 0 | } else { |
550 | 0 | SetNumberValue(result, value.GetEnumValue()); |
551 | 0 | } |
552 | 0 | return absl::OkStatus(); |
553 | 0 | } |
554 | | |
555 | | absl::Status MapNullFieldToValue( |
556 | | const google::protobuf::MapValueConstRef& value, |
557 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
558 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
559 | 0 | ABSL_DCHECK_EQ(value.type(), field->cpp_type()); |
560 | 0 | ABSL_DCHECK(!field->is_repeated()); |
561 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_ENUM); |
562 | 0 | ABSL_DCHECK_EQ(field->enum_type()->full_name(), |
563 | 0 | "google.protobuf.NullValue"); |
564 | 0 | SetNullValue(result); |
565 | 0 | return absl::OkStatus(); |
566 | 0 | } |
567 | | |
568 | | absl::StatusOr<RepeatedFieldToValue> GetRepeatedFieldToValue( |
569 | 0 | const google::protobuf::FieldDescriptor* absl_nonnull field) { |
570 | 0 | switch (field->type()) { |
571 | 0 | case FieldDescriptor::TYPE_DOUBLE: |
572 | 0 | return &MessageToJsonState::RepeatedDoubleFieldToValue; |
573 | 0 | case FieldDescriptor::TYPE_FLOAT: |
574 | 0 | return &MessageToJsonState::RepeatedFloatFieldToValue; |
575 | 0 | case FieldDescriptor::TYPE_FIXED64: |
576 | 0 | ABSL_FALLTHROUGH_INTENDED; |
577 | 0 | case FieldDescriptor::TYPE_UINT64: |
578 | 0 | return &MessageToJsonState::RepeatedUInt64FieldToValue; |
579 | 0 | case FieldDescriptor::TYPE_BOOL: |
580 | 0 | return &MessageToJsonState::RepeatedBoolFieldToValue; |
581 | 0 | case FieldDescriptor::TYPE_STRING: |
582 | 0 | return &MessageToJsonState::RepeatedStringFieldToValue; |
583 | 0 | case FieldDescriptor::TYPE_GROUP: |
584 | 0 | ABSL_FALLTHROUGH_INTENDED; |
585 | 0 | case FieldDescriptor::TYPE_MESSAGE: |
586 | 0 | return &MessageToJsonState::RepeatedMessageFieldToValue; |
587 | 0 | case FieldDescriptor::TYPE_BYTES: |
588 | 0 | return &MessageToJsonState::RepeatedBytesFieldToValue; |
589 | 0 | case FieldDescriptor::TYPE_FIXED32: |
590 | 0 | ABSL_FALLTHROUGH_INTENDED; |
591 | 0 | case FieldDescriptor::TYPE_UINT32: |
592 | 0 | return &MessageToJsonState::RepeatedUInt32FieldToValue; |
593 | 0 | case FieldDescriptor::TYPE_ENUM: { |
594 | 0 | const auto* enum_descriptor = field->enum_type(); |
595 | 0 | if (enum_descriptor->full_name() == "google.protobuf.NullValue") { |
596 | 0 | return &MessageToJsonState::RepeatedNullFieldToValue; |
597 | 0 | } else { |
598 | 0 | return &MessageToJsonState::RepeatedEnumFieldToValue; |
599 | 0 | } |
600 | 0 | } |
601 | 0 | case FieldDescriptor::TYPE_SFIXED32: |
602 | 0 | ABSL_FALLTHROUGH_INTENDED; |
603 | 0 | case FieldDescriptor::TYPE_SINT32: |
604 | 0 | ABSL_FALLTHROUGH_INTENDED; |
605 | 0 | case FieldDescriptor::TYPE_INT32: |
606 | 0 | return &MessageToJsonState::RepeatedInt32FieldToValue; |
607 | 0 | case FieldDescriptor::TYPE_SFIXED64: |
608 | 0 | ABSL_FALLTHROUGH_INTENDED; |
609 | 0 | case FieldDescriptor::TYPE_SINT64: |
610 | 0 | ABSL_FALLTHROUGH_INTENDED; |
611 | 0 | case FieldDescriptor::TYPE_INT64: |
612 | 0 | return &MessageToJsonState::RepeatedInt64FieldToValue; |
613 | 0 | default: |
614 | 0 | return absl::InvalidArgumentError(absl::StrCat( |
615 | 0 | "unexpected message field type: ", field->type_name())); |
616 | 0 | } |
617 | 0 | } |
618 | | |
619 | | absl::Status RepeatedBoolFieldToValue( |
620 | | const google::protobuf::Reflection* absl_nonnull reflection, |
621 | | const google::protobuf::Message& message, |
622 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
623 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
624 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
625 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
626 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_BOOL); |
627 | 0 | SetBoolValue(result, reflection->GetRepeatedBool(message, field, index)); |
628 | 0 | return absl::OkStatus(); |
629 | 0 | } |
630 | | |
631 | | absl::Status RepeatedInt32FieldToValue( |
632 | | const google::protobuf::Reflection* absl_nonnull reflection, |
633 | | const google::protobuf::Message& message, |
634 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
635 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
636 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
637 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
638 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_INT32); |
639 | 0 | SetNumberValue(result, reflection->GetRepeatedInt32(message, field, index)); |
640 | 0 | return absl::OkStatus(); |
641 | 0 | } |
642 | | |
643 | | absl::Status RepeatedInt64FieldToValue( |
644 | | const google::protobuf::Reflection* absl_nonnull reflection, |
645 | | const google::protobuf::Message& message, |
646 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
647 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
648 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
649 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
650 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_INT64); |
651 | 0 | SetNumberValue(result, reflection->GetRepeatedInt64(message, field, index)); |
652 | 0 | return absl::OkStatus(); |
653 | 0 | } |
654 | | |
655 | | absl::Status RepeatedUInt32FieldToValue( |
656 | | const google::protobuf::Reflection* absl_nonnull reflection, |
657 | | const google::protobuf::Message& message, |
658 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
659 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
660 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
661 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
662 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_UINT32); |
663 | 0 | SetNumberValue(result, |
664 | 0 | reflection->GetRepeatedUInt32(message, field, index)); |
665 | 0 | return absl::OkStatus(); |
666 | 0 | } |
667 | | |
668 | | absl::Status RepeatedUInt64FieldToValue( |
669 | | const google::protobuf::Reflection* absl_nonnull reflection, |
670 | | const google::protobuf::Message& message, |
671 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
672 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
673 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
674 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
675 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_UINT64); |
676 | 0 | SetNumberValue(result, |
677 | 0 | reflection->GetRepeatedUInt64(message, field, index)); |
678 | 0 | return absl::OkStatus(); |
679 | 0 | } |
680 | | |
681 | | absl::Status RepeatedFloatFieldToValue( |
682 | | const google::protobuf::Reflection* absl_nonnull reflection, |
683 | | const google::protobuf::Message& message, |
684 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
685 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
686 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
687 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
688 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_FLOAT); |
689 | 0 | SetNumberValue(result, reflection->GetRepeatedFloat(message, field, index)); |
690 | 0 | return absl::OkStatus(); |
691 | 0 | } |
692 | | |
693 | | absl::Status RepeatedDoubleFieldToValue( |
694 | | const google::protobuf::Reflection* absl_nonnull reflection, |
695 | | const google::protobuf::Message& message, |
696 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
697 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
698 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
699 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
700 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_DOUBLE); |
701 | 0 | SetNumberValue(result, |
702 | 0 | reflection->GetRepeatedDouble(message, field, index)); |
703 | 0 | return absl::OkStatus(); |
704 | 0 | } |
705 | | |
706 | | absl::Status RepeatedBytesFieldToValue( |
707 | | const google::protobuf::Reflection* absl_nonnull reflection, |
708 | | const google::protobuf::Message& message, |
709 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
710 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
711 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
712 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
713 | 0 | ABSL_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES); |
714 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_STRING); |
715 | 0 | absl::visit(absl::Overload( |
716 | 0 | [&](absl::string_view string) -> void { |
717 | 0 | SetStringValueFromBytes(result, string); |
718 | 0 | }, |
719 | 0 | [&](absl::Cord&& cord) -> void { |
720 | 0 | SetStringValueFromBytes(result, cord); |
721 | 0 | }), |
722 | 0 | AsVariant(GetRepeatedBytesField(reflection, message, field, |
723 | 0 | index, scratch_))); |
724 | 0 | return absl::OkStatus(); |
725 | 0 | } |
726 | | |
727 | | absl::Status RepeatedStringFieldToValue( |
728 | | const google::protobuf::Reflection* absl_nonnull reflection, |
729 | | const google::protobuf::Message& message, |
730 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
731 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
732 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
733 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
734 | 0 | ABSL_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_STRING); |
735 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_STRING); |
736 | 0 | absl::visit( |
737 | 0 | absl::Overload( |
738 | 0 | [&](absl::string_view string) -> void { |
739 | 0 | SetStringValue(result, string); |
740 | 0 | }, |
741 | 0 | [&](absl::Cord&& cord) -> void { SetStringValue(result, cord); }), |
742 | 0 | AsVariant(GetRepeatedStringField(reflection, message, field, index, |
743 | 0 | scratch_))); |
744 | 0 | return absl::OkStatus(); |
745 | 0 | } |
746 | | |
747 | | absl::Status RepeatedMessageFieldToValue( |
748 | | const google::protobuf::Reflection* absl_nonnull reflection, |
749 | | const google::protobuf::Message& message, |
750 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
751 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
752 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
753 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
754 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_MESSAGE); |
755 | 0 | return ToJson(reflection->GetRepeatedMessage(message, field, index), |
756 | 0 | result); |
757 | 0 | } |
758 | | |
759 | | absl::Status RepeatedEnumFieldToValue( |
760 | | const google::protobuf::Reflection* absl_nonnull reflection, |
761 | | const google::protobuf::Message& message, |
762 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
763 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
764 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
765 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
766 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_ENUM); |
767 | 0 | ABSL_DCHECK_NE(field->enum_type()->full_name(), |
768 | 0 | "google.protobuf.NullValue"); |
769 | 0 | if (const auto* value = reflection->GetRepeatedEnum(message, field, index); |
770 | 0 | value != nullptr) { |
771 | 0 | SetStringValue(result, value->name()); |
772 | 0 | } else { |
773 | 0 | SetNumberValue(result, |
774 | 0 | reflection->GetRepeatedEnumValue(message, field, index)); |
775 | 0 | } |
776 | 0 | return absl::OkStatus(); |
777 | 0 | } |
778 | | |
779 | | absl::Status RepeatedNullFieldToValue( |
780 | | const google::protobuf::Reflection* absl_nonnull reflection, |
781 | | const google::protobuf::Message& message, |
782 | | const google::protobuf::FieldDescriptor* absl_nonnull field, int index, |
783 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
784 | 0 | ABSL_DCHECK_EQ(reflection, message.GetReflection()); |
785 | 0 | ABSL_DCHECK(!field->is_map() && field->is_repeated()); |
786 | 0 | ABSL_DCHECK_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_ENUM); |
787 | 0 | ABSL_DCHECK_EQ(field->enum_type()->full_name(), |
788 | 0 | "google.protobuf.NullValue"); |
789 | 0 | SetNullValue(result); |
790 | 0 | return absl::OkStatus(); |
791 | 0 | } |
792 | | |
793 | | absl::Status MessageMapFieldToJson( |
794 | | const google::protobuf::Message& message, |
795 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
796 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
797 | 0 | const auto* reflection = message.GetReflection(); |
798 | 0 | if (reflection->FieldSize(message, field) == 0) { |
799 | 0 | return absl::OkStatus(); |
800 | 0 | } |
801 | 0 | const auto key_to_string = |
802 | 0 | GetMapFieldKeyToString(field->message_type()->map_key()); |
803 | 0 | const auto* value_descriptor = field->message_type()->map_value(); |
804 | 0 | CEL_ASSIGN_OR_RETURN(const auto value_to_value, |
805 | 0 | GetMapFieldValueToValue(value_descriptor)); |
806 | 0 | auto begin = extensions::protobuf_internal::ConstMapBegin(*reflection, |
807 | 0 | message, *field); |
808 | 0 | const auto end = extensions::protobuf_internal::ConstMapEnd( |
809 | 0 | *reflection, message, *field); |
810 | 0 | for (; begin != end; ++begin) { |
811 | 0 | auto key = (*key_to_string)(begin.GetKey()); |
812 | 0 | CEL_RETURN_IF_ERROR((this->*value_to_value)( |
813 | 0 | begin.GetValueRef(), value_descriptor, InsertField(result, key))); |
814 | 0 | } |
815 | 0 | return absl::OkStatus(); |
816 | 0 | } |
817 | | |
818 | | absl::Status MessageRepeatedFieldToJson( |
819 | | const google::protobuf::Message& message, |
820 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
821 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
822 | 0 | const auto* reflection = message.GetReflection(); |
823 | 0 | const int size = reflection->FieldSize(message, field); |
824 | 0 | if (size == 0) { |
825 | 0 | return absl::OkStatus(); |
826 | 0 | } |
827 | 0 | CEL_ASSIGN_OR_RETURN(const auto to_value, GetRepeatedFieldToValue(field)); |
828 | 0 | for (int index = 0; index < size; ++index) { |
829 | 0 | CEL_RETURN_IF_ERROR((this->*to_value)(reflection, message, field, index, |
830 | 0 | AddValues(result))); |
831 | 0 | } |
832 | 0 | return absl::OkStatus(); |
833 | 0 | } |
834 | | |
835 | | absl::Status MessageFieldToJson( |
836 | | const google::protobuf::Message& message, |
837 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
838 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
839 | 0 | if (field->is_map()) { |
840 | 0 | return MessageMapFieldToJson(message, field, MutableStructValue(result)); |
841 | 0 | } |
842 | 0 | if (field->is_repeated()) { |
843 | 0 | return MessageRepeatedFieldToJson(message, field, |
844 | 0 | MutableListValue(result)); |
845 | 0 | } |
846 | 0 | const auto* reflection = message.GetReflection(); |
847 | 0 | switch (field->type()) { |
848 | 0 | case FieldDescriptor::TYPE_DOUBLE: |
849 | 0 | SetNumberValue(result, reflection->GetDouble(message, field)); |
850 | 0 | break; |
851 | 0 | case FieldDescriptor::TYPE_FLOAT: |
852 | 0 | SetNumberValue(result, reflection->GetFloat(message, field)); |
853 | 0 | break; |
854 | 0 | case FieldDescriptor::TYPE_FIXED64: |
855 | 0 | ABSL_FALLTHROUGH_INTENDED; |
856 | 0 | case FieldDescriptor::TYPE_UINT64: |
857 | 0 | SetNumberValue(result, reflection->GetUInt64(message, field)); |
858 | 0 | break; |
859 | 0 | case FieldDescriptor::TYPE_BOOL: |
860 | 0 | SetBoolValue(result, reflection->GetBool(message, field)); |
861 | 0 | break; |
862 | 0 | case FieldDescriptor::TYPE_STRING: |
863 | 0 | StringValueToJson( |
864 | 0 | well_known_types::GetStringField(message, field, scratch_), result); |
865 | 0 | break; |
866 | 0 | case FieldDescriptor::TYPE_GROUP: |
867 | 0 | ABSL_FALLTHROUGH_INTENDED; |
868 | 0 | case FieldDescriptor::TYPE_MESSAGE: |
869 | 0 | return ToJson((reflection->GetMessage)(message, field), result); |
870 | 0 | case FieldDescriptor::TYPE_BYTES: |
871 | 0 | BytesValueToJson( |
872 | 0 | well_known_types::GetBytesField(message, field, scratch_), result); |
873 | 0 | break; |
874 | 0 | case FieldDescriptor::TYPE_FIXED32: |
875 | 0 | ABSL_FALLTHROUGH_INTENDED; |
876 | 0 | case FieldDescriptor::TYPE_UINT32: |
877 | 0 | SetNumberValue(result, reflection->GetUInt32(message, field)); |
878 | 0 | break; |
879 | 0 | case FieldDescriptor::TYPE_ENUM: { |
880 | 0 | const auto* enum_descriptor = field->enum_type(); |
881 | 0 | if (enum_descriptor->full_name() == "google.protobuf.NullValue") { |
882 | 0 | SetNullValue(result); |
883 | 0 | } else { |
884 | 0 | const auto* enum_value_descriptor = |
885 | 0 | reflection->GetEnum(message, field); |
886 | 0 | if (enum_value_descriptor != nullptr) { |
887 | 0 | SetStringValue(result, enum_value_descriptor->name()); |
888 | 0 | } else { |
889 | 0 | SetNumberValue(result, reflection->GetEnumValue(message, field)); |
890 | 0 | } |
891 | 0 | } |
892 | 0 | } break; |
893 | 0 | case FieldDescriptor::TYPE_SFIXED32: |
894 | 0 | ABSL_FALLTHROUGH_INTENDED; |
895 | 0 | case FieldDescriptor::TYPE_SINT32: |
896 | 0 | ABSL_FALLTHROUGH_INTENDED; |
897 | 0 | case FieldDescriptor::TYPE_INT32: |
898 | 0 | SetNumberValue(result, reflection->GetInt32(message, field)); |
899 | 0 | break; |
900 | 0 | case FieldDescriptor::TYPE_SFIXED64: |
901 | 0 | ABSL_FALLTHROUGH_INTENDED; |
902 | 0 | case FieldDescriptor::TYPE_SINT64: |
903 | 0 | ABSL_FALLTHROUGH_INTENDED; |
904 | 0 | case FieldDescriptor::TYPE_INT64: |
905 | 0 | SetNumberValue(result, reflection->GetInt64(message, field)); |
906 | 0 | break; |
907 | 0 | default: |
908 | 0 | return absl::InvalidArgumentError(absl::StrCat( |
909 | 0 | "unexpected message field type: ", field->type_name())); |
910 | 0 | } |
911 | 0 | return absl::OkStatus(); |
912 | 0 | } |
913 | | |
914 | | absl::Status MessageToJson(const google::protobuf::Message& message, |
915 | 0 | google::protobuf::MessageLite* absl_nonnull result) { |
916 | 0 | std::vector<const google::protobuf::FieldDescriptor*> fields; |
917 | 0 | const auto* reflection = message.GetReflection(); |
918 | 0 | reflection->ListFields(message, &fields); |
919 | 0 | if (!fields.empty()) { |
920 | 0 | for (const auto* field : fields) { |
921 | 0 | CEL_RETURN_IF_ERROR(MessageFieldToJson( |
922 | 0 | message, field, InsertField(result, field->json_name()))); |
923 | 0 | } |
924 | 0 | } |
925 | 0 | return absl::OkStatus(); |
926 | 0 | } |
927 | | |
928 | | void StringValueToJson(const well_known_types::StringValue& value, |
929 | 0 | google::protobuf::MessageLite* absl_nonnull result) const { |
930 | 0 | absl::visit(absl::Overload([&](absl::string_view string) |
931 | 0 | -> void { SetStringValue(result, string); }, |
932 | 0 | [&](const absl::Cord& cord) -> void { |
933 | 0 | SetStringValue(result, cord); |
934 | 0 | }), |
935 | 0 | AsVariant(value)); |
936 | 0 | } |
937 | | |
938 | | void BytesValueToJson(const well_known_types::BytesValue& value, |
939 | 0 | google::protobuf::MessageLite* absl_nonnull result) const { |
940 | 0 | absl::visit(absl::Overload( |
941 | 0 | [&](absl::string_view string) -> void { |
942 | 0 | SetStringValueFromBytes(result, string); |
943 | 0 | }, |
944 | 0 | [&](const absl::Cord& cord) -> void { |
945 | 0 | SetStringValueFromBytes(result, cord); |
946 | 0 | }), |
947 | 0 | AsVariant(value)); |
948 | 0 | } |
949 | | |
950 | | virtual void SetNullValue( |
951 | | google::protobuf::MessageLite* absl_nonnull message) const = 0; |
952 | | |
953 | | virtual void SetBoolValue(google::protobuf::MessageLite* absl_nonnull message, |
954 | | bool value) const = 0; |
955 | | |
956 | | virtual void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
957 | | double value) const = 0; |
958 | | |
959 | | void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
960 | 0 | float value) const { |
961 | 0 | SetNumberValue(message, static_cast<double>(value)); |
962 | 0 | } |
963 | | |
964 | | virtual void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
965 | | int64_t value) const = 0; |
966 | | |
967 | | void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
968 | 0 | int32_t value) const { |
969 | 0 | SetNumberValue(message, static_cast<double>(value)); |
970 | 0 | } |
971 | | |
972 | | virtual void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
973 | | uint64_t value) const = 0; |
974 | | |
975 | | void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
976 | 0 | uint32_t value) const { |
977 | 0 | SetNumberValue(message, static_cast<double>(value)); |
978 | 0 | } |
979 | | |
980 | | virtual void SetStringValue(google::protobuf::MessageLite* absl_nonnull message, |
981 | | absl::string_view value) const = 0; |
982 | | |
983 | | virtual void SetStringValue(google::protobuf::MessageLite* absl_nonnull message, |
984 | | const absl::Cord& value) const = 0; |
985 | | |
986 | | void SetStringValueFromBytes(google::protobuf::MessageLite* absl_nonnull message, |
987 | 0 | absl::string_view value) const { |
988 | 0 | if (value.empty()) { |
989 | 0 | SetStringValue(message, value); |
990 | 0 | return; |
991 | 0 | } |
992 | 0 | SetStringValue(message, absl::Base64Escape(value)); |
993 | 0 | } |
994 | | |
995 | | void SetStringValueFromBytes(google::protobuf::MessageLite* absl_nonnull message, |
996 | 0 | const absl::Cord& value) const { |
997 | 0 | if (value.empty()) { |
998 | 0 | SetStringValue(message, value); |
999 | 0 | return; |
1000 | 0 | } |
1001 | 0 | if (auto flat = value.TryFlat(); flat) { |
1002 | 0 | SetStringValue(message, absl::Base64Escape(*flat)); |
1003 | 0 | return; |
1004 | 0 | } |
1005 | 0 | SetStringValue(message, |
1006 | 0 | absl::Base64Escape(static_cast<std::string>(value))); |
1007 | 0 | } |
1008 | | |
1009 | | virtual google::protobuf::MessageLite* absl_nonnull MutableListValue( |
1010 | | google::protobuf::MessageLite* absl_nonnull message) const = 0; |
1011 | | |
1012 | | virtual google::protobuf::MessageLite* absl_nonnull MutableStructValue( |
1013 | | google::protobuf::MessageLite* absl_nonnull message) const = 0; |
1014 | | |
1015 | | virtual google::protobuf::MessageLite* absl_nonnull AddValues( |
1016 | | google::protobuf::MessageLite* absl_nonnull message) const = 0; |
1017 | | |
1018 | | virtual google::protobuf::MessageLite* absl_nonnull InsertField( |
1019 | | google::protobuf::MessageLite* absl_nonnull message, |
1020 | | absl::string_view name) const = 0; |
1021 | | |
1022 | | const google::protobuf::DescriptorPool* absl_nonnull const descriptor_pool_; |
1023 | | google::protobuf::MessageFactory* absl_nonnull const message_factory_; |
1024 | | std::string scratch_; |
1025 | | Reflection reflection_; |
1026 | | }; |
1027 | | |
1028 | | class GeneratedMessageToJsonState final : public MessageToJsonState { |
1029 | | public: |
1030 | | using MessageToJsonState::MessageToJsonState; |
1031 | | |
1032 | 0 | absl::Status Initialize(google::protobuf::MessageLite* absl_nonnull message) override { |
1033 | | // Nothing to do. |
1034 | 0 | return absl::OkStatus(); |
1035 | 0 | } |
1036 | | |
1037 | | private: |
1038 | 0 | void SetNullValue(google::protobuf::MessageLite* absl_nonnull message) const override { |
1039 | 0 | ValueReflection::SetNullValue( |
1040 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message)); |
1041 | 0 | } |
1042 | | |
1043 | | void SetBoolValue(google::protobuf::MessageLite* absl_nonnull message, |
1044 | 0 | bool value) const override { |
1045 | 0 | ValueReflection::SetBoolValue( |
1046 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message), value); |
1047 | 0 | } |
1048 | | |
1049 | | void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
1050 | 0 | double value) const override { |
1051 | 0 | ValueReflection::SetNumberValue( |
1052 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message), value); |
1053 | 0 | } |
1054 | | |
1055 | | void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
1056 | 0 | int64_t value) const override { |
1057 | 0 | ValueReflection::SetNumberValue( |
1058 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message), value); |
1059 | 0 | } |
1060 | | |
1061 | | void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
1062 | 0 | uint64_t value) const override { |
1063 | 0 | ValueReflection::SetNumberValue( |
1064 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message), value); |
1065 | 0 | } |
1066 | | |
1067 | | void SetStringValue(google::protobuf::MessageLite* absl_nonnull message, |
1068 | 0 | absl::string_view value) const override { |
1069 | 0 | ValueReflection::SetStringValue( |
1070 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message), value); |
1071 | 0 | } |
1072 | | |
1073 | | void SetStringValue(google::protobuf::MessageLite* absl_nonnull message, |
1074 | 0 | const absl::Cord& value) const override { |
1075 | 0 | ValueReflection::SetStringValue( |
1076 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message), value); |
1077 | 0 | } |
1078 | | |
1079 | | google::protobuf::MessageLite* absl_nonnull MutableListValue( |
1080 | 0 | google::protobuf::MessageLite* absl_nonnull message) const override { |
1081 | 0 | return ValueReflection::MutableListValue( |
1082 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message)); |
1083 | 0 | } |
1084 | | |
1085 | | google::protobuf::MessageLite* absl_nonnull MutableStructValue( |
1086 | 0 | google::protobuf::MessageLite* absl_nonnull message) const override { |
1087 | 0 | return ValueReflection::MutableStructValue( |
1088 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message)); |
1089 | 0 | } |
1090 | | |
1091 | | google::protobuf::MessageLite* absl_nonnull AddValues( |
1092 | 0 | google::protobuf::MessageLite* absl_nonnull message) const override { |
1093 | 0 | return ListValueReflection::AddValues( |
1094 | 0 | google::protobuf::DownCastMessage<google::protobuf::ListValue>(message)); |
1095 | 0 | } |
1096 | | |
1097 | | google::protobuf::MessageLite* absl_nonnull InsertField( |
1098 | | google::protobuf::MessageLite* absl_nonnull message, |
1099 | 0 | absl::string_view name) const override { |
1100 | 0 | return StructReflection::InsertField( |
1101 | 0 | google::protobuf::DownCastMessage<google::protobuf::Struct>(message), name); |
1102 | 0 | } |
1103 | | }; |
1104 | | |
1105 | | class DynamicMessageToJsonState final : public MessageToJsonState { |
1106 | | public: |
1107 | | using MessageToJsonState::MessageToJsonState; |
1108 | | |
1109 | 0 | absl::Status Initialize(google::protobuf::MessageLite* absl_nonnull message) override { |
1110 | 0 | CEL_RETURN_IF_ERROR(reflection_.Initialize( |
1111 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)->GetDescriptor())); |
1112 | 0 | return absl::OkStatus(); |
1113 | 0 | } |
1114 | | |
1115 | | private: |
1116 | 0 | void SetNullValue(google::protobuf::MessageLite* absl_nonnull message) const override { |
1117 | 0 | reflection_.Value().SetNullValue( |
1118 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1119 | 0 | } |
1120 | | |
1121 | | void SetBoolValue(google::protobuf::MessageLite* absl_nonnull message, |
1122 | 0 | bool value) const override { |
1123 | 0 | reflection_.Value().SetBoolValue( |
1124 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message), value); |
1125 | 0 | } |
1126 | | |
1127 | | void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
1128 | 0 | double value) const override { |
1129 | 0 | reflection_.Value().SetNumberValue( |
1130 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message), value); |
1131 | 0 | } |
1132 | | |
1133 | | void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
1134 | 0 | int64_t value) const override { |
1135 | 0 | reflection_.Value().SetNumberValue( |
1136 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message), value); |
1137 | 0 | } |
1138 | | |
1139 | | void SetNumberValue(google::protobuf::MessageLite* absl_nonnull message, |
1140 | 0 | uint64_t value) const override { |
1141 | 0 | reflection_.Value().SetNumberValue( |
1142 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message), value); |
1143 | 0 | } |
1144 | | |
1145 | | void SetStringValue(google::protobuf::MessageLite* absl_nonnull message, |
1146 | 0 | absl::string_view value) const override { |
1147 | 0 | reflection_.Value().SetStringValue( |
1148 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message), value); |
1149 | 0 | } |
1150 | | |
1151 | | void SetStringValue(google::protobuf::MessageLite* absl_nonnull message, |
1152 | 0 | const absl::Cord& value) const override { |
1153 | 0 | reflection_.Value().SetStringValue( |
1154 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message), value); |
1155 | 0 | } |
1156 | | |
1157 | | google::protobuf::MessageLite* absl_nonnull MutableListValue( |
1158 | 0 | google::protobuf::MessageLite* absl_nonnull message) const override { |
1159 | 0 | return reflection_.Value().MutableListValue( |
1160 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1161 | 0 | } |
1162 | | |
1163 | | google::protobuf::MessageLite* absl_nonnull MutableStructValue( |
1164 | 0 | google::protobuf::MessageLite* absl_nonnull message) const override { |
1165 | 0 | return reflection_.Value().MutableStructValue( |
1166 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1167 | 0 | } |
1168 | | |
1169 | | google::protobuf::MessageLite* absl_nonnull AddValues( |
1170 | 0 | google::protobuf::MessageLite* absl_nonnull message) const override { |
1171 | 0 | return reflection_.ListValue().AddValues( |
1172 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1173 | 0 | } |
1174 | | |
1175 | | google::protobuf::MessageLite* absl_nonnull InsertField( |
1176 | | google::protobuf::MessageLite* absl_nonnull message, |
1177 | 0 | absl::string_view name) const override { |
1178 | 0 | return reflection_.Struct().InsertField( |
1179 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message), name); |
1180 | 0 | } |
1181 | | |
1182 | | JsonReflection reflection_; |
1183 | | }; |
1184 | | |
1185 | | } // namespace |
1186 | | |
1187 | | absl::Status MessageToJson( |
1188 | | const google::protobuf::Message& message, |
1189 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
1190 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
1191 | 0 | google::protobuf::Value* absl_nonnull result) { |
1192 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
1193 | 0 | ABSL_DCHECK(message_factory != nullptr); |
1194 | 0 | ABSL_DCHECK(result != nullptr); |
1195 | 0 | auto state = std::make_unique<GeneratedMessageToJsonState>(descriptor_pool, |
1196 | 0 | message_factory); |
1197 | 0 | CEL_RETURN_IF_ERROR(state->Initialize(result)); |
1198 | 0 | return state->ToJson(message, result); |
1199 | 0 | } |
1200 | | |
1201 | | absl::Status MessageToJson( |
1202 | | const google::protobuf::Message& message, |
1203 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
1204 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
1205 | 0 | google::protobuf::Struct* absl_nonnull result) { |
1206 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
1207 | 0 | ABSL_DCHECK(message_factory != nullptr); |
1208 | 0 | ABSL_DCHECK(result != nullptr); |
1209 | 0 | auto state = std::make_unique<GeneratedMessageToJsonState>(descriptor_pool, |
1210 | 0 | message_factory); |
1211 | 0 | CEL_RETURN_IF_ERROR(state->Initialize(result)); |
1212 | 0 | return state->ToJsonObject(message, result); |
1213 | 0 | } |
1214 | | |
1215 | | absl::Status MessageToJson( |
1216 | | const google::protobuf::Message& message, |
1217 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
1218 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
1219 | 0 | google::protobuf::Message* absl_nonnull result) { |
1220 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
1221 | 0 | ABSL_DCHECK(message_factory != nullptr); |
1222 | 0 | ABSL_DCHECK(result != nullptr); |
1223 | 0 | auto state = std::make_unique<DynamicMessageToJsonState>(descriptor_pool, |
1224 | 0 | message_factory); |
1225 | 0 | CEL_RETURN_IF_ERROR(state->Initialize(result)); |
1226 | 0 | switch (result->GetDescriptor()->well_known_type()) { |
1227 | 0 | case google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE: |
1228 | 0 | return state->ToJson(message, result); |
1229 | 0 | case google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT: |
1230 | 0 | return state->ToJsonObject(message, result); |
1231 | 0 | default: |
1232 | 0 | return absl::InvalidArgumentError("cannot convert message to JSON array"); |
1233 | 0 | } |
1234 | 0 | } |
1235 | | |
1236 | | absl::Status MessageFieldToJson( |
1237 | | const google::protobuf::Message& message, |
1238 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
1239 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
1240 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
1241 | 0 | google::protobuf::Value* absl_nonnull result) { |
1242 | 0 | ABSL_DCHECK_EQ(field->containing_type(), message.GetDescriptor()); |
1243 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
1244 | 0 | ABSL_DCHECK(message_factory != nullptr); |
1245 | 0 | ABSL_DCHECK(result != nullptr); |
1246 | 0 | auto state = std::make_unique<GeneratedMessageToJsonState>(descriptor_pool, |
1247 | 0 | message_factory); |
1248 | 0 | CEL_RETURN_IF_ERROR(state->Initialize(result)); |
1249 | 0 | return state->FieldToJson(message, field, result); |
1250 | 0 | } |
1251 | | |
1252 | | absl::Status MessageFieldToJson( |
1253 | | const google::protobuf::Message& message, |
1254 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
1255 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
1256 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
1257 | 0 | google::protobuf::ListValue* absl_nonnull result) { |
1258 | 0 | ABSL_DCHECK_EQ(field->containing_type(), message.GetDescriptor()); |
1259 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
1260 | 0 | ABSL_DCHECK(message_factory != nullptr); |
1261 | 0 | ABSL_DCHECK(result != nullptr); |
1262 | 0 | auto state = std::make_unique<GeneratedMessageToJsonState>(descriptor_pool, |
1263 | 0 | message_factory); |
1264 | 0 | CEL_RETURN_IF_ERROR(state->Initialize(result)); |
1265 | 0 | return state->FieldToJsonArray(message, field, result); |
1266 | 0 | } |
1267 | | |
1268 | | absl::Status MessageFieldToJson( |
1269 | | const google::protobuf::Message& message, |
1270 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
1271 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
1272 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
1273 | 0 | google::protobuf::Struct* absl_nonnull result) { |
1274 | 0 | ABSL_DCHECK_EQ(field->containing_type(), message.GetDescriptor()); |
1275 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
1276 | 0 | ABSL_DCHECK(message_factory != nullptr); |
1277 | 0 | ABSL_DCHECK(result != nullptr); |
1278 | 0 | auto state = std::make_unique<GeneratedMessageToJsonState>(descriptor_pool, |
1279 | 0 | message_factory); |
1280 | 0 | CEL_RETURN_IF_ERROR(state->Initialize(result)); |
1281 | 0 | return state->FieldToJsonObject(message, field, result); |
1282 | 0 | } |
1283 | | |
1284 | | absl::Status MessageFieldToJson( |
1285 | | const google::protobuf::Message& message, |
1286 | | const google::protobuf::FieldDescriptor* absl_nonnull field, |
1287 | | const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool, |
1288 | | google::protobuf::MessageFactory* absl_nonnull message_factory, |
1289 | 0 | google::protobuf::Message* absl_nonnull result) { |
1290 | 0 | ABSL_DCHECK_EQ(field->containing_type(), message.GetDescriptor()); |
1291 | 0 | ABSL_DCHECK(descriptor_pool != nullptr); |
1292 | 0 | ABSL_DCHECK(message_factory != nullptr); |
1293 | 0 | ABSL_DCHECK(result != nullptr); |
1294 | 0 | auto state = std::make_unique<DynamicMessageToJsonState>(descriptor_pool, |
1295 | 0 | message_factory); |
1296 | 0 | CEL_RETURN_IF_ERROR(state->Initialize(result)); |
1297 | 0 | switch (result->GetDescriptor()->well_known_type()) { |
1298 | 0 | case google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE: |
1299 | 0 | return state->FieldToJson(message, field, result); |
1300 | 0 | case google::protobuf::Descriptor::WELLKNOWNTYPE_LISTVALUE: |
1301 | 0 | return state->FieldToJsonArray(message, field, result); |
1302 | 0 | case google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT: |
1303 | 0 | return state->FieldToJsonObject(message, field, result); |
1304 | 0 | default: |
1305 | 0 | return absl::InternalError("unreachable"); |
1306 | 0 | } |
1307 | 0 | } |
1308 | | |
1309 | 0 | absl::Status CheckJson(const google::protobuf::MessageLite& message) { |
1310 | 0 | if (const auto* generated_message = |
1311 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::Value>(&message); |
1312 | 0 | generated_message) { |
1313 | 0 | return absl::OkStatus(); |
1314 | 0 | } |
1315 | 0 | if (const auto* dynamic_message = |
1316 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::Message>(&message); |
1317 | 0 | dynamic_message) { |
1318 | 0 | CEL_ASSIGN_OR_RETURN(auto reflection, |
1319 | 0 | GetValueReflection(dynamic_message->GetDescriptor())); |
1320 | 0 | CEL_RETURN_IF_ERROR( |
1321 | 0 | GetListValueReflection(reflection.GetListValueDescriptor()).status()); |
1322 | 0 | CEL_RETURN_IF_ERROR( |
1323 | 0 | GetStructReflection(reflection.GetStructDescriptor()).status()); |
1324 | 0 | return absl::OkStatus(); |
1325 | 0 | } |
1326 | 0 | return absl::InvalidArgumentError( |
1327 | 0 | absl::StrCat("message must be an instance of `google.protobuf.Value`: ", |
1328 | 0 | message.GetTypeName())); |
1329 | 0 | } |
1330 | | |
1331 | 0 | absl::Status CheckJsonList(const google::protobuf::MessageLite& message) { |
1332 | 0 | if (const auto* generated_message = |
1333 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::ListValue>(&message); |
1334 | 0 | generated_message) { |
1335 | 0 | return absl::OkStatus(); |
1336 | 0 | } |
1337 | 0 | if (const auto* dynamic_message = |
1338 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::Message>(&message); |
1339 | 0 | dynamic_message) { |
1340 | 0 | CEL_ASSIGN_OR_RETURN( |
1341 | 0 | auto reflection, |
1342 | 0 | GetListValueReflection(dynamic_message->GetDescriptor())); |
1343 | 0 | CEL_ASSIGN_OR_RETURN(auto value_reflection, |
1344 | 0 | GetValueReflection(reflection.GetValueDescriptor())); |
1345 | 0 | CEL_RETURN_IF_ERROR( |
1346 | 0 | GetStructReflection(value_reflection.GetStructDescriptor()).status()); |
1347 | 0 | return absl::OkStatus(); |
1348 | 0 | } |
1349 | 0 | return absl::InvalidArgumentError(absl::StrCat( |
1350 | 0 | "message must be an instance of `google.protobuf.ListValue`: ", |
1351 | 0 | message.GetTypeName())); |
1352 | 0 | } |
1353 | | |
1354 | 0 | absl::Status CheckJsonMap(const google::protobuf::MessageLite& message) { |
1355 | 0 | if (const auto* generated_message = |
1356 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::Struct>(&message); |
1357 | 0 | generated_message) { |
1358 | 0 | return absl::OkStatus(); |
1359 | 0 | } |
1360 | 0 | if (const auto* dynamic_message = |
1361 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::Message>(&message); |
1362 | 0 | dynamic_message) { |
1363 | 0 | CEL_ASSIGN_OR_RETURN(auto reflection, |
1364 | 0 | GetStructReflection(dynamic_message->GetDescriptor())); |
1365 | 0 | CEL_ASSIGN_OR_RETURN(auto value_reflection, |
1366 | 0 | GetValueReflection(reflection.GetValueDescriptor())); |
1367 | 0 | CEL_RETURN_IF_ERROR( |
1368 | 0 | GetListValueReflection(value_reflection.GetListValueDescriptor()) |
1369 | 0 | .status()); |
1370 | 0 | return absl::OkStatus(); |
1371 | 0 | } |
1372 | 0 | return absl::InvalidArgumentError( |
1373 | 0 | absl::StrCat("message must be an instance of `google.protobuf.Struct`: ", |
1374 | 0 | message.GetTypeName())); |
1375 | 0 | } |
1376 | | |
1377 | | namespace { |
1378 | | |
1379 | | class JsonMapIterator final { |
1380 | | public: |
1381 | | using Generated = |
1382 | | typename google::protobuf::Map<std::string, |
1383 | | google::protobuf::Value>::const_iterator; |
1384 | | using Dynamic = google::protobuf::ConstMapIterator; |
1385 | | using Value = std::pair<well_known_types::StringValue, |
1386 | | const google::protobuf::MessageLite* absl_nonnull>; |
1387 | | |
1388 | | // NOLINTNEXTLINE(google-explicit-constructor) |
1389 | 0 | JsonMapIterator(Generated generated) : variant_(std::move(generated)) {} |
1390 | | |
1391 | | // NOLINTNEXTLINE(google-explicit-constructor) |
1392 | 0 | JsonMapIterator(Dynamic dynamic) : variant_(std::move(dynamic)) {} |
1393 | | |
1394 | | JsonMapIterator(const JsonMapIterator&) = default; |
1395 | | JsonMapIterator(JsonMapIterator&&) = default; |
1396 | | JsonMapIterator& operator=(const JsonMapIterator&) = default; |
1397 | | JsonMapIterator& operator=(JsonMapIterator&&) = default; |
1398 | | |
1399 | 0 | Value Next(std::string& scratch ABSL_ATTRIBUTE_LIFETIME_BOUND) { |
1400 | 0 | Value result; |
1401 | 0 | absl::visit(absl::Overload( |
1402 | 0 | [&](Generated& generated) -> void { |
1403 | 0 | result = std::pair{absl::string_view(generated->first), |
1404 | 0 | &generated->second}; |
1405 | 0 | ++generated; |
1406 | 0 | }, |
1407 | 0 | [&](Dynamic& dynamic) -> void { |
1408 | 0 | const auto& key = dynamic.GetKey().GetStringValue(); |
1409 | 0 | scratch.assign(key.data(), key.size()); |
1410 | 0 | result = |
1411 | 0 | std::pair{absl::string_view(scratch), |
1412 | 0 | &dynamic.GetValueRef().GetMessageValue()}; |
1413 | 0 | ++dynamic; |
1414 | 0 | }), |
1415 | 0 | variant_); |
1416 | 0 | return result; |
1417 | 0 | } |
1418 | | |
1419 | | private: |
1420 | | std::variant<Generated, Dynamic> variant_; |
1421 | | }; |
1422 | | |
1423 | | class JsonAccessor { |
1424 | | public: |
1425 | 0 | virtual ~JsonAccessor() = default; |
1426 | | |
1427 | | virtual google::protobuf::Value::KindCase GetKindCase( |
1428 | | const google::protobuf::MessageLite& message) const = 0; |
1429 | | |
1430 | | virtual bool GetBoolValue(const google::protobuf::MessageLite& message) const = 0; |
1431 | | |
1432 | | virtual double GetNumberValue(const google::protobuf::MessageLite& message) const = 0; |
1433 | | |
1434 | | virtual well_known_types::StringValue GetStringValue( |
1435 | | const google::protobuf::MessageLite& message, |
1436 | | std::string& scratch ABSL_ATTRIBUTE_LIFETIME_BOUND) const = 0; |
1437 | | |
1438 | | virtual const google::protobuf::MessageLite& GetListValue( |
1439 | | const google::protobuf::MessageLite& message) const = 0; |
1440 | | |
1441 | | virtual int ValuesSize(const google::protobuf::MessageLite& message) const = 0; |
1442 | | |
1443 | | virtual const google::protobuf::MessageLite& Values(const google::protobuf::MessageLite& message, |
1444 | | int index) const = 0; |
1445 | | |
1446 | | virtual const google::protobuf::MessageLite& GetStructValue( |
1447 | | const google::protobuf::MessageLite& message) const = 0; |
1448 | | |
1449 | | virtual int FieldsSize(const google::protobuf::MessageLite& message) const = 0; |
1450 | | |
1451 | | virtual const google::protobuf::MessageLite* absl_nullable FindField( |
1452 | | const google::protobuf::MessageLite& message, absl::string_view name) const = 0; |
1453 | | |
1454 | | virtual JsonMapIterator IterateFields( |
1455 | | const google::protobuf::MessageLite& message) const = 0; |
1456 | | }; |
1457 | | |
1458 | | class GeneratedJsonAccessor final : public JsonAccessor { |
1459 | | public: |
1460 | 0 | static const GeneratedJsonAccessor* absl_nonnull Singleton() { |
1461 | 0 | static const absl::NoDestructor<GeneratedJsonAccessor> singleton; |
1462 | 0 | return &*singleton; |
1463 | 0 | } |
1464 | | |
1465 | | google::protobuf::Value::KindCase GetKindCase( |
1466 | 0 | const google::protobuf::MessageLite& message) const override { |
1467 | 0 | return ValueReflection::GetKindCase( |
1468 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message)); |
1469 | 0 | } |
1470 | | |
1471 | 0 | bool GetBoolValue(const google::protobuf::MessageLite& message) const override { |
1472 | 0 | return ValueReflection::GetBoolValue( |
1473 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message)); |
1474 | 0 | } |
1475 | | |
1476 | 0 | double GetNumberValue(const google::protobuf::MessageLite& message) const override { |
1477 | 0 | return ValueReflection::GetNumberValue( |
1478 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message)); |
1479 | 0 | } |
1480 | | |
1481 | | well_known_types::StringValue GetStringValue( |
1482 | 0 | const google::protobuf::MessageLite& message, std::string&) const override { |
1483 | 0 | return ValueReflection::GetStringValue( |
1484 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message)); |
1485 | 0 | } |
1486 | | |
1487 | | const google::protobuf::MessageLite& GetListValue( |
1488 | 0 | const google::protobuf::MessageLite& message) const override { |
1489 | 0 | return ValueReflection::GetListValue( |
1490 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message)); |
1491 | 0 | } |
1492 | | |
1493 | 0 | int ValuesSize(const google::protobuf::MessageLite& message) const override { |
1494 | 0 | return ListValueReflection::ValuesSize( |
1495 | 0 | google::protobuf::DownCastMessage<google::protobuf::ListValue>(message)); |
1496 | 0 | } |
1497 | | |
1498 | | const google::protobuf::MessageLite& Values(const google::protobuf::MessageLite& message, |
1499 | 0 | int index) const override { |
1500 | 0 | return ListValueReflection::Values( |
1501 | 0 | google::protobuf::DownCastMessage<google::protobuf::ListValue>(message), index); |
1502 | 0 | } |
1503 | | |
1504 | | const google::protobuf::MessageLite& GetStructValue( |
1505 | 0 | const google::protobuf::MessageLite& message) const override { |
1506 | 0 | return ValueReflection::GetStructValue( |
1507 | 0 | google::protobuf::DownCastMessage<google::protobuf::Value>(message)); |
1508 | 0 | } |
1509 | | |
1510 | 0 | int FieldsSize(const google::protobuf::MessageLite& message) const override { |
1511 | 0 | return StructReflection::FieldsSize( |
1512 | 0 | google::protobuf::DownCastMessage<google::protobuf::Struct>(message)); |
1513 | 0 | } |
1514 | | |
1515 | | const google::protobuf::MessageLite* absl_nullable FindField( |
1516 | | const google::protobuf::MessageLite& message, |
1517 | 0 | absl::string_view name) const override { |
1518 | 0 | return StructReflection::FindField( |
1519 | 0 | google::protobuf::DownCastMessage<google::protobuf::Struct>(message), name); |
1520 | 0 | } |
1521 | | |
1522 | | JsonMapIterator IterateFields( |
1523 | 0 | const google::protobuf::MessageLite& message) const override { |
1524 | 0 | return StructReflection::BeginFields( |
1525 | 0 | google::protobuf::DownCastMessage<google::protobuf::Struct>(message)); |
1526 | 0 | } |
1527 | | }; |
1528 | | |
1529 | | class DynamicJsonAccessor final : public JsonAccessor { |
1530 | | public: |
1531 | 0 | void InitializeValue(const google::protobuf::Message& message) { |
1532 | 0 | ABSL_CHECK_OK(reflection_.Initialize(message.GetDescriptor())); // Crash OK |
1533 | 0 | } |
1534 | | |
1535 | 0 | void InitializeListValue(const google::protobuf::Message& message) { |
1536 | 0 | ABSL_CHECK_OK(reflection_.Initialize(message.GetDescriptor())); // Crash OK |
1537 | 0 | } |
1538 | | |
1539 | 0 | void InitializeStruct(const google::protobuf::Message& message) { |
1540 | 0 | ABSL_CHECK_OK(reflection_.Initialize(message.GetDescriptor())); // Crash OK |
1541 | 0 | } |
1542 | | |
1543 | | google::protobuf::Value::KindCase GetKindCase( |
1544 | 0 | const google::protobuf::MessageLite& message) const override { |
1545 | 0 | return reflection_.Value().GetKindCase( |
1546 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1547 | 0 | } |
1548 | | |
1549 | 0 | bool GetBoolValue(const google::protobuf::MessageLite& message) const override { |
1550 | 0 | return reflection_.Value().GetBoolValue( |
1551 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1552 | 0 | } |
1553 | | |
1554 | 0 | double GetNumberValue(const google::protobuf::MessageLite& message) const override { |
1555 | 0 | return reflection_.Value().GetNumberValue( |
1556 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1557 | 0 | } |
1558 | | |
1559 | | well_known_types::StringValue GetStringValue( |
1560 | 0 | const google::protobuf::MessageLite& message, std::string& scratch) const override { |
1561 | 0 | return reflection_.Value().GetStringValue( |
1562 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message), scratch); |
1563 | 0 | } |
1564 | | |
1565 | | const google::protobuf::MessageLite& GetListValue( |
1566 | 0 | const google::protobuf::MessageLite& message) const override { |
1567 | 0 | return reflection_.Value().GetListValue( |
1568 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1569 | 0 | } |
1570 | | |
1571 | 0 | int ValuesSize(const google::protobuf::MessageLite& message) const override { |
1572 | 0 | return reflection_.ListValue().ValuesSize( |
1573 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1574 | 0 | } |
1575 | | |
1576 | | const google::protobuf::MessageLite& Values(const google::protobuf::MessageLite& message, |
1577 | 0 | int index) const override { |
1578 | 0 | return reflection_.ListValue().Values( |
1579 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message), index); |
1580 | 0 | } |
1581 | | |
1582 | | const google::protobuf::MessageLite& GetStructValue( |
1583 | 0 | const google::protobuf::MessageLite& message) const override { |
1584 | 0 | return reflection_.Value().GetStructValue( |
1585 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1586 | 0 | } |
1587 | | |
1588 | 0 | int FieldsSize(const google::protobuf::MessageLite& message) const override { |
1589 | 0 | return reflection_.Struct().FieldsSize( |
1590 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1591 | 0 | } |
1592 | | |
1593 | | const google::protobuf::MessageLite* absl_nullable FindField( |
1594 | | const google::protobuf::MessageLite& message, |
1595 | 0 | absl::string_view name) const override { |
1596 | 0 | return reflection_.Struct().FindField( |
1597 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message), name); |
1598 | 0 | } |
1599 | | |
1600 | | JsonMapIterator IterateFields( |
1601 | 0 | const google::protobuf::MessageLite& message) const override { |
1602 | 0 | return reflection_.Struct().BeginFields( |
1603 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(message)); |
1604 | 0 | } |
1605 | | |
1606 | | private: |
1607 | | JsonReflection reflection_; |
1608 | | }; |
1609 | | |
1610 | 0 | std::string JsonStringDebugString(const well_known_types::StringValue& value) { |
1611 | 0 | return absl::visit(absl::Overload( |
1612 | 0 | [&](absl::string_view string) -> std::string { |
1613 | 0 | return FormatStringLiteral(string); |
1614 | 0 | }, |
1615 | 0 | [&](const absl::Cord& cord) -> std::string { |
1616 | 0 | return FormatStringLiteral(cord); |
1617 | 0 | }), |
1618 | 0 | well_known_types::AsVariant(value)); |
1619 | 0 | } |
1620 | | |
1621 | 0 | std::string JsonNumberDebugString(double value) { |
1622 | 0 | if (std::isfinite(value)) { |
1623 | 0 | if (std::floor(value) != value) { |
1624 | | // The double is not representable as a whole number, so use |
1625 | | // absl::StrCat which will add decimal places. |
1626 | 0 | return absl::StrCat(value); |
1627 | 0 | } |
1628 | | // absl::StrCat historically would represent 0.0 as 0, and we want the |
1629 | | // decimal places so ZetaSQL correctly assumes the type as double |
1630 | | // instead of int64. |
1631 | 0 | std::string stringified = absl::StrCat(value); |
1632 | 0 | if (!absl::StrContains(stringified, '.')) { |
1633 | 0 | absl::StrAppend(&stringified, ".0"); |
1634 | 0 | } else { |
1635 | | // absl::StrCat has a decimal now? Use it directly. |
1636 | 0 | } |
1637 | 0 | return stringified; |
1638 | 0 | } |
1639 | 0 | if (std::isnan(value)) { |
1640 | 0 | return "nan"; |
1641 | 0 | } |
1642 | 0 | if (std::signbit(value)) { |
1643 | 0 | return "-infinity"; |
1644 | 0 | } |
1645 | 0 | return "+infinity"; |
1646 | 0 | } |
1647 | | |
1648 | | class JsonDebugStringState final { |
1649 | | public: |
1650 | | JsonDebugStringState(const JsonAccessor* absl_nonnull accessor, |
1651 | | std::string* absl_nonnull output) |
1652 | 0 | : accessor_(accessor), output_(output) {} |
1653 | | |
1654 | 0 | void ValueDebugString(const google::protobuf::MessageLite& message) { |
1655 | 0 | const auto kind_case = accessor_->GetKindCase(message); |
1656 | 0 | switch (kind_case) { |
1657 | 0 | case google::protobuf::Value::KIND_NOT_SET: |
1658 | 0 | ABSL_FALLTHROUGH_INTENDED; |
1659 | 0 | case google::protobuf::Value::kNullValue: |
1660 | 0 | output_->append("null"); |
1661 | 0 | break; |
1662 | 0 | case google::protobuf::Value::kBoolValue: |
1663 | 0 | if (accessor_->GetBoolValue(message)) { |
1664 | 0 | output_->append("true"); |
1665 | 0 | } else { |
1666 | 0 | output_->append("false"); |
1667 | 0 | } |
1668 | 0 | break; |
1669 | 0 | case google::protobuf::Value::kNumberValue: |
1670 | 0 | output_->append( |
1671 | 0 | JsonNumberDebugString(accessor_->GetNumberValue(message))); |
1672 | 0 | break; |
1673 | 0 | case google::protobuf::Value::kStringValue: |
1674 | 0 | output_->append(JsonStringDebugString( |
1675 | 0 | accessor_->GetStringValue(message, scratch_))); |
1676 | 0 | break; |
1677 | 0 | case google::protobuf::Value::kListValue: |
1678 | 0 | ListValueDebugString(accessor_->GetListValue(message)); |
1679 | 0 | break; |
1680 | 0 | case google::protobuf::Value::kStructValue: |
1681 | 0 | StructDebugString(accessor_->GetStructValue(message)); |
1682 | 0 | break; |
1683 | 0 | default: |
1684 | | // Should not get here, but if for some terrible reason |
1685 | | // `google.protobuf.Value` is expanded, just skip. |
1686 | 0 | break; |
1687 | 0 | } |
1688 | 0 | } |
1689 | | |
1690 | 0 | void ListValueDebugString(const google::protobuf::MessageLite& message) { |
1691 | 0 | const int size = accessor_->ValuesSize(message); |
1692 | 0 | output_->push_back('['); |
1693 | 0 | for (int i = 0; i < size; ++i) { |
1694 | 0 | if (i > 0) { |
1695 | 0 | output_->append(", "); |
1696 | 0 | } |
1697 | 0 | ValueDebugString(accessor_->Values(message, i)); |
1698 | 0 | } |
1699 | 0 | output_->push_back(']'); |
1700 | 0 | } |
1701 | | |
1702 | 0 | void StructDebugString(const google::protobuf::MessageLite& message) { |
1703 | 0 | const int size = accessor_->FieldsSize(message); |
1704 | 0 | std::string key_scratch; |
1705 | 0 | well_known_types::StringValue key; |
1706 | 0 | const google::protobuf::MessageLite* absl_nonnull value; |
1707 | 0 | auto iterator = accessor_->IterateFields(message); |
1708 | 0 | output_->push_back('{'); |
1709 | 0 | for (int i = 0; i < size; ++i) { |
1710 | 0 | if (i > 0) { |
1711 | 0 | output_->append(", "); |
1712 | 0 | } |
1713 | 0 | std::tie(key, value) = iterator.Next(key_scratch); |
1714 | 0 | output_->append(JsonStringDebugString(key)); |
1715 | 0 | output_->append(": "); |
1716 | 0 | ValueDebugString(*value); |
1717 | 0 | } |
1718 | 0 | output_->push_back('}'); |
1719 | 0 | } |
1720 | | |
1721 | | private: |
1722 | | const JsonAccessor* absl_nonnull const accessor_; |
1723 | | std::string* absl_nonnull const output_; |
1724 | | std::string scratch_; |
1725 | | }; |
1726 | | |
1727 | | } // namespace |
1728 | | |
1729 | 0 | std::string JsonDebugString(const google::protobuf::Value& message) { |
1730 | 0 | std::string output; |
1731 | 0 | JsonDebugStringState(GeneratedJsonAccessor::Singleton(), &output) |
1732 | 0 | .ValueDebugString(message); |
1733 | 0 | return output; |
1734 | 0 | } |
1735 | | |
1736 | 0 | std::string JsonDebugString(const google::protobuf::Message& message) { |
1737 | 0 | DynamicJsonAccessor accessor; |
1738 | 0 | accessor.InitializeValue(message); |
1739 | 0 | std::string output; |
1740 | 0 | JsonDebugStringState(&accessor, &output).ValueDebugString(message); |
1741 | 0 | return output; |
1742 | 0 | } |
1743 | | |
1744 | 0 | std::string JsonListDebugString(const google::protobuf::ListValue& message) { |
1745 | 0 | std::string output; |
1746 | 0 | JsonDebugStringState(GeneratedJsonAccessor::Singleton(), &output) |
1747 | 0 | .ListValueDebugString(message); |
1748 | 0 | return output; |
1749 | 0 | } |
1750 | | |
1751 | 0 | std::string JsonListDebugString(const google::protobuf::Message& message) { |
1752 | 0 | DynamicJsonAccessor accessor; |
1753 | 0 | accessor.InitializeListValue(message); |
1754 | 0 | std::string output; |
1755 | 0 | JsonDebugStringState(&accessor, &output).ListValueDebugString(message); |
1756 | 0 | return output; |
1757 | 0 | } |
1758 | | |
1759 | 0 | std::string JsonMapDebugString(const google::protobuf::Struct& message) { |
1760 | 0 | std::string output; |
1761 | 0 | JsonDebugStringState(GeneratedJsonAccessor::Singleton(), &output) |
1762 | 0 | .StructDebugString(message); |
1763 | 0 | return output; |
1764 | 0 | } |
1765 | | |
1766 | 0 | std::string JsonMapDebugString(const google::protobuf::Message& message) { |
1767 | 0 | DynamicJsonAccessor accessor; |
1768 | 0 | accessor.InitializeStruct(message); |
1769 | 0 | std::string output; |
1770 | 0 | JsonDebugStringState(&accessor, &output).StructDebugString(message); |
1771 | 0 | return output; |
1772 | 0 | } |
1773 | | |
1774 | | namespace { |
1775 | | |
1776 | | class JsonEqualsState final { |
1777 | | public: |
1778 | | explicit JsonEqualsState(const JsonAccessor* absl_nonnull lhs_accessor, |
1779 | | const JsonAccessor* absl_nonnull rhs_accessor) |
1780 | 0 | : lhs_accessor_(lhs_accessor), rhs_accessor_(rhs_accessor) {} |
1781 | | |
1782 | | bool ValueEqual(const google::protobuf::MessageLite& lhs, |
1783 | 0 | const google::protobuf::MessageLite& rhs) { |
1784 | 0 | auto lhs_kind_case = lhs_accessor_->GetKindCase(lhs); |
1785 | 0 | if (lhs_kind_case == google::protobuf::Value::KIND_NOT_SET) { |
1786 | 0 | lhs_kind_case = google::protobuf::Value::kNullValue; |
1787 | 0 | } |
1788 | 0 | auto rhs_kind_case = rhs_accessor_->GetKindCase(rhs); |
1789 | 0 | if (rhs_kind_case == google::protobuf::Value::KIND_NOT_SET) { |
1790 | 0 | rhs_kind_case = google::protobuf::Value::kNullValue; |
1791 | 0 | } |
1792 | 0 | if (lhs_kind_case != rhs_kind_case) { |
1793 | 0 | return false; |
1794 | 0 | } |
1795 | 0 | switch (lhs_kind_case) { |
1796 | 0 | case google::protobuf::Value::KIND_NOT_SET: |
1797 | 0 | ABSL_UNREACHABLE(); |
1798 | 0 | case google::protobuf::Value::kNullValue: |
1799 | 0 | return true; |
1800 | 0 | case google::protobuf::Value::kBoolValue: |
1801 | 0 | return lhs_accessor_->GetBoolValue(lhs) == |
1802 | 0 | rhs_accessor_->GetBoolValue(rhs); |
1803 | 0 | case google::protobuf::Value::kNumberValue: |
1804 | 0 | return lhs_accessor_->GetNumberValue(lhs) == |
1805 | 0 | rhs_accessor_->GetNumberValue(rhs); |
1806 | 0 | case google::protobuf::Value::kStringValue: |
1807 | 0 | return lhs_accessor_->GetStringValue(lhs, lhs_scratch_) == |
1808 | 0 | rhs_accessor_->GetStringValue(rhs, rhs_scratch_); |
1809 | 0 | case google::protobuf::Value::kListValue: |
1810 | 0 | return ListValueEqual(lhs_accessor_->GetListValue(lhs), |
1811 | 0 | rhs_accessor_->GetListValue(rhs)); |
1812 | 0 | case google::protobuf::Value::kStructValue: |
1813 | 0 | return StructEqual(lhs_accessor_->GetStructValue(lhs), |
1814 | 0 | rhs_accessor_->GetStructValue(rhs)); |
1815 | 0 | default: |
1816 | | // Should not get here, but if for some terrible reason |
1817 | | // `google.protobuf.Value` is expanded, default to false. |
1818 | 0 | return false; |
1819 | 0 | } |
1820 | 0 | } |
1821 | | |
1822 | | bool ListValueEqual(const google::protobuf::MessageLite& lhs, |
1823 | 0 | const google::protobuf::MessageLite& rhs) { |
1824 | 0 | const int lhs_size = lhs_accessor_->ValuesSize(lhs); |
1825 | 0 | const int rhs_size = rhs_accessor_->ValuesSize(rhs); |
1826 | 0 | if (lhs_size != rhs_size) { |
1827 | 0 | return false; |
1828 | 0 | } |
1829 | 0 | for (int i = 0; i < lhs_size; ++i) { |
1830 | 0 | if (!ValueEqual(lhs_accessor_->Values(lhs, i), |
1831 | 0 | rhs_accessor_->Values(rhs, i))) { |
1832 | 0 | return false; |
1833 | 0 | } |
1834 | 0 | } |
1835 | 0 | return true; |
1836 | 0 | } |
1837 | | |
1838 | | bool StructEqual(const google::protobuf::MessageLite& lhs, |
1839 | 0 | const google::protobuf::MessageLite& rhs) { |
1840 | 0 | const int lhs_size = lhs_accessor_->FieldsSize(lhs); |
1841 | 0 | const int rhs_size = rhs_accessor_->FieldsSize(rhs); |
1842 | 0 | if (lhs_size != rhs_size) { |
1843 | 0 | return false; |
1844 | 0 | } |
1845 | 0 | if (lhs_size == 0) { |
1846 | 0 | return true; |
1847 | 0 | } |
1848 | 0 | std::string lhs_key_scratch; |
1849 | 0 | well_known_types::StringValue lhs_key; |
1850 | 0 | const google::protobuf::MessageLite* absl_nonnull lhs_value; |
1851 | 0 | auto lhs_iterator = lhs_accessor_->IterateFields(lhs); |
1852 | 0 | for (int i = 0; i < lhs_size; ++i) { |
1853 | 0 | std::tie(lhs_key, lhs_value) = lhs_iterator.Next(lhs_key_scratch); |
1854 | 0 | if (const auto* rhs_value = rhs_accessor_->FindField( |
1855 | 0 | rhs, absl::visit( |
1856 | 0 | absl::Overload( |
1857 | 0 | [](absl::string_view string) -> absl::string_view { |
1858 | 0 | return string; |
1859 | 0 | }, |
1860 | 0 | [&lhs_key_scratch]( |
1861 | 0 | const absl::Cord& cord) -> absl::string_view { |
1862 | 0 | if (auto flat = cord.TryFlat(); flat) { |
1863 | 0 | return *flat; |
1864 | 0 | } |
1865 | 0 | absl::CopyCordToString(cord, &lhs_key_scratch); |
1866 | 0 | return absl::string_view(lhs_key_scratch); |
1867 | 0 | }), |
1868 | 0 | AsVariant(lhs_key))); |
1869 | 0 | rhs_value == nullptr || !ValueEqual(*lhs_value, *rhs_value)) { |
1870 | 0 | return false; |
1871 | 0 | } |
1872 | 0 | } |
1873 | 0 | return true; |
1874 | 0 | } |
1875 | | |
1876 | | private: |
1877 | | const JsonAccessor* absl_nonnull const lhs_accessor_; |
1878 | | const JsonAccessor* absl_nonnull const rhs_accessor_; |
1879 | | std::string lhs_scratch_; |
1880 | | std::string rhs_scratch_; |
1881 | | }; |
1882 | | |
1883 | | } // namespace |
1884 | | |
1885 | | bool JsonEquals(const google::protobuf::Value& lhs, |
1886 | 0 | const google::protobuf::Value& rhs) { |
1887 | 0 | return JsonEqualsState(GeneratedJsonAccessor::Singleton(), |
1888 | 0 | GeneratedJsonAccessor::Singleton()) |
1889 | 0 | .ValueEqual(lhs, rhs); |
1890 | 0 | } |
1891 | | |
1892 | | bool JsonEquals(const google::protobuf::Value& lhs, |
1893 | 0 | const google::protobuf::Message& rhs) { |
1894 | 0 | DynamicJsonAccessor rhs_accessor; |
1895 | 0 | rhs_accessor.InitializeValue(rhs); |
1896 | 0 | return JsonEqualsState(GeneratedJsonAccessor::Singleton(), &rhs_accessor) |
1897 | 0 | .ValueEqual(lhs, rhs); |
1898 | 0 | } |
1899 | | |
1900 | | bool JsonEquals(const google::protobuf::Message& lhs, |
1901 | 0 | const google::protobuf::Value& rhs) { |
1902 | 0 | DynamicJsonAccessor lhs_accessor; |
1903 | 0 | lhs_accessor.InitializeValue(lhs); |
1904 | 0 | return JsonEqualsState(&lhs_accessor, GeneratedJsonAccessor::Singleton()) |
1905 | 0 | .ValueEqual(lhs, rhs); |
1906 | 0 | } |
1907 | | |
1908 | 0 | bool JsonEquals(const google::protobuf::Message& lhs, const google::protobuf::Message& rhs) { |
1909 | 0 | DynamicJsonAccessor lhs_accessor; |
1910 | 0 | lhs_accessor.InitializeValue(lhs); |
1911 | 0 | DynamicJsonAccessor rhs_accessor; |
1912 | 0 | rhs_accessor.InitializeValue(rhs); |
1913 | 0 | return JsonEqualsState(&lhs_accessor, &rhs_accessor).ValueEqual(lhs, rhs); |
1914 | 0 | } |
1915 | | |
1916 | | bool JsonEquals(const google::protobuf::MessageLite& lhs, |
1917 | 0 | const google::protobuf::MessageLite& rhs) { |
1918 | 0 | const auto* lhs_generated = |
1919 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::Value>(&lhs); |
1920 | 0 | const auto* rhs_generated = |
1921 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::Value>(&rhs); |
1922 | 0 | if (lhs_generated && rhs_generated) { |
1923 | 0 | return JsonEquals(*lhs_generated, *rhs_generated); |
1924 | 0 | } |
1925 | 0 | if (lhs_generated) { |
1926 | 0 | return JsonEquals(*lhs_generated, |
1927 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(rhs)); |
1928 | 0 | } |
1929 | 0 | if (rhs_generated) { |
1930 | 0 | return JsonEquals(google::protobuf::DownCastMessage<google::protobuf::Message>(lhs), |
1931 | 0 | *rhs_generated); |
1932 | 0 | } |
1933 | 0 | return JsonEquals(google::protobuf::DownCastMessage<google::protobuf::Message>(lhs), |
1934 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(rhs)); |
1935 | 0 | } |
1936 | | |
1937 | | bool JsonListEquals(const google::protobuf::ListValue& lhs, |
1938 | 0 | const google::protobuf::ListValue& rhs) { |
1939 | 0 | return JsonEqualsState(GeneratedJsonAccessor::Singleton(), |
1940 | 0 | GeneratedJsonAccessor::Singleton()) |
1941 | 0 | .ListValueEqual(lhs, rhs); |
1942 | 0 | } |
1943 | | |
1944 | | bool JsonListEquals(const google::protobuf::ListValue& lhs, |
1945 | 0 | const google::protobuf::Message& rhs) { |
1946 | 0 | DynamicJsonAccessor rhs_accessor; |
1947 | 0 | rhs_accessor.InitializeListValue(rhs); |
1948 | 0 | return JsonEqualsState(GeneratedJsonAccessor::Singleton(), &rhs_accessor) |
1949 | 0 | .ListValueEqual(lhs, rhs); |
1950 | 0 | } |
1951 | | |
1952 | | bool JsonListEquals(const google::protobuf::Message& lhs, |
1953 | 0 | const google::protobuf::ListValue& rhs) { |
1954 | 0 | DynamicJsonAccessor lhs_accessor; |
1955 | 0 | lhs_accessor.InitializeListValue(lhs); |
1956 | 0 | return JsonEqualsState(&lhs_accessor, GeneratedJsonAccessor::Singleton()) |
1957 | 0 | .ListValueEqual(lhs, rhs); |
1958 | 0 | } |
1959 | | |
1960 | 0 | bool JsonListEquals(const google::protobuf::Message& lhs, const google::protobuf::Message& rhs) { |
1961 | 0 | DynamicJsonAccessor lhs_accessor; |
1962 | 0 | lhs_accessor.InitializeListValue(lhs); |
1963 | 0 | DynamicJsonAccessor rhs_accessor; |
1964 | 0 | rhs_accessor.InitializeListValue(rhs); |
1965 | 0 | return JsonEqualsState(&lhs_accessor, &rhs_accessor).ListValueEqual(lhs, rhs); |
1966 | 0 | } |
1967 | | |
1968 | | bool JsonListEquals(const google::protobuf::MessageLite& lhs, |
1969 | 0 | const google::protobuf::MessageLite& rhs) { |
1970 | 0 | const auto* lhs_generated = |
1971 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::ListValue>(&lhs); |
1972 | 0 | const auto* rhs_generated = |
1973 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::ListValue>(&rhs); |
1974 | 0 | if (lhs_generated && rhs_generated) { |
1975 | 0 | return JsonListEquals(*lhs_generated, *rhs_generated); |
1976 | 0 | } |
1977 | 0 | if (lhs_generated) { |
1978 | 0 | return JsonListEquals(*lhs_generated, |
1979 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(rhs)); |
1980 | 0 | } |
1981 | 0 | if (rhs_generated) { |
1982 | 0 | return JsonListEquals(google::protobuf::DownCastMessage<google::protobuf::Message>(lhs), |
1983 | 0 | *rhs_generated); |
1984 | 0 | } |
1985 | 0 | return JsonListEquals(google::protobuf::DownCastMessage<google::protobuf::Message>(lhs), |
1986 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(rhs)); |
1987 | 0 | } |
1988 | | |
1989 | | bool JsonMapEquals(const google::protobuf::Struct& lhs, |
1990 | 0 | const google::protobuf::Struct& rhs) { |
1991 | 0 | return JsonEqualsState(GeneratedJsonAccessor::Singleton(), |
1992 | 0 | GeneratedJsonAccessor::Singleton()) |
1993 | 0 | .StructEqual(lhs, rhs); |
1994 | 0 | } |
1995 | | |
1996 | | bool JsonMapEquals(const google::protobuf::Struct& lhs, |
1997 | 0 | const google::protobuf::Message& rhs) { |
1998 | 0 | DynamicJsonAccessor rhs_accessor; |
1999 | 0 | rhs_accessor.InitializeStruct(rhs); |
2000 | 0 | return JsonEqualsState(GeneratedJsonAccessor::Singleton(), &rhs_accessor) |
2001 | 0 | .StructEqual(lhs, rhs); |
2002 | 0 | } |
2003 | | |
2004 | | bool JsonMapEquals(const google::protobuf::Message& lhs, |
2005 | 0 | const google::protobuf::Struct& rhs) { |
2006 | 0 | DynamicJsonAccessor lhs_accessor; |
2007 | 0 | lhs_accessor.InitializeStruct(lhs); |
2008 | 0 | return JsonEqualsState(&lhs_accessor, GeneratedJsonAccessor::Singleton()) |
2009 | 0 | .StructEqual(lhs, rhs); |
2010 | 0 | } |
2011 | | |
2012 | 0 | bool JsonMapEquals(const google::protobuf::Message& lhs, const google::protobuf::Message& rhs) { |
2013 | 0 | DynamicJsonAccessor lhs_accessor; |
2014 | 0 | lhs_accessor.InitializeStruct(lhs); |
2015 | 0 | DynamicJsonAccessor rhs_accessor; |
2016 | 0 | rhs_accessor.InitializeStruct(rhs); |
2017 | 0 | return JsonEqualsState(&lhs_accessor, &rhs_accessor).StructEqual(lhs, rhs); |
2018 | 0 | } |
2019 | | |
2020 | | bool JsonMapEquals(const google::protobuf::MessageLite& lhs, |
2021 | 0 | const google::protobuf::MessageLite& rhs) { |
2022 | 0 | const auto* lhs_generated = |
2023 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::Struct>(&lhs); |
2024 | 0 | const auto* rhs_generated = |
2025 | 0 | google::protobuf::DynamicCastMessage<google::protobuf::Struct>(&rhs); |
2026 | 0 | if (lhs_generated && rhs_generated) { |
2027 | 0 | return JsonMapEquals(*lhs_generated, *rhs_generated); |
2028 | 0 | } |
2029 | 0 | if (lhs_generated) { |
2030 | 0 | return JsonMapEquals(*lhs_generated, |
2031 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(rhs)); |
2032 | 0 | } |
2033 | 0 | if (rhs_generated) { |
2034 | 0 | return JsonMapEquals(google::protobuf::DownCastMessage<google::protobuf::Message>(lhs), |
2035 | 0 | *rhs_generated); |
2036 | 0 | } |
2037 | 0 | return JsonMapEquals(google::protobuf::DownCastMessage<google::protobuf::Message>(lhs), |
2038 | 0 | google::protobuf::DownCastMessage<google::protobuf::Message>(rhs)); |
2039 | 0 | } |
2040 | | |
2041 | | } // namespace cel::internal |