Coverage Report

Created: 2026-10-09 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/values/struct_value_builder.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 "common/values/struct_value_builder.h"
16
17
#include <cstdint>
18
#include <limits>
19
#include <memory>
20
#include <optional>
21
#include <string>
22
#include <utility>
23
24
#include "google/protobuf/struct.pb.h"
25
#include "absl/base/nullability.h"
26
#include "absl/base/optimization.h"
27
#include "absl/functional/overload.h"
28
#include "absl/log/absl_check.h"
29
#include "absl/status/status.h"
30
#include "absl/status/statusor.h"
31
#include "absl/strings/cord.h"
32
#include "absl/strings/str_cat.h"
33
#include "absl/strings/string_view.h"
34
#include "absl/types/optional.h"
35
#include "common/allocator.h"
36
#include "common/any.h"
37
#include "common/memory.h"
38
#include "common/value.h"
39
#include "common/value_kind.h"
40
#include "common/values/value_builder.h"
41
#include "extensions/protobuf/internal/map_reflection.h"
42
#include "internal/status_macros.h"
43
#include "internal/well_known_types.h"
44
#include "google/protobuf/arena.h"
45
#include "google/protobuf/descriptor.h"
46
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
47
#include "google/protobuf/message.h"
48
49
// TODO(uncreated-issue/82): Improve test coverage for struct value builder
50
51
// TODO(uncreated-issue/76): improve test coverage for JSON/Any
52
53
namespace cel::common_internal {
54
55
namespace {
56
57
absl::StatusOr<const google::protobuf::Descriptor* absl_nonnull> GetDescriptor(
58
0
    const google::protobuf::Message& message) {
59
0
  const auto* desc = message.GetDescriptor();
60
0
  if (ABSL_PREDICT_FALSE(desc == nullptr)) {
61
0
    return absl::InvalidArgumentError(
62
0
        absl::StrCat(message.GetTypeName(), " is missing descriptor"));
63
0
  }
64
0
  return desc;
65
0
}
66
67
absl::StatusOr<absl::optional<ErrorValue>> ProtoMessageCopyUsingSerialization(
68
0
    google::protobuf::MessageLite* to, const google::protobuf::MessageLite* from) {
69
0
  ABSL_DCHECK_EQ(to->GetTypeName(), from->GetTypeName());
70
0
  absl::Cord serialized;
71
0
  if (!from->SerializePartialToString(&serialized)) {
72
0
    return absl::UnknownError(
73
0
        absl::StrCat("failed to serialize `", from->GetTypeName(), "`"));
74
0
  }
75
0
  if (!to->ParsePartialFromString(serialized)) {
76
0
    return absl::UnknownError(
77
0
        absl::StrCat("failed to parse `", to->GetTypeName(), "`"));
78
0
  }
79
0
  return std::nullopt;
80
0
}
81
82
absl::StatusOr<absl::optional<ErrorValue>> ProtoMessageCopy(
83
    google::protobuf::Message* absl_nonnull to_message,
84
    const google::protobuf::Descriptor* absl_nonnull to_descriptor,
85
    const google::protobuf::Message* absl_nonnull from_message,
86
0
    google::protobuf::Arena* absl_nonnull arena) {
87
0
  CEL_ASSIGN_OR_RETURN(const auto* from_descriptor,
88
0
                       GetDescriptor(*from_message));
89
0
  if (to_descriptor == from_descriptor) {
90
    // Same.
91
0
    to_message->CopyFrom(*from_message);
92
0
    return std::nullopt;
93
0
  }
94
0
  if (to_descriptor->full_name() == from_descriptor->full_name()) {
95
    // Same type, different descriptors.
96
0
    return ProtoMessageCopyUsingSerialization(to_message, from_message);
97
0
  }
98
0
  return TypeConversionError(from_descriptor->full_name(),
99
0
                             to_descriptor->full_name(), arena);
100
0
}
101
102
absl::StatusOr<absl::optional<ErrorValue>> ProtoMessageFromValueImpl(
103
    const Value& value, const google::protobuf::DescriptorPool* absl_nonnull pool,
104
    google::protobuf::MessageFactory* absl_nonnull factory,
105
    well_known_types::Reflection* absl_nonnull well_known_types,
106
0
    google::protobuf::Message* absl_nonnull message, google::protobuf::Arena* absl_nonnull arena) {
107
0
  CEL_ASSIGN_OR_RETURN(const auto* to_desc, GetDescriptor(*message));
108
0
  switch (to_desc->well_known_type()) {
109
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_FLOATVALUE: {
110
0
      if (auto double_value = value.AsDouble(); double_value) {
111
0
        CEL_RETURN_IF_ERROR(well_known_types->FloatValue().Initialize(
112
0
            message->GetDescriptor()));
113
0
        well_known_types->FloatValue().SetValue(
114
0
            message, static_cast<float>(double_value->NativeValue()));
115
0
        return std::nullopt;
116
0
      }
117
0
      return TypeConversionError(value.GetTypeName(), to_desc->full_name(),
118
0
                                 arena);
119
0
    }
120
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_DOUBLEVALUE: {
121
0
      if (auto double_value = value.AsDouble(); double_value) {
122
0
        CEL_RETURN_IF_ERROR(well_known_types->DoubleValue().Initialize(
123
0
            message->GetDescriptor()));
124
0
        well_known_types->DoubleValue().SetValue(message,
125
0
                                                 double_value->NativeValue());
126
0
        return std::nullopt;
127
0
      }
128
0
      return TypeConversionError(value.GetTypeName(), to_desc->full_name(),
129
0
                                 arena);
130
0
    }
131
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_INT32VALUE: {
132
0
      if (auto int_value = value.AsInt(); int_value) {
133
0
        if (int_value->NativeValue() < std::numeric_limits<int32_t>::min() ||
134
0
            int_value->NativeValue() > std::numeric_limits<int32_t>::max()) {
135
0
          return ErrorValue::From(
136
0
              absl::OutOfRangeError("int64 to int32 overflow"), arena);
137
0
        }
138
0
        CEL_RETURN_IF_ERROR(well_known_types->Int32Value().Initialize(
139
0
            message->GetDescriptor()));
140
0
        well_known_types->Int32Value().SetValue(
141
0
            message, static_cast<int32_t>(int_value->NativeValue()));
142
0
        return std::nullopt;
143
0
      }
144
0
      return TypeConversionError(value.GetTypeName(), to_desc->full_name(),
145
0
                                 arena);
146
0
    }
147
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_INT64VALUE: {
148
0
      if (auto int_value = value.AsInt(); int_value) {
149
0
        CEL_RETURN_IF_ERROR(well_known_types->Int64Value().Initialize(
150
0
            message->GetDescriptor()));
151
0
        well_known_types->Int64Value().SetValue(message,
152
0
                                                int_value->NativeValue());
153
0
        return std::nullopt;
154
0
      }
155
0
      return TypeConversionError(value.GetTypeName(), to_desc->full_name(),
156
0
                                 arena);
157
0
    }
158
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_UINT32VALUE: {
159
0
      if (auto uint_value = value.AsUint(); uint_value) {
160
0
        if (uint_value->NativeValue() > std::numeric_limits<uint32_t>::max()) {
161
0
          return ErrorValue::From(
162
0
              absl::OutOfRangeError("uint64 to uint32 overflow"), arena);
163
0
        }
164
0
        CEL_RETURN_IF_ERROR(well_known_types->UInt32Value().Initialize(
165
0
            message->GetDescriptor()));
166
0
        well_known_types->UInt32Value().SetValue(
167
0
            message, static_cast<uint32_t>(uint_value->NativeValue()));
168
0
        return std::nullopt;
169
0
      }
170
0
      return TypeConversionError(value.GetTypeName(), to_desc->full_name(),
171
0
                                 arena);
172
0
    }
173
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_UINT64VALUE: {
174
0
      if (auto uint_value = value.AsUint(); uint_value) {
175
0
        CEL_RETURN_IF_ERROR(well_known_types->UInt64Value().Initialize(
176
0
            message->GetDescriptor()));
177
0
        well_known_types->UInt64Value().SetValue(message,
178
0
                                                 uint_value->NativeValue());
179
0
        return std::nullopt;
180
0
      }
181
0
      return TypeConversionError(value.GetTypeName(), to_desc->full_name(),
182
0
                                 arena);
183
0
    }
184
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_STRINGVALUE: {
185
0
      if (auto string_value = value.AsString(); string_value) {
186
0
        CEL_RETURN_IF_ERROR(well_known_types->StringValue().Initialize(
187
0
            message->GetDescriptor()));
188
0
        well_known_types->StringValue().SetValue(message,
189
0
                                                 string_value->NativeCord());
190
0
        return std::nullopt;
191
0
      }
192
0
      return TypeConversionError(value.GetTypeName(), to_desc->full_name(),
193
0
                                 arena);
194
0
    }
195
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_BYTESVALUE: {
196
0
      if (auto bytes_value = value.AsBytes(); bytes_value) {
197
0
        CEL_RETURN_IF_ERROR(well_known_types->BytesValue().Initialize(
198
0
            message->GetDescriptor()));
199
0
        well_known_types->BytesValue().SetValue(message,
200
0
                                                bytes_value->NativeCord());
201
0
        return std::nullopt;
202
0
      }
203
0
      return TypeConversionError(value.GetTypeName(), to_desc->full_name(),
204
0
                                 arena);
205
0
    }
206
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_BOOLVALUE: {
207
0
      if (auto bool_value = value.AsBool(); bool_value) {
208
0
        CEL_RETURN_IF_ERROR(
209
0
            well_known_types->BoolValue().Initialize(message->GetDescriptor()));
210
0
        well_known_types->BoolValue().SetValue(message,
211
0
                                               bool_value->NativeValue());
212
0
        return std::nullopt;
213
0
      }
214
0
      return TypeConversionError(value.GetTypeName(), to_desc->full_name(),
215
0
                                 arena);
216
0
    }
217
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_ANY: {
218
0
      google::protobuf::io::CordOutputStream serialized;
219
0
      CEL_RETURN_IF_ERROR(value.SerializeTo(pool, factory, &serialized));
220
0
      std::string type_url;
221
0
      switch (value.kind()) {
222
0
        case ValueKind::kNull:
223
0
          type_url = MakeTypeUrl("google.protobuf.Value");
224
0
          break;
225
0
        case ValueKind::kBool:
226
0
          type_url = MakeTypeUrl("google.protobuf.BoolValue");
227
0
          break;
228
0
        case ValueKind::kInt:
229
0
          type_url = MakeTypeUrl("google.protobuf.Int64Value");
230
0
          break;
231
0
        case ValueKind::kUint:
232
0
          type_url = MakeTypeUrl("google.protobuf.UInt64Value");
233
0
          break;
234
0
        case ValueKind::kDouble:
235
0
          type_url = MakeTypeUrl("google.protobuf.DoubleValue");
236
0
          break;
237
0
        case ValueKind::kBytes:
238
0
          type_url = MakeTypeUrl("google.protobuf.BytesValue");
239
0
          break;
240
0
        case ValueKind::kString:
241
0
          type_url = MakeTypeUrl("google.protobuf.StringValue");
242
0
          break;
243
0
        case ValueKind::kList:
244
0
          type_url = MakeTypeUrl("google.protobuf.ListValue");
245
0
          break;
246
0
        case ValueKind::kMap:
247
0
          type_url = MakeTypeUrl("google.protobuf.Struct");
248
0
          break;
249
0
        case ValueKind::kDuration:
250
0
          type_url = MakeTypeUrl("google.protobuf.Duration");
251
0
          break;
252
0
        case ValueKind::kTimestamp:
253
0
          type_url = MakeTypeUrl("google.protobuf.Timestamp");
254
0
          break;
255
0
        default:
256
0
          type_url = MakeTypeUrl(value.GetTypeName());
257
0
          break;
258
0
      }
259
0
      CEL_RETURN_IF_ERROR(
260
0
          well_known_types->Any().Initialize(message->GetDescriptor()));
261
0
      well_known_types->Any().SetTypeUrl(message, type_url);
262
0
      well_known_types->Any().SetValue(message,
263
0
                                       std::move(serialized).Consume());
264
0
      return std::nullopt;
265
0
    }
266
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_DURATION: {
267
0
      if (auto duration_value = value.AsDuration(); duration_value) {
268
0
        CEL_RETURN_IF_ERROR(
269
0
            well_known_types->Duration().Initialize(message->GetDescriptor()));
270
0
        well_known_types->Duration().UnsafeSetFromAbslDuration(
271
0
            message, duration_value->NativeValue());
272
0
        return std::nullopt;
273
0
      }
274
0
      return TypeConversionError(value.GetTypeName(), to_desc->full_name(),
275
0
                                 arena);
276
0
    }
277
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_TIMESTAMP: {
278
0
      if (auto timestamp_value = value.AsTimestamp(); timestamp_value) {
279
0
        CEL_RETURN_IF_ERROR(
280
0
            well_known_types->Timestamp().Initialize(message->GetDescriptor()));
281
0
        well_known_types->Timestamp().UnsafeSetFromAbslTime(
282
0
            message, timestamp_value->NativeValue());
283
0
        return std::nullopt;
284
0
      }
285
0
      return TypeConversionError(value.GetTypeName(), to_desc->full_name(),
286
0
                                 arena);
287
0
    }
288
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE: {
289
0
      CEL_RETURN_IF_ERROR(value.ConvertToJson(pool, factory, message));
290
0
      return std::nullopt;
291
0
    }
292
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_LISTVALUE: {
293
0
      CEL_RETURN_IF_ERROR(value.ConvertToJsonArray(pool, factory, message));
294
0
      return std::nullopt;
295
0
    }
296
0
    case google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT: {
297
0
      CEL_RETURN_IF_ERROR(value.ConvertToJsonObject(pool, factory, message));
298
0
      return std::nullopt;
299
0
    }
300
0
    default:
301
0
      break;
302
0
  }
303
304
  // Not a well known type.
305
306
  // Deal with legacy values.
307
0
  if (auto legacy_value = common_internal::AsLegacyStructValue(value);
308
0
      legacy_value) {
309
0
    const auto* from_message = legacy_value->message_ptr();
310
0
    return ProtoMessageCopy(message, to_desc, from_message, arena);
311
0
  }
312
313
  // Deal with modern values.
314
0
  if (auto parsed_message_value = value.AsParsedMessage();
315
0
      parsed_message_value) {
316
0
    return ProtoMessageCopy(message, to_desc,
317
0
                            cel::to_address(*parsed_message_value), arena);
318
0
  }
319
320
0
  return TypeConversionError(value.GetTypeName(), message->GetTypeName(),
321
0
                             arena);
322
0
}
323
324
// Converts a value to a specific protocol buffer map key.
325
using ProtoMapKeyFromValueConverter =
326
    absl::StatusOr<absl::optional<ErrorValue>> (*)(const Value&,
327
                                                   google::protobuf::MapKey&,
328
                                                   std::string&,
329
                                                   google::protobuf::Arena* absl_nonnull);
330
331
absl::StatusOr<absl::optional<ErrorValue>> ProtoBoolMapKeyFromValueConverter(
332
    const Value& value, google::protobuf::MapKey& key, std::string&,
333
0
    google::protobuf::Arena* absl_nonnull arena) {
334
0
  if (auto bool_value = value.AsBool(); bool_value) {
335
0
    key.SetBoolValue(bool_value->NativeValue());
336
0
    return std::nullopt;
337
0
  }
338
0
  return TypeConversionError(value.GetTypeName(), "bool", arena);
339
0
}
340
341
absl::StatusOr<absl::optional<ErrorValue>> ProtoInt32MapKeyFromValueConverter(
342
    const Value& value, google::protobuf::MapKey& key, std::string&,
343
0
    google::protobuf::Arena* absl_nonnull arena) {
344
0
  if (auto int_value = value.AsInt(); int_value) {
345
0
    if (int_value->NativeValue() < std::numeric_limits<int32_t>::min() ||
346
0
        int_value->NativeValue() > std::numeric_limits<int32_t>::max()) {
347
0
      return ErrorValue::From(absl::OutOfRangeError("int64 to int32 overflow"),
348
0
                              arena);
349
0
    }
350
0
    key.SetInt32Value(static_cast<int32_t>(int_value->NativeValue()));
351
0
    return std::nullopt;
352
0
  }
353
0
  return TypeConversionError(value.GetTypeName(), "int", arena);
354
0
}
355
356
absl::StatusOr<absl::optional<ErrorValue>> ProtoInt64MapKeyFromValueConverter(
357
    const Value& value, google::protobuf::MapKey& key, std::string&,
358
0
    google::protobuf::Arena* absl_nonnull arena) {
359
0
  if (auto int_value = value.AsInt(); int_value) {
360
0
    key.SetInt64Value(int_value->NativeValue());
361
0
    return std::nullopt;
362
0
  }
363
0
  return TypeConversionError(value.GetTypeName(), "int", arena);
364
0
}
365
366
absl::StatusOr<absl::optional<ErrorValue>> ProtoUInt32MapKeyFromValueConverter(
367
    const Value& value, google::protobuf::MapKey& key, std::string&,
368
0
    google::protobuf::Arena* absl_nonnull arena) {
369
0
  if (auto uint_value = value.AsUint(); uint_value) {
370
0
    if (uint_value->NativeValue() > std::numeric_limits<uint32_t>::max()) {
371
0
      return ErrorValue::From(
372
0
          absl::OutOfRangeError("uint64 to uint32 overflow"), arena);
373
0
    }
374
0
    key.SetUInt32Value(static_cast<uint32_t>(uint_value->NativeValue()));
375
0
    return std::nullopt;
376
0
  }
377
0
  return TypeConversionError(value.GetTypeName(), "uint", arena);
378
0
}
379
380
absl::StatusOr<absl::optional<ErrorValue>> ProtoUInt64MapKeyFromValueConverter(
381
    const Value& value, google::protobuf::MapKey& key, std::string&,
382
0
    google::protobuf::Arena* absl_nonnull arena) {
383
0
  if (auto uint_value = value.AsUint(); uint_value) {
384
0
    key.SetUInt64Value(uint_value->NativeValue());
385
0
    return std::nullopt;
386
0
  }
387
0
  return TypeConversionError(value.GetTypeName(), "uint", arena);
388
0
}
389
390
absl::StatusOr<absl::optional<ErrorValue>> ProtoStringMapKeyFromValueConverter(
391
    const Value& value, google::protobuf::MapKey& key, std::string& key_string,
392
0
    google::protobuf::Arena* absl_nonnull arena) {
393
0
  if (auto string_value = value.AsString(); string_value) {
394
    // `google::protobuf::MapKey` does not own the string, which may be stored inline in
395
    // `value` or in `key_string`; `value` must not be moved.
396
0
    key.SetStringValue(string_value->ToStringView(&key_string));
397
0
    return std::nullopt;
398
0
  }
399
0
  return TypeConversionError(value.GetTypeName(), "string", arena);
400
0
}
401
402
// Gets the converter for converting from values to protocol buffer map key.
403
absl::StatusOr<ProtoMapKeyFromValueConverter> GetProtoMapKeyFromValueConverter(
404
0
    google::protobuf::FieldDescriptor::CppType cpp_type) {
405
0
  switch (cpp_type) {
406
0
    case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
407
0
      return ProtoBoolMapKeyFromValueConverter;
408
0
    case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
409
0
      return ProtoInt32MapKeyFromValueConverter;
410
0
    case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
411
0
      return ProtoInt64MapKeyFromValueConverter;
412
0
    case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
413
0
      return ProtoUInt32MapKeyFromValueConverter;
414
0
    case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
415
0
      return ProtoUInt64MapKeyFromValueConverter;
416
0
    case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
417
0
      return ProtoStringMapKeyFromValueConverter;
418
0
    default:
419
0
      return absl::InvalidArgumentError(
420
0
          absl::StrCat("unexpected protocol buffer map key type: ",
421
0
                       google::protobuf::FieldDescriptor::CppTypeName(cpp_type)));
422
0
  }
423
0
}
424
425
// Converts a value to a specific protocol buffer map value.
426
using ProtoMapValueFromValueConverter =
427
    absl::StatusOr<absl::optional<ErrorValue>> (*)(
428
        const Value&, const google::protobuf::FieldDescriptor* absl_nonnull,
429
        const google::protobuf::DescriptorPool* absl_nonnull,
430
        google::protobuf::MessageFactory* absl_nonnull,
431
        well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef&,
432
        google::protobuf::Arena* absl_nonnull);
433
434
absl::StatusOr<absl::optional<ErrorValue>> ProtoBoolMapValueFromValueConverter(
435
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull,
436
    const google::protobuf::DescriptorPool* absl_nonnull,
437
    google::protobuf::MessageFactory* absl_nonnull,
438
    well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef& value_ref,
439
0
    google::protobuf::Arena* absl_nonnull arena) {
440
0
  if (auto bool_value = value.AsBool(); bool_value) {
441
0
    value_ref.SetBoolValue(bool_value->NativeValue());
442
0
    return std::nullopt;
443
0
  }
444
0
  return TypeConversionError(value.GetTypeName(), "bool", arena);
445
0
}
446
447
absl::StatusOr<absl::optional<ErrorValue>> ProtoInt32MapValueFromValueConverter(
448
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull,
449
    const google::protobuf::DescriptorPool* absl_nonnull,
450
    google::protobuf::MessageFactory* absl_nonnull,
451
    well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef& value_ref,
452
0
    google::protobuf::Arena* absl_nonnull arena) {
453
0
  if (auto int_value = value.AsInt(); int_value) {
454
0
    if (int_value->NativeValue() < std::numeric_limits<int32_t>::min() ||
455
0
        int_value->NativeValue() > std::numeric_limits<int32_t>::max()) {
456
0
      return ErrorValue::From(absl::OutOfRangeError("int64 to int32 overflow"),
457
0
                              arena);
458
0
    }
459
0
    value_ref.SetInt32Value(static_cast<int32_t>(int_value->NativeValue()));
460
0
    return std::nullopt;
461
0
  }
462
0
  return TypeConversionError(value.GetTypeName(), "int", arena);
463
0
}
464
465
absl::StatusOr<absl::optional<ErrorValue>> ProtoInt64MapValueFromValueConverter(
466
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull,
467
    const google::protobuf::DescriptorPool* absl_nonnull,
468
    google::protobuf::MessageFactory* absl_nonnull,
469
    well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef& value_ref,
470
0
    google::protobuf::Arena* absl_nonnull arena) {
471
0
  if (auto int_value = value.AsInt(); int_value) {
472
0
    value_ref.SetInt64Value(int_value->NativeValue());
473
0
    return std::nullopt;
474
0
  }
475
0
  return TypeConversionError(value.GetTypeName(), "int", arena);
476
0
}
477
478
absl::StatusOr<absl::optional<ErrorValue>>
479
ProtoUInt32MapValueFromValueConverter(
480
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull,
481
    const google::protobuf::DescriptorPool* absl_nonnull,
482
    google::protobuf::MessageFactory* absl_nonnull,
483
    well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef& value_ref,
484
0
    google::protobuf::Arena* absl_nonnull arena) {
485
0
  if (auto uint_value = value.AsUint(); uint_value) {
486
0
    if (uint_value->NativeValue() > std::numeric_limits<uint32_t>::max()) {
487
0
      return ErrorValue::From(
488
0
          absl::OutOfRangeError("uint64 to uint32 overflow"), arena);
489
0
    }
490
0
    value_ref.SetUInt32Value(static_cast<uint32_t>(uint_value->NativeValue()));
491
0
    return std::nullopt;
492
0
  }
493
0
  return TypeConversionError(value.GetTypeName(), "uint", arena);
494
0
}
495
496
absl::StatusOr<absl::optional<ErrorValue>>
497
ProtoUInt64MapValueFromValueConverter(
498
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull,
499
    const google::protobuf::DescriptorPool* absl_nonnull,
500
    google::protobuf::MessageFactory* absl_nonnull,
501
    well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef& value_ref,
502
0
    google::protobuf::Arena* absl_nonnull arena) {
503
0
  if (auto uint_value = value.AsUint(); uint_value) {
504
0
    value_ref.SetUInt64Value(uint_value->NativeValue());
505
0
    return std::nullopt;
506
0
  }
507
0
  return TypeConversionError(value.GetTypeName(), "uint", arena);
508
0
}
509
510
absl::StatusOr<absl::optional<ErrorValue>> ProtoFloatMapValueFromValueConverter(
511
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull,
512
    const google::protobuf::DescriptorPool* absl_nonnull,
513
    google::protobuf::MessageFactory* absl_nonnull,
514
    well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef& value_ref,
515
0
    google::protobuf::Arena* absl_nonnull arena) {
516
0
  if (auto double_value = value.AsDouble(); double_value) {
517
0
    value_ref.SetFloatValue(double_value->NativeValue());
518
0
    return std::nullopt;
519
0
  }
520
0
  return TypeConversionError(value.GetTypeName(), "double", arena);
521
0
}
522
523
absl::StatusOr<absl::optional<ErrorValue>>
524
ProtoDoubleMapValueFromValueConverter(
525
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull,
526
    const google::protobuf::DescriptorPool* absl_nonnull,
527
    google::protobuf::MessageFactory* absl_nonnull,
528
    well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef& value_ref,
529
0
    google::protobuf::Arena* absl_nonnull arena) {
530
0
  if (auto double_value = value.AsDouble(); double_value) {
531
0
    value_ref.SetDoubleValue(double_value->NativeValue());
532
0
    return std::nullopt;
533
0
  }
534
0
  return TypeConversionError(value.GetTypeName(), "double", arena);
535
0
}
536
537
absl::StatusOr<absl::optional<ErrorValue>> ProtoBytesMapValueFromValueConverter(
538
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull,
539
    const google::protobuf::DescriptorPool* absl_nonnull,
540
    google::protobuf::MessageFactory* absl_nonnull,
541
    well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef& value_ref,
542
0
    google::protobuf::Arena* absl_nonnull arena) {
543
0
  if (auto bytes_value = value.AsBytes(); bytes_value) {
544
0
    value_ref.SetStringValue(bytes_value->NativeString());
545
0
    return std::nullopt;
546
0
  }
547
0
  return TypeConversionError(value.GetTypeName(), "bytes", arena);
548
0
}
549
550
absl::StatusOr<absl::optional<ErrorValue>>
551
ProtoStringMapValueFromValueConverter(
552
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull,
553
    const google::protobuf::DescriptorPool* absl_nonnull,
554
    google::protobuf::MessageFactory* absl_nonnull,
555
    well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef& value_ref,
556
0
    google::protobuf::Arena* absl_nonnull arena) {
557
0
  if (auto string_value = value.AsString(); string_value) {
558
0
    value_ref.SetStringValue(string_value->NativeString());
559
0
    return std::nullopt;
560
0
  }
561
0
  return TypeConversionError(value.GetTypeName(), "string", arena);
562
0
}
563
564
absl::StatusOr<absl::optional<ErrorValue>> ProtoNullMapValueFromValueConverter(
565
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull,
566
    const google::protobuf::DescriptorPool* absl_nonnull,
567
    google::protobuf::MessageFactory* absl_nonnull,
568
    well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef& value_ref,
569
0
    google::protobuf::Arena* absl_nonnull arena) {
570
0
  if (value.IsNull() || value.IsInt()) {
571
0
    value_ref.SetEnumValue(0);
572
0
    return std::nullopt;
573
0
  }
574
0
  return TypeConversionError(value.GetTypeName(), "google.protobuf.NullValue",
575
0
                             arena);
576
0
}
577
578
absl::StatusOr<absl::optional<ErrorValue>> ProtoEnumMapValueFromValueConverter(
579
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull field,
580
    const google::protobuf::DescriptorPool* absl_nonnull,
581
    google::protobuf::MessageFactory* absl_nonnull,
582
    well_known_types::Reflection* absl_nonnull, google::protobuf::MapValueRef& value_ref,
583
0
    google::protobuf::Arena* absl_nonnull arena) {
584
0
  if (auto int_value = value.AsInt(); int_value) {
585
0
    if (int_value->NativeValue() < std::numeric_limits<int32_t>::min() ||
586
0
        int_value->NativeValue() > std::numeric_limits<int32_t>::max()) {
587
0
      return ErrorValue::From(absl::OutOfRangeError("int64 to int32 overflow"),
588
0
                              arena);
589
0
    }
590
0
    value_ref.SetEnumValue(static_cast<int32_t>(int_value->NativeValue()));
591
0
    return std::nullopt;
592
0
  }
593
0
  return TypeConversionError(value.GetTypeName(), "enum", arena);
594
0
}
595
596
absl::StatusOr<absl::optional<ErrorValue>>
597
ProtoMessageMapValueFromValueConverter(
598
    const Value& value, const google::protobuf::FieldDescriptor* absl_nonnull,
599
    const google::protobuf::DescriptorPool* absl_nonnull pool,
600
    google::protobuf::MessageFactory* absl_nonnull factory,
601
    well_known_types::Reflection* absl_nonnull well_known_types,
602
0
    google::protobuf::MapValueRef& value_ref, google::protobuf::Arena* absl_nonnull arena) {
603
0
  return ProtoMessageFromValueImpl(value, pool, factory, well_known_types,
604
0
                                   value_ref.MutableMessageValue(), arena);
605
0
}
606
607
// Gets the converter for converting from values to protocol buffer map value.
608
absl::StatusOr<ProtoMapValueFromValueConverter>
609
GetProtoMapValueFromValueConverter(
610
0
    const google::protobuf::FieldDescriptor* absl_nonnull field) {
611
0
  ABSL_DCHECK(field->is_map());
612
0
  const auto* value_field = field->message_type()->map_value();
613
0
  switch (value_field->cpp_type()) {
614
0
    case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
615
0
      return ProtoBoolMapValueFromValueConverter;
616
0
    case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
617
0
      return ProtoInt32MapValueFromValueConverter;
618
0
    case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
619
0
      return ProtoInt64MapValueFromValueConverter;
620
0
    case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
621
0
      return ProtoUInt32MapValueFromValueConverter;
622
0
    case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
623
0
      return ProtoUInt64MapValueFromValueConverter;
624
0
    case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
625
0
      return ProtoFloatMapValueFromValueConverter;
626
0
    case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
627
0
      return ProtoDoubleMapValueFromValueConverter;
628
0
    case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
629
0
      if (value_field->type() == google::protobuf::FieldDescriptor::TYPE_BYTES) {
630
0
        return ProtoBytesMapValueFromValueConverter;
631
0
      }
632
0
      return ProtoStringMapValueFromValueConverter;
633
0
    case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
634
0
      if (value_field->enum_type()->full_name() ==
635
0
          "google.protobuf.NullValue") {
636
0
        return ProtoNullMapValueFromValueConverter;
637
0
      }
638
0
      return ProtoEnumMapValueFromValueConverter;
639
0
    case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
640
0
      return ProtoMessageMapValueFromValueConverter;
641
0
    default:
642
0
      return absl::InvalidArgumentError(absl::StrCat(
643
0
          "unexpected protocol buffer map value type: ",
644
0
          google::protobuf::FieldDescriptor::CppTypeName(value_field->cpp_type())));
645
0
  }
646
0
}
647
648
using ProtoRepeatedFieldFromValueMutator =
649
    absl::StatusOr<absl::optional<ErrorValue>> (*)(
650
        const google::protobuf::DescriptorPool* absl_nonnull,
651
        google::protobuf::MessageFactory* absl_nonnull,
652
        well_known_types::Reflection* absl_nonnull,
653
        const google::protobuf::Reflection* absl_nonnull, google::protobuf::Message* absl_nonnull,
654
        const google::protobuf::FieldDescriptor* absl_nonnull, const Value&,
655
        google::protobuf::Arena* absl_nonnull);
656
657
absl::StatusOr<absl::optional<ErrorValue>>
658
ProtoBoolRepeatedFieldFromValueMutator(
659
    const google::protobuf::DescriptorPool* absl_nonnull,
660
    google::protobuf::MessageFactory* absl_nonnull,
661
    well_known_types::Reflection* absl_nonnull,
662
    const google::protobuf::Reflection* absl_nonnull reflection,
663
    google::protobuf::Message* absl_nonnull message,
664
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
665
0
    google::protobuf::Arena* absl_nonnull arena) {
666
0
  if (auto bool_value = value.AsBool(); bool_value) {
667
0
    reflection->AddBool(message, field, bool_value->NativeValue());
668
0
    return std::nullopt;
669
0
  }
670
0
  return TypeConversionError(value.GetTypeName(), "bool", arena);
671
0
}
672
673
absl::StatusOr<absl::optional<ErrorValue>>
674
ProtoInt32RepeatedFieldFromValueMutator(
675
    const google::protobuf::DescriptorPool* absl_nonnull,
676
    google::protobuf::MessageFactory* absl_nonnull,
677
    well_known_types::Reflection* absl_nonnull,
678
    const google::protobuf::Reflection* absl_nonnull reflection,
679
    google::protobuf::Message* absl_nonnull message,
680
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
681
0
    google::protobuf::Arena* absl_nonnull arena) {
682
0
  if (auto int_value = value.AsInt(); int_value) {
683
0
    if (int_value->NativeValue() < std::numeric_limits<int32_t>::min() ||
684
0
        int_value->NativeValue() > std::numeric_limits<int32_t>::max()) {
685
0
      return ErrorValue::From(absl::OutOfRangeError("int64 to int32 overflow"),
686
0
                              arena);
687
0
    }
688
0
    reflection->AddInt32(message, field,
689
0
                         static_cast<int32_t>(int_value->NativeValue()));
690
0
    return std::nullopt;
691
0
  }
692
0
  return TypeConversionError(value.GetTypeName(), "int", arena);
693
0
}
694
695
absl::StatusOr<absl::optional<ErrorValue>>
696
ProtoInt64RepeatedFieldFromValueMutator(
697
    const google::protobuf::DescriptorPool* absl_nonnull,
698
    google::protobuf::MessageFactory* absl_nonnull,
699
    well_known_types::Reflection* absl_nonnull,
700
    const google::protobuf::Reflection* absl_nonnull reflection,
701
    google::protobuf::Message* absl_nonnull message,
702
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
703
0
    google::protobuf::Arena* absl_nonnull arena) {
704
0
  if (auto int_value = value.AsInt(); int_value) {
705
0
    reflection->AddInt64(message, field, int_value->NativeValue());
706
0
    return std::nullopt;
707
0
  }
708
0
  return TypeConversionError(value.GetTypeName(), "int", arena);
709
0
}
710
711
absl::StatusOr<absl::optional<ErrorValue>>
712
ProtoUInt32RepeatedFieldFromValueMutator(
713
    const google::protobuf::DescriptorPool* absl_nonnull,
714
    google::protobuf::MessageFactory* absl_nonnull,
715
    well_known_types::Reflection* absl_nonnull,
716
    const google::protobuf::Reflection* absl_nonnull reflection,
717
    google::protobuf::Message* absl_nonnull message,
718
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
719
0
    google::protobuf::Arena* absl_nonnull arena) {
720
0
  if (auto uint_value = value.AsUint(); uint_value) {
721
0
    if (uint_value->NativeValue() > std::numeric_limits<uint32_t>::max()) {
722
0
      return ErrorValue::From(
723
0
          absl::OutOfRangeError("uint64 to uint32 overflow"), arena);
724
0
    }
725
0
    reflection->AddUInt32(message, field,
726
0
                          static_cast<uint32_t>(uint_value->NativeValue()));
727
0
    return std::nullopt;
728
0
  }
729
0
  return TypeConversionError(value.GetTypeName(), "uint", arena);
730
0
}
731
732
absl::StatusOr<absl::optional<ErrorValue>>
733
ProtoUInt64RepeatedFieldFromValueMutator(
734
    const google::protobuf::DescriptorPool* absl_nonnull,
735
    google::protobuf::MessageFactory* absl_nonnull,
736
    well_known_types::Reflection* absl_nonnull,
737
    const google::protobuf::Reflection* absl_nonnull reflection,
738
    google::protobuf::Message* absl_nonnull message,
739
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
740
0
    google::protobuf::Arena* absl_nonnull arena) {
741
0
  if (auto uint_value = value.AsUint(); uint_value) {
742
0
    reflection->AddUInt64(message, field, uint_value->NativeValue());
743
0
    return std::nullopt;
744
0
  }
745
0
  return TypeConversionError(value.GetTypeName(), "uint", arena);
746
0
}
747
748
absl::StatusOr<absl::optional<ErrorValue>>
749
ProtoFloatRepeatedFieldFromValueMutator(
750
    const google::protobuf::DescriptorPool* absl_nonnull,
751
    google::protobuf::MessageFactory* absl_nonnull,
752
    well_known_types::Reflection* absl_nonnull,
753
    const google::protobuf::Reflection* absl_nonnull reflection,
754
    google::protobuf::Message* absl_nonnull message,
755
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
756
0
    google::protobuf::Arena* absl_nonnull arena) {
757
0
  if (auto double_value = value.AsDouble(); double_value) {
758
0
    reflection->AddFloat(message, field,
759
0
                         static_cast<float>(double_value->NativeValue()));
760
0
    return std::nullopt;
761
0
  }
762
0
  return TypeConversionError(value.GetTypeName(), "double", arena);
763
0
}
764
765
absl::StatusOr<absl::optional<ErrorValue>>
766
ProtoDoubleRepeatedFieldFromValueMutator(
767
    const google::protobuf::DescriptorPool* absl_nonnull,
768
    google::protobuf::MessageFactory* absl_nonnull,
769
    well_known_types::Reflection* absl_nonnull,
770
    const google::protobuf::Reflection* absl_nonnull reflection,
771
    google::protobuf::Message* absl_nonnull message,
772
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
773
0
    google::protobuf::Arena* absl_nonnull arena) {
774
0
  if (auto double_value = value.AsDouble(); double_value) {
775
0
    reflection->AddDouble(message, field, double_value->NativeValue());
776
0
    return std::nullopt;
777
0
  }
778
0
  return TypeConversionError(value.GetTypeName(), "double", arena);
779
0
}
780
781
absl::StatusOr<absl::optional<ErrorValue>>
782
ProtoBytesRepeatedFieldFromValueMutator(
783
    const google::protobuf::DescriptorPool* absl_nonnull,
784
    google::protobuf::MessageFactory* absl_nonnull,
785
    well_known_types::Reflection* absl_nonnull,
786
    const google::protobuf::Reflection* absl_nonnull reflection,
787
    google::protobuf::Message* absl_nonnull message,
788
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
789
0
    google::protobuf::Arena* absl_nonnull arena) {
790
0
  if (auto bytes_value = value.AsBytes(); bytes_value) {
791
0
    reflection->AddString(message, field, bytes_value->NativeString());
792
0
    return std::nullopt;
793
0
  }
794
0
  return TypeConversionError(value.GetTypeName(), "bytes", arena);
795
0
}
796
797
absl::StatusOr<absl::optional<ErrorValue>>
798
ProtoStringRepeatedFieldFromValueMutator(
799
    const google::protobuf::DescriptorPool* absl_nonnull,
800
    google::protobuf::MessageFactory* absl_nonnull,
801
    well_known_types::Reflection* absl_nonnull,
802
    const google::protobuf::Reflection* absl_nonnull reflection,
803
    google::protobuf::Message* absl_nonnull message,
804
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
805
0
    google::protobuf::Arena* absl_nonnull arena) {
806
0
  if (auto string_value = value.AsString(); string_value) {
807
0
    reflection->AddString(message, field, string_value->NativeString());
808
0
    return std::nullopt;
809
0
  }
810
0
  return TypeConversionError(value.GetTypeName(), "string", arena);
811
0
}
812
813
absl::StatusOr<absl::optional<ErrorValue>>
814
ProtoNullRepeatedFieldFromValueMutator(
815
    const google::protobuf::DescriptorPool* absl_nonnull,
816
    google::protobuf::MessageFactory* absl_nonnull,
817
    well_known_types::Reflection* absl_nonnull,
818
    const google::protobuf::Reflection* absl_nonnull reflection,
819
    google::protobuf::Message* absl_nonnull message,
820
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
821
0
    google::protobuf::Arena* absl_nonnull arena) {
822
0
  if (value.IsNull() || value.IsInt()) {
823
0
    reflection->AddEnumValue(message, field, 0);
824
0
    return std::nullopt;
825
0
  }
826
0
  return TypeConversionError(value.GetTypeName(), "null_type", arena);
827
0
}
828
829
absl::StatusOr<absl::optional<ErrorValue>>
830
ProtoEnumRepeatedFieldFromValueMutator(
831
    const google::protobuf::DescriptorPool* absl_nonnull,
832
    google::protobuf::MessageFactory* absl_nonnull,
833
    well_known_types::Reflection* absl_nonnull,
834
    const google::protobuf::Reflection* absl_nonnull reflection,
835
    google::protobuf::Message* absl_nonnull message,
836
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
837
0
    google::protobuf::Arena* absl_nonnull arena) {
838
0
  const auto* enum_descriptor = field->enum_type();
839
0
  if (auto int_value = value.AsInt(); int_value) {
840
0
    if (int_value->NativeValue() < std::numeric_limits<int>::min() ||
841
0
        int_value->NativeValue() > std::numeric_limits<int>::max()) {
842
0
      return TypeConversionError(value.GetTypeName(),
843
0
                                 enum_descriptor->full_name(), arena);
844
0
    }
845
0
    reflection->AddEnumValue(message, field,
846
0
                             static_cast<int>(int_value->NativeValue()));
847
0
    return std::nullopt;
848
0
  }
849
0
  return TypeConversionError(value.GetTypeName(), enum_descriptor->full_name(),
850
0
                             arena);
851
0
}
852
853
absl::StatusOr<absl::optional<ErrorValue>>
854
ProtoMessageRepeatedFieldFromValueMutator(
855
    const google::protobuf::DescriptorPool* absl_nonnull pool,
856
    google::protobuf::MessageFactory* absl_nonnull factory,
857
    well_known_types::Reflection* absl_nonnull well_known_types,
858
    const google::protobuf::Reflection* absl_nonnull reflection,
859
    google::protobuf::Message* absl_nonnull message,
860
    const google::protobuf::FieldDescriptor* absl_nonnull field, const Value& value,
861
0
    google::protobuf::Arena* absl_nonnull arena) {
862
  // If the value is null and the target repeated field is anything except
863
  // google.protobuf.{Any,ListValue,Struct,Value}, it should be pruned.
864
0
  if (value.IsNull()) {
865
0
    const auto well_known_type = field->message_type()->well_known_type();
866
0
    if (well_known_type != google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE &&
867
0
        well_known_type != google::protobuf::Descriptor::WELLKNOWNTYPE_LISTVALUE &&
868
0
        well_known_type != google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT &&
869
0
        well_known_type != google::protobuf::Descriptor::WELLKNOWNTYPE_ANY) {
870
0
      return std::nullopt;
871
0
    }
872
0
  }
873
0
  auto* element = reflection->AddMessage(message, field, factory);
874
0
  auto result = ProtoMessageFromValueImpl(value, pool, factory,
875
0
                                          well_known_types, element, arena);
876
0
  if (!result.ok() || result->has_value()) {
877
0
    reflection->RemoveLast(message, field);
878
0
  }
879
0
  return result;
880
0
}
881
882
absl::StatusOr<ProtoRepeatedFieldFromValueMutator>
883
GetProtoRepeatedFieldFromValueMutator(
884
0
    const google::protobuf::FieldDescriptor* absl_nonnull field) {
885
0
  ABSL_DCHECK(!field->is_map());
886
0
  ABSL_DCHECK(field->is_repeated());
887
0
  switch (field->cpp_type()) {
888
0
    case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
889
0
      return ProtoBoolRepeatedFieldFromValueMutator;
890
0
    case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
891
0
      return ProtoInt32RepeatedFieldFromValueMutator;
892
0
    case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
893
0
      return ProtoInt64RepeatedFieldFromValueMutator;
894
0
    case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
895
0
      return ProtoUInt32RepeatedFieldFromValueMutator;
896
0
    case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
897
0
      return ProtoUInt64RepeatedFieldFromValueMutator;
898
0
    case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
899
0
      return ProtoFloatRepeatedFieldFromValueMutator;
900
0
    case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
901
0
      return ProtoDoubleRepeatedFieldFromValueMutator;
902
0
    case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
903
0
      if (field->type() == google::protobuf::FieldDescriptor::TYPE_BYTES) {
904
0
        return ProtoBytesRepeatedFieldFromValueMutator;
905
0
      }
906
0
      return ProtoStringRepeatedFieldFromValueMutator;
907
0
    case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
908
0
      if (field->enum_type()->full_name() == "google.protobuf.NullValue") {
909
0
        return ProtoNullRepeatedFieldFromValueMutator;
910
0
      }
911
0
      return ProtoEnumRepeatedFieldFromValueMutator;
912
0
    case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
913
0
      return ProtoMessageRepeatedFieldFromValueMutator;
914
0
    default:
915
0
      return absl::InvalidArgumentError(absl::StrCat(
916
0
          "unexpected protocol buffer repeated field type: ",
917
0
          google::protobuf::FieldDescriptor::CppTypeName(field->cpp_type())));
918
0
  }
919
0
}
920
921
class MessageValueBuilderImpl {
922
 public:
923
  MessageValueBuilderImpl(
924
      google::protobuf::Arena* absl_nullable arena,
925
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
926
      google::protobuf::MessageFactory* absl_nonnull message_factory,
927
      google::protobuf::Message* absl_nonnull message)
928
950k
      : arena_(arena),
929
950k
        descriptor_pool_(descriptor_pool),
930
950k
        message_factory_(message_factory),
931
950k
        message_(message),
932
950k
        descriptor_(message_->GetDescriptor()),
933
950k
        reflection_(message_->GetReflection()) {}
934
935
950k
  ~MessageValueBuilderImpl() {
936
950k
    if (arena_ == nullptr && message_ != nullptr) {
937
0
      delete message_;
938
0
    }
939
950k
  }
940
941
  absl::StatusOr<absl::optional<ErrorValue>> SetFieldByName(
942
431k
      absl::string_view name, Value value) {
943
431k
    const auto* field = descriptor_->FindFieldByName(name);
944
431k
    if (field == nullptr) {
945
0
      field = descriptor_pool_->FindExtensionByPrintableName(descriptor_, name);
946
0
      if (field == nullptr) {
947
0
        return NoSuchFieldError(name, arena_);
948
0
      }
949
0
    }
950
431k
    return SetField(field, std::move(value));
951
431k
  }
952
953
  absl::StatusOr<absl::optional<ErrorValue>> SetFieldByNumber(int64_t number,
954
0
                                                              Value value) {
955
0
    if (number < std::numeric_limits<int32_t>::min() ||
956
0
        number > std::numeric_limits<int32_t>::max()) {
957
0
      return NoSuchFieldError(absl::StrCat(number), arena_);
958
0
    }
959
0
    const auto* field =
960
0
        descriptor_->FindFieldByNumber(static_cast<int>(number));
961
0
    if (field == nullptr) {
962
0
      return NoSuchFieldError(absl::StrCat(number), arena_);
963
0
    }
964
0
    return SetField(field, std::move(value));
965
0
  }
966
967
920k
  absl::StatusOr<Value> Build() && {
968
920k
    return Value::WrapMessage(std::exchange(message_, nullptr),
969
920k
                              descriptor_pool_, message_factory_, arena_);
970
920k
  }
971
972
0
  absl::StatusOr<StructValue> BuildStruct() && {
973
0
    return ParsedMessageValue(std::exchange(message_, nullptr), arena_);
974
0
  }
975
976
 private:
977
  absl::StatusOr<absl::optional<ErrorValue>> SetMapField(
978
0
      const google::protobuf::FieldDescriptor* absl_nonnull field, Value value) {
979
0
    auto map_value = value.AsMap();
980
0
    if (!map_value) {
981
0
      return TypeConversionError(value.GetTypeName(), "map", arena_);
982
0
    }
983
0
    CEL_ASSIGN_OR_RETURN(auto key_converter,
984
0
                         GetProtoMapKeyFromValueConverter(
985
0
                             field->message_type()->map_key()->cpp_type()));
986
0
    CEL_ASSIGN_OR_RETURN(auto value_converter,
987
0
                         GetProtoMapValueFromValueConverter(field));
988
0
    reflection_->ClearField(message_, field);
989
0
    const auto* map_value_field = field->message_type()->map_value();
990
0
    absl::optional<ErrorValue> error_value;
991
    // Don't replace this pattern with a status macro; nested macro invocations
992
    // have the same __LINE__ on MSVC, causing CEL_ASSIGN_OR_RETURN invocations
993
    // to conflict with each-other.
994
0
    auto status = map_value->ForEach(
995
0
        [this, field, key_converter, map_value_field, value_converter,
996
0
         &error_value](const Value& entry_key,
997
0
                       const Value& entry_value) -> absl::StatusOr<bool> {
998
0
          std::string proto_key_string;
999
0
          google::protobuf::MapKey proto_key;
1000
0
          CEL_ASSIGN_OR_RETURN(
1001
0
              error_value,
1002
0
              (*key_converter)(entry_key, proto_key, proto_key_string, arena_));
1003
0
          if (error_value) {
1004
0
            return false;
1005
0
          }
1006
0
          if (map_value_field->cpp_type() ==
1007
0
                  google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE &&
1008
0
              entry_value.IsNull()) {
1009
0
            auto well_known_type =
1010
0
                map_value_field->message_type()->well_known_type();
1011
0
            if (well_known_type != google::protobuf::Descriptor::WELLKNOWNTYPE_ANY &&
1012
0
                well_known_type != google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE &&
1013
0
                well_known_type !=
1014
0
                    google::protobuf::Descriptor::WELLKNOWNTYPE_LISTVALUE &&
1015
0
                well_known_type != google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT) {
1016
0
              return true;
1017
0
            }
1018
0
          }
1019
0
          google::protobuf::MapValueRef proto_value;
1020
0
          extensions::protobuf_internal::InsertOrLookupMapValue(
1021
0
              *reflection_, message_, *field, proto_key, &proto_value);
1022
0
          CEL_ASSIGN_OR_RETURN(
1023
0
              error_value,
1024
0
              (*value_converter)(entry_value, map_value_field, descriptor_pool_,
1025
0
                                 message_factory_, &well_known_types_,
1026
0
                                 proto_value, arena_));
1027
0
          if (error_value) {
1028
0
            return false;
1029
0
          }
1030
0
          return true;
1031
0
        },
1032
0
        descriptor_pool_, message_factory_, arena_);
1033
0
    if (!status.ok()) {
1034
0
      return status;
1035
0
    }
1036
0
    return error_value;
1037
0
  }
1038
1039
  absl::StatusOr<absl::optional<ErrorValue>> SetRepeatedField(
1040
0
      const google::protobuf::FieldDescriptor* absl_nonnull field, Value value) {
1041
0
    auto list_value = value.AsList();
1042
0
    if (!list_value) {
1043
0
      return TypeConversionError(value.GetTypeName(), "list", arena_)
1044
0
          .NativeValue();
1045
0
    }
1046
0
    CEL_ASSIGN_OR_RETURN(auto accessor,
1047
0
                         GetProtoRepeatedFieldFromValueMutator(field));
1048
0
    reflection_->ClearField(message_, field);
1049
0
    absl::optional<ErrorValue> error_value;
1050
0
    CEL_RETURN_IF_ERROR(list_value->ForEach(
1051
0
        [this, field, accessor,
1052
0
         &error_value](const Value& element) -> absl::StatusOr<bool> {
1053
0
          if (field->message_type() != nullptr && element.IsNull()) {
1054
0
            auto well_known_type = field->message_type()->well_known_type();
1055
0
            if (well_known_type != google::protobuf::Descriptor::WELLKNOWNTYPE_ANY &&
1056
0
                well_known_type != google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE &&
1057
0
                well_known_type !=
1058
0
                    google::protobuf::Descriptor::WELLKNOWNTYPE_LISTVALUE &&
1059
0
                well_known_type != google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT) {
1060
0
              return true;
1061
0
            }
1062
0
          }
1063
0
          CEL_ASSIGN_OR_RETURN(error_value,
1064
0
                               (*accessor)(descriptor_pool_, message_factory_,
1065
0
                                           &well_known_types_, reflection_,
1066
0
                                           message_, field, element, arena_));
1067
0
          return !error_value;
1068
0
        },
1069
0
        descriptor_pool_, message_factory_, arena_));
1070
0
    return error_value;
1071
0
  }
1072
1073
  absl::StatusOr<absl::optional<ErrorValue>> SetSingularField(
1074
431k
      const google::protobuf::FieldDescriptor* absl_nonnull field, Value value) {
1075
431k
    switch (field->cpp_type()) {
1076
24.2k
      case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
1077
24.2k
        if (auto bool_value = value.AsBool(); bool_value) {
1078
179
          reflection_->SetBool(message_, field, bool_value->NativeValue());
1079
179
          return std::nullopt;
1080
179
        }
1081
24.0k
        return TypeConversionError(value.GetTypeName(), "bool", arena_);
1082
24.2k
      }
1083
0
      case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
1084
0
        if (auto int_value = value.AsInt(); int_value) {
1085
0
          if (int_value->NativeValue() < std::numeric_limits<int32_t>::min() ||
1086
0
              int_value->NativeValue() > std::numeric_limits<int32_t>::max()) {
1087
0
            return ErrorValue::From(
1088
0
                absl::OutOfRangeError("int64 to int32 overflow"), arena_);
1089
0
          }
1090
0
          reflection_->SetInt32(message_, field,
1091
0
                                static_cast<int32_t>(int_value->NativeValue()));
1092
0
          return std::nullopt;
1093
0
        }
1094
0
        return TypeConversionError(value.GetTypeName(), "int", arena_);
1095
0
      }
1096
0
      case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
1097
0
        if (auto int_value = value.AsInt(); int_value) {
1098
0
          reflection_->SetInt64(message_, field, int_value->NativeValue());
1099
0
          return std::nullopt;
1100
0
        }
1101
0
        return TypeConversionError(value.GetTypeName(), "int", arena_);
1102
0
      }
1103
0
      case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
1104
0
        if (auto uint_value = value.AsUint(); uint_value) {
1105
0
          if (uint_value->NativeValue() >
1106
0
              std::numeric_limits<uint32_t>::max()) {
1107
0
            return ErrorValue::From(
1108
0
                absl::OutOfRangeError("uint64 to uint32 overflow"), arena_);
1109
0
          }
1110
0
          reflection_->SetUInt32(
1111
0
              message_, field,
1112
0
              static_cast<uint32_t>(uint_value->NativeValue()));
1113
0
          return std::nullopt;
1114
0
        }
1115
0
        return TypeConversionError(value.GetTypeName(), "uint", arena_);
1116
0
      }
1117
0
      case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
1118
0
        if (auto uint_value = value.AsUint(); uint_value) {
1119
0
          reflection_->SetUInt64(message_, field, uint_value->NativeValue());
1120
0
          return std::nullopt;
1121
0
        }
1122
0
        return TypeConversionError(value.GetTypeName(), "uint", arena_);
1123
0
      }
1124
0
      case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
1125
0
        if (auto double_value = value.AsDouble(); double_value) {
1126
0
          reflection_->SetFloat(message_, field, double_value->NativeValue());
1127
0
          return std::nullopt;
1128
0
        }
1129
0
        return TypeConversionError(value.GetTypeName(), "double", arena_);
1130
0
      }
1131
1
      case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
1132
1
        if (auto double_value = value.AsDouble(); double_value) {
1133
0
          reflection_->SetDouble(message_, field, double_value->NativeValue());
1134
0
          return std::nullopt;
1135
0
        }
1136
1
        return TypeConversionError(value.GetTypeName(), "double", arena_);
1137
1
      }
1138
0
      case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
1139
0
        if (field->type() == google::protobuf::FieldDescriptor::TYPE_BYTES) {
1140
0
          if (auto bytes_value = value.AsBytes(); bytes_value) {
1141
0
            bytes_value->NativeValue(absl::Overload(
1142
0
                [this, field](absl::string_view string) {
1143
0
                  reflection_->SetString(message_, field, std::string(string));
1144
0
                },
1145
0
                [this, field](const absl::Cord& cord) {
1146
0
                  reflection_->SetString(message_, field, cord);
1147
0
                }));
1148
0
            return std::nullopt;
1149
0
          }
1150
0
          return TypeConversionError(value.GetTypeName(), "bytes", arena_);
1151
0
        }
1152
0
        if (auto string_value = value.AsString(); string_value) {
1153
0
          string_value->NativeValue(absl::Overload(
1154
0
              [this, field](absl::string_view string) {
1155
0
                reflection_->SetString(message_, field, std::string(string));
1156
0
              },
1157
0
              [this, field](const absl::Cord& cord) {
1158
0
                reflection_->SetString(message_, field, cord);
1159
0
              }));
1160
0
          return std::nullopt;
1161
0
        }
1162
0
        return TypeConversionError(value.GetTypeName(), "string", arena_);
1163
0
      }
1164
5.78k
      case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
1165
5.78k
        if (field->enum_type()->full_name() == "google.protobuf.NullValue") {
1166
5.78k
          if (value.IsNull() || value.IsInt()) {
1167
304
            reflection_->SetEnumValue(message_, field, 0);
1168
304
            return std::nullopt;
1169
304
          }
1170
5.48k
          return TypeConversionError(value.GetTypeName(), "null_type", arena_);
1171
5.78k
        }
1172
0
        if (auto int_value = value.AsInt(); int_value) {
1173
0
          if (int_value->NativeValue() >= std::numeric_limits<int32_t>::min() &&
1174
0
              int_value->NativeValue() <= std::numeric_limits<int32_t>::max()) {
1175
0
            reflection_->SetEnumValue(
1176
0
                message_, field, static_cast<int>(int_value->NativeValue()));
1177
0
            return std::nullopt;
1178
0
          }
1179
0
        }
1180
0
        return TypeConversionError(value.GetTypeName(),
1181
0
                                   field->enum_type()->full_name(), arena_);
1182
0
      }
1183
401k
      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
1184
401k
        switch (field->message_type()->well_known_type()) {
1185
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_BOOLVALUE: {
1186
0
            if (value.IsNull()) {
1187
              // Allowing assigning `null` to message fields.
1188
0
              return std::nullopt;
1189
0
            }
1190
0
            if (auto bool_value = value.AsBool(); bool_value) {
1191
0
              CEL_RETURN_IF_ERROR(well_known_types_.BoolValue().Initialize(
1192
0
                  field->message_type()));
1193
0
              well_known_types_.BoolValue().SetValue(
1194
0
                  reflection_->MutableMessage(message_, field,
1195
0
                                              message_factory_),
1196
0
                  bool_value->NativeValue());
1197
0
              return std::nullopt;
1198
0
            }
1199
0
            return TypeConversionError(value.GetTypeName(),
1200
0
                                       field->message_type()->full_name(),
1201
0
                                       arena_);
1202
0
          }
1203
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_INT32VALUE: {
1204
0
            if (value.IsNull()) {
1205
              // Allowing assigning `null` to message fields.
1206
0
              return std::nullopt;
1207
0
            }
1208
0
            if (auto int_value = value.AsInt(); int_value) {
1209
0
              if (int_value->NativeValue() <
1210
0
                      std::numeric_limits<int32_t>::min() ||
1211
0
                  int_value->NativeValue() >
1212
0
                      std::numeric_limits<int32_t>::max()) {
1213
0
                return absl::OutOfRangeError("int64 to int32 overflow");
1214
0
              }
1215
0
              CEL_RETURN_IF_ERROR(well_known_types_.Int32Value().Initialize(
1216
0
                  field->message_type()));
1217
0
              well_known_types_.Int32Value().SetValue(
1218
0
                  reflection_->MutableMessage(message_, field,
1219
0
                                              message_factory_),
1220
0
                  static_cast<int32_t>(int_value->NativeValue()));
1221
0
              return std::nullopt;
1222
0
            }
1223
0
            return TypeConversionError(value.GetTypeName(),
1224
0
                                       field->message_type()->full_name(),
1225
0
                                       arena_);
1226
0
          }
1227
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_INT64VALUE: {
1228
0
            if (value.IsNull()) {
1229
              // Allowing assigning `null` to message fields.
1230
0
              return std::nullopt;
1231
0
            }
1232
0
            if (auto int_value = value.AsInt(); int_value) {
1233
0
              CEL_RETURN_IF_ERROR(well_known_types_.Int64Value().Initialize(
1234
0
                  field->message_type()));
1235
0
              well_known_types_.Int64Value().SetValue(
1236
0
                  reflection_->MutableMessage(message_, field,
1237
0
                                              message_factory_),
1238
0
                  int_value->NativeValue());
1239
0
              return std::nullopt;
1240
0
            }
1241
0
            return TypeConversionError(value.GetTypeName(),
1242
0
                                       field->message_type()->full_name(),
1243
0
                                       arena_);
1244
0
          }
1245
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_UINT32VALUE: {
1246
0
            if (value.IsNull()) {
1247
              // Allowing assigning `null` to message fields.
1248
0
              return std::nullopt;
1249
0
            }
1250
0
            if (auto uint_value = value.AsUint(); uint_value) {
1251
0
              if (uint_value->NativeValue() >
1252
0
                  std::numeric_limits<uint32_t>::max()) {
1253
0
                return absl::OutOfRangeError("uint64 to uint32 overflow");
1254
0
              }
1255
0
              CEL_RETURN_IF_ERROR(well_known_types_.UInt32Value().Initialize(
1256
0
                  field->message_type()));
1257
0
              well_known_types_.UInt32Value().SetValue(
1258
0
                  reflection_->MutableMessage(message_, field,
1259
0
                                              message_factory_),
1260
0
                  static_cast<uint32_t>(uint_value->NativeValue()));
1261
0
              return std::nullopt;
1262
0
            }
1263
0
            return TypeConversionError(value.GetTypeName(),
1264
0
                                       field->message_type()->full_name(),
1265
0
                                       arena_);
1266
0
          }
1267
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_UINT64VALUE: {
1268
0
            if (value.IsNull()) {
1269
              // Allowing assigning `null` to message fields.
1270
0
              return std::nullopt;
1271
0
            }
1272
0
            if (auto uint_value = value.AsUint(); uint_value) {
1273
0
              CEL_RETURN_IF_ERROR(well_known_types_.UInt64Value().Initialize(
1274
0
                  field->message_type()));
1275
0
              well_known_types_.UInt64Value().SetValue(
1276
0
                  reflection_->MutableMessage(message_, field,
1277
0
                                              message_factory_),
1278
0
                  uint_value->NativeValue());
1279
0
              return std::nullopt;
1280
0
            }
1281
0
            return TypeConversionError(value.GetTypeName(),
1282
0
                                       field->message_type()->full_name(),
1283
0
                                       arena_);
1284
0
          }
1285
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_FLOATVALUE: {
1286
0
            if (value.IsNull()) {
1287
              // Allowing assigning `null` to message fields.
1288
0
              return std::nullopt;
1289
0
            }
1290
0
            if (auto double_value = value.AsDouble(); double_value) {
1291
0
              CEL_RETURN_IF_ERROR(well_known_types_.FloatValue().Initialize(
1292
0
                  field->message_type()));
1293
0
              well_known_types_.FloatValue().SetValue(
1294
0
                  reflection_->MutableMessage(message_, field,
1295
0
                                              message_factory_),
1296
0
                  static_cast<float>(double_value->NativeValue()));
1297
0
              return std::nullopt;
1298
0
            }
1299
0
            return TypeConversionError(value.GetTypeName(),
1300
0
                                       field->message_type()->full_name(),
1301
0
                                       arena_);
1302
0
          }
1303
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_DOUBLEVALUE: {
1304
0
            if (value.IsNull()) {
1305
              // Allowing assigning `null` to message fields.
1306
0
              return std::nullopt;
1307
0
            }
1308
0
            if (auto double_value = value.AsDouble(); double_value) {
1309
0
              CEL_RETURN_IF_ERROR(well_known_types_.DoubleValue().Initialize(
1310
0
                  field->message_type()));
1311
0
              well_known_types_.DoubleValue().SetValue(
1312
0
                  reflection_->MutableMessage(message_, field,
1313
0
                                              message_factory_),
1314
0
                  double_value->NativeValue());
1315
0
              return std::nullopt;
1316
0
            }
1317
0
            return TypeConversionError(value.GetTypeName(),
1318
0
                                       field->message_type()->full_name(),
1319
0
                                       arena_);
1320
0
          }
1321
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_BYTESVALUE: {
1322
0
            if (value.IsNull()) {
1323
              // Allowing assigning `null` to message fields.
1324
0
              return std::nullopt;
1325
0
            }
1326
0
            if (auto bytes_value = value.AsBytes(); bytes_value) {
1327
0
              CEL_RETURN_IF_ERROR(well_known_types_.BytesValue().Initialize(
1328
0
                  field->message_type()));
1329
0
              well_known_types_.BytesValue().SetValue(
1330
0
                  reflection_->MutableMessage(message_, field,
1331
0
                                              message_factory_),
1332
0
                  bytes_value->NativeCord());
1333
0
              return std::nullopt;
1334
0
            }
1335
0
            return TypeConversionError(value.GetTypeName(),
1336
0
                                       field->message_type()->full_name(),
1337
0
                                       arena_);
1338
0
          }
1339
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_STRINGVALUE: {
1340
0
            if (value.IsNull()) {
1341
              // Allowing assigning `null` to message fields.
1342
0
              return std::nullopt;
1343
0
            }
1344
0
            if (auto string_value = value.AsString(); string_value) {
1345
0
              CEL_RETURN_IF_ERROR(well_known_types_.StringValue().Initialize(
1346
0
                  field->message_type()));
1347
0
              well_known_types_.StringValue().SetValue(
1348
0
                  reflection_->MutableMessage(message_, field,
1349
0
                                              message_factory_),
1350
0
                  string_value->NativeCord());
1351
0
              return std::nullopt;
1352
0
            }
1353
0
            return TypeConversionError(value.GetTypeName(),
1354
0
                                       field->message_type()->full_name(),
1355
0
                                       arena_);
1356
0
          }
1357
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_DURATION: {
1358
0
            if (value.IsNull()) {
1359
              // Allowing assigning `null` to message fields.
1360
0
              return std::nullopt;
1361
0
            }
1362
0
            if (auto duration_value = value.AsDuration(); duration_value) {
1363
0
              CEL_RETURN_IF_ERROR(well_known_types_.Duration().Initialize(
1364
0
                  field->message_type()));
1365
1366
0
              well_known_types_.Duration().UnsafeSetFromAbslDuration(
1367
0
                  reflection_->MutableMessage(message_, field,
1368
0
                                              message_factory_),
1369
0
                  duration_value->NativeValue());
1370
0
              return std::nullopt;
1371
0
            }
1372
0
            return TypeConversionError(value.GetTypeName(),
1373
0
                                       field->message_type()->full_name(),
1374
0
                                       arena_);
1375
0
          }
1376
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_TIMESTAMP: {
1377
0
            if (value.IsNull()) {
1378
              // Allowing assigning `null` to message fields.
1379
0
              return std::nullopt;
1380
0
            }
1381
0
            if (auto timestamp_value = value.AsTimestamp(); timestamp_value) {
1382
0
              CEL_RETURN_IF_ERROR(well_known_types_.Timestamp().Initialize(
1383
0
                  field->message_type()));
1384
0
              well_known_types_.Timestamp().UnsafeSetFromAbslTime(
1385
0
                  reflection_->MutableMessage(message_, field,
1386
0
                                              message_factory_),
1387
0
                  timestamp_value->NativeValue());
1388
0
              return std::nullopt;
1389
0
            }
1390
0
            return TypeConversionError(value.GetTypeName(),
1391
0
                                       field->message_type()->full_name(),
1392
0
                                       arena_);
1393
0
          }
1394
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE: {
1395
0
            CEL_RETURN_IF_ERROR(
1396
0
                value.ConvertToJson(descriptor_pool_, message_factory_,
1397
0
                                    reflection_->MutableMessage(
1398
0
                                        message_, field, message_factory_)));
1399
0
            return std::nullopt;
1400
0
          }
1401
401k
          case google::protobuf::Descriptor::WELLKNOWNTYPE_LISTVALUE: {
1402
401k
            CEL_RETURN_IF_ERROR(value.ConvertToJsonArray(
1403
401k
                descriptor_pool_, message_factory_,
1404
401k
                reflection_->MutableMessage(message_, field,
1405
401k
                                            message_factory_)));
1406
401k
            return std::nullopt;
1407
401k
          }
1408
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT: {
1409
0
            CEL_RETURN_IF_ERROR(value.ConvertToJsonObject(
1410
0
                descriptor_pool_, message_factory_,
1411
0
                reflection_->MutableMessage(message_, field,
1412
0
                                            message_factory_)));
1413
0
            return std::nullopt;
1414
0
          }
1415
0
          case google::protobuf::Descriptor::WELLKNOWNTYPE_ANY: {
1416
            // Probably not correct, need to use the parent/common one.
1417
0
            google::protobuf::io::CordOutputStream serialized;
1418
0
            CEL_RETURN_IF_ERROR(value.SerializeTo(
1419
0
                descriptor_pool_, message_factory_, &serialized));
1420
0
            std::string type_url;
1421
0
            switch (value.kind()) {
1422
0
              case ValueKind::kNull:
1423
0
                type_url = MakeTypeUrl("google.protobuf.Value");
1424
0
                break;
1425
0
              case ValueKind::kBool:
1426
0
                type_url = MakeTypeUrl("google.protobuf.BoolValue");
1427
0
                break;
1428
0
              case ValueKind::kInt:
1429
0
                type_url = MakeTypeUrl("google.protobuf.Int64Value");
1430
0
                break;
1431
0
              case ValueKind::kUint:
1432
0
                type_url = MakeTypeUrl("google.protobuf.UInt64Value");
1433
0
                break;
1434
0
              case ValueKind::kDouble:
1435
0
                type_url = MakeTypeUrl("google.protobuf.DoubleValue");
1436
0
                break;
1437
0
              case ValueKind::kBytes:
1438
0
                type_url = MakeTypeUrl("google.protobuf.BytesValue");
1439
0
                break;
1440
0
              case ValueKind::kString:
1441
0
                type_url = MakeTypeUrl("google.protobuf.StringValue");
1442
0
                break;
1443
0
              case ValueKind::kList:
1444
0
                type_url = MakeTypeUrl("google.protobuf.ListValue");
1445
0
                break;
1446
0
              case ValueKind::kMap:
1447
0
                type_url = MakeTypeUrl("google.protobuf.Struct");
1448
0
                break;
1449
0
              case ValueKind::kDuration:
1450
0
                type_url = MakeTypeUrl("google.protobuf.Duration");
1451
0
                break;
1452
0
              case ValueKind::kTimestamp:
1453
0
                type_url = MakeTypeUrl("google.protobuf.Timestamp");
1454
0
                break;
1455
0
              default:
1456
0
                type_url = MakeTypeUrl(value.GetTypeName());
1457
0
                break;
1458
0
            }
1459
0
            CEL_RETURN_IF_ERROR(
1460
0
                well_known_types_.Any().Initialize(field->message_type()));
1461
0
            well_known_types_.Any().SetTypeUrl(
1462
0
                reflection_->MutableMessage(message_, field, message_factory_),
1463
0
                type_url);
1464
0
            well_known_types_.Any().SetValue(
1465
0
                reflection_->MutableMessage(message_, field, message_factory_),
1466
0
                std::move(serialized).Consume());
1467
0
            return std::nullopt;
1468
0
          }
1469
0
          default:
1470
0
            if (value.IsNull()) {
1471
              // Allowing assigning `null` to message fields.
1472
0
              return std::nullopt;
1473
0
            }
1474
0
            break;
1475
401k
        }
1476
0
        return ProtoMessageFromValueImpl(
1477
0
            value, descriptor_pool_, message_factory_, &well_known_types_,
1478
0
            reflection_->MutableMessage(message_, field, message_factory_),
1479
0
            arena_);
1480
401k
      }
1481
0
      default:
1482
0
        return absl::InternalError(
1483
0
            absl::StrCat("unexpected protocol buffer message field type: ",
1484
0
                         field->cpp_type_name()));
1485
431k
    }
1486
431k
  }
1487
1488
  absl::StatusOr<absl::optional<ErrorValue>> SetField(
1489
431k
      const google::protobuf::FieldDescriptor* absl_nonnull field, Value value) {
1490
431k
    if (field->is_map()) {
1491
0
      return SetMapField(field, std::move(value));
1492
0
    }
1493
431k
    if (field->is_repeated()) {
1494
0
      return SetRepeatedField(field, std::move(value));
1495
0
    }
1496
431k
    return SetSingularField(field, std::move(value));
1497
431k
  }
1498
1499
  google::protobuf::Arena* absl_nullable const arena_;
1500
  const google::protobuf::DescriptorPool* absl_nonnull const descriptor_pool_;
1501
  google::protobuf::MessageFactory* absl_nonnull const message_factory_;
1502
  google::protobuf::Message* absl_nullable message_;
1503
  const google::protobuf::Descriptor* absl_nonnull const descriptor_;
1504
  const google::protobuf::Reflection* absl_nonnull const reflection_;
1505
  well_known_types::Reflection well_known_types_;
1506
};
1507
1508
class ValueBuilderImpl final : public ValueBuilder {
1509
 public:
1510
  ValueBuilderImpl(google::protobuf::Arena* absl_nullable arena,
1511
                   const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
1512
                   google::protobuf::MessageFactory* absl_nonnull message_factory,
1513
                   google::protobuf::Message* absl_nonnull message)
1514
950k
      : builder_(arena, descriptor_pool, message_factory, message) {}
1515
1516
  absl::StatusOr<absl::optional<ErrorValue>> SetFieldByName(
1517
431k
      absl::string_view name, Value value) override {
1518
431k
    return builder_.SetFieldByName(name, std::move(value));
1519
431k
  }
1520
1521
  absl::StatusOr<absl::optional<ErrorValue>> SetFieldByNumber(
1522
0
      int64_t number, Value value) override {
1523
0
    return builder_.SetFieldByNumber(number, std::move(value));
1524
0
  }
1525
1526
920k
  absl::StatusOr<Value> Build() && override {
1527
920k
    return std::move(builder_).Build();
1528
920k
  }
1529
1530
 private:
1531
  MessageValueBuilderImpl builder_;
1532
};
1533
1534
class StructValueBuilderImpl final : public StructValueBuilder {
1535
 public:
1536
  StructValueBuilderImpl(
1537
      google::protobuf::Arena* absl_nullable arena,
1538
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
1539
      google::protobuf::MessageFactory* absl_nonnull message_factory,
1540
      google::protobuf::Message* absl_nonnull message)
1541
0
      : builder_(arena, descriptor_pool, message_factory, message) {}
1542
1543
  absl::StatusOr<absl::optional<ErrorValue>> SetFieldByName(
1544
0
      absl::string_view name, Value value) override {
1545
0
    return builder_.SetFieldByName(name, std::move(value));
1546
0
  }
1547
1548
  absl::StatusOr<absl::optional<ErrorValue>> SetFieldByNumber(
1549
0
      int64_t number, Value value) override {
1550
0
    return builder_.SetFieldByNumber(number, std::move(value));
1551
0
  }
1552
1553
0
  absl::StatusOr<StructValue> Build() && override {
1554
0
    return std::move(builder_).BuildStruct();
1555
0
  }
1556
1557
 private:
1558
  MessageValueBuilderImpl builder_;
1559
};
1560
1561
}  // namespace
1562
1563
absl_nullable cel::ValueBuilderPtr NewValueBuilder(
1564
    Allocator<> allocator,
1565
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
1566
    google::protobuf::MessageFactory* absl_nonnull message_factory,
1567
975k
    absl::string_view name) {
1568
975k
  const google::protobuf::Descriptor* absl_nullable descriptor =
1569
975k
      descriptor_pool->FindMessageTypeByName(name);
1570
975k
  if (descriptor == nullptr) {
1571
25.1k
    return nullptr;
1572
25.1k
  }
1573
950k
  const google::protobuf::Message* absl_nullable prototype =
1574
950k
      message_factory->GetPrototype(descriptor);
1575
1.90M
  ABSL_DCHECK(prototype != nullptr)
1576
1.90M
      << "failed to get message prototype from factory, did you pass a dynamic "
1577
1.90M
         "descriptor to the generated message factory? we consider this to be "
1578
1.90M
         "a logic error and not a runtime error: "
1579
1.90M
      << descriptor->full_name();
1580
950k
  if (ABSL_PREDICT_FALSE(prototype == nullptr)) {
1581
0
    return nullptr;
1582
0
  }
1583
950k
  return std::make_unique<ValueBuilderImpl>(allocator.arena(), descriptor_pool,
1584
950k
                                            message_factory,
1585
950k
                                            prototype->New(allocator.arena()));
1586
950k
}
1587
1588
absl_nullable cel::StructValueBuilderPtr NewStructValueBuilder(
1589
    Allocator<> allocator,
1590
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
1591
    google::protobuf::MessageFactory* absl_nonnull message_factory,
1592
0
    absl::string_view name) {
1593
0
  const google::protobuf::Descriptor* absl_nullable descriptor =
1594
0
      descriptor_pool->FindMessageTypeByName(name);
1595
0
  if (descriptor == nullptr) {
1596
0
    return nullptr;
1597
0
  }
1598
0
  const google::protobuf::Message* absl_nullable prototype =
1599
0
      message_factory->GetPrototype(descriptor);
1600
0
  ABSL_DCHECK(prototype != nullptr)
1601
0
      << "failed to get message prototype from factory, did you pass a dynamic "
1602
0
         "descriptor to the generated message factory? we consider this to be "
1603
0
         "a logic error and not a runtime error: "
1604
0
      << descriptor->full_name();
1605
0
  if (ABSL_PREDICT_FALSE(prototype == nullptr)) {
1606
0
    return nullptr;
1607
0
  }
1608
0
  return std::make_unique<StructValueBuilderImpl>(
1609
0
      allocator.arena(), descriptor_pool, message_factory,
1610
0
      prototype->New(allocator.arena()));
1611
0
}
1612
1613
}  // namespace cel::common_internal