Coverage Report

Created: 2026-05-27 07:00

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