Coverage Report

Created: 2026-09-14 06:52

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