Coverage Report

Created: 2026-05-27 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/ast_proto.cc
Line
Count
Source
1
// Copyright 2022 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/ast_proto.h"
16
17
#include <cstdint>
18
#include <memory>
19
#include <string>
20
#include <utility>
21
#include <vector>
22
23
#include "cel/expr/checked.pb.h"
24
#include "cel/expr/syntax.pb.h"
25
#include "google/protobuf/duration.pb.h"
26
#include "google/protobuf/struct.pb.h"
27
#include "google/protobuf/timestamp.pb.h"
28
#include "absl/base/nullability.h"
29
#include "absl/container/flat_hash_map.h"
30
#include "absl/status/status.h"
31
#include "absl/status/statusor.h"
32
#include "absl/types/variant.h"
33
#include "common/ast.h"
34
#include "common/ast/constant_proto.h"
35
#include "common/ast/expr_proto.h"
36
#include "common/ast/source_info_proto.h"
37
#include "common/constant.h"
38
#include "common/expr.h"
39
#include "internal/status_macros.h"
40
41
namespace cel {
42
namespace {
43
44
using ::cel::ast_internal::ConstantFromProto;
45
using ::cel::ast_internal::ConstantToProto;
46
using ::cel::ast_internal::ExprFromProto;
47
using ::cel::ast_internal::ExprToProto;
48
49
using ExprPb = cel::expr::Expr;
50
using ParsedExprPb = cel::expr::ParsedExpr;
51
using CheckedExprPb = cel::expr::CheckedExpr;
52
using SourceInfoPb = cel::expr::SourceInfo;
53
using ExtensionPb = cel::expr::SourceInfo::Extension;
54
using ReferencePb = cel::expr::Reference;
55
using TypePb = cel::expr::Type;
56
using ExtensionPb = cel::expr::SourceInfo::Extension;
57
58
10.3k
absl::StatusOr<Expr> ExprValueFromProto(const ExprPb& expr) {
59
10.3k
  Expr result;
60
10.3k
  CEL_RETURN_IF_ERROR(ExprFromProto(expr, result));
61
10.3k
  return result;
62
10.3k
}
63
64
absl::StatusOr<SourceInfo> ConvertProtoSourceInfoToNative(
65
10.3k
    const cel::expr::SourceInfo& source_info) {
66
10.3k
  absl::flat_hash_map<int64_t, Expr> macro_calls;
67
10.3k
  for (const auto& pair : source_info.macro_calls()) {
68
0
    auto native_expr = ExprValueFromProto(pair.second);
69
0
    if (!native_expr.ok()) {
70
0
      return native_expr.status();
71
0
    }
72
0
    macro_calls.emplace(pair.first, *(std::move(native_expr)));
73
0
  }
74
10.3k
  std::vector<ExtensionSpec> extensions;
75
10.3k
  extensions.reserve(source_info.extensions_size());
76
10.3k
  for (const auto& extension : source_info.extensions()) {
77
0
    std::vector<ExtensionSpec::Component> components;
78
0
    components.reserve(extension.affected_components().size());
79
0
    for (const auto& component : extension.affected_components()) {
80
0
      switch (component) {
81
0
        case ExtensionPb::COMPONENT_PARSER:
82
0
          components.push_back(ExtensionSpec::Component::kParser);
83
0
          break;
84
0
        case ExtensionPb::COMPONENT_TYPE_CHECKER:
85
0
          components.push_back(ExtensionSpec::Component::kTypeChecker);
86
0
          break;
87
0
        case ExtensionPb::COMPONENT_RUNTIME:
88
0
          components.push_back(ExtensionSpec::Component::kRuntime);
89
0
          break;
90
0
        default:
91
0
          components.push_back(ExtensionSpec::Component::kUnspecified);
92
0
          break;
93
0
      }
94
0
    }
95
0
    extensions.push_back(ExtensionSpec(
96
0
        extension.id(),
97
0
        std::make_unique<ExtensionSpec::Version>(extension.version().major(),
98
0
                                                 extension.version().minor()),
99
0
        std::move(components)));
100
0
  }
101
10.3k
  return SourceInfo(
102
10.3k
      source_info.syntax_version(), source_info.location(),
103
10.3k
      std::vector<int32_t>(source_info.line_offsets().begin(),
104
10.3k
                           source_info.line_offsets().end()),
105
10.3k
      absl::flat_hash_map<int64_t, int32_t>(source_info.positions().begin(),
106
10.3k
                                            source_info.positions().end()),
107
10.3k
      std::move(macro_calls), std::move(extensions));
108
10.3k
}
109
110
absl::StatusOr<TypeSpec> ConvertProtoTypeToNative(
111
    const cel::expr::Type& type);
112
113
absl::StatusOr<PrimitiveType> ToNative(
114
0
    cel::expr::Type::PrimitiveType primitive_type) {
115
0
  switch (primitive_type) {
116
0
    case cel::expr::Type::PRIMITIVE_TYPE_UNSPECIFIED:
117
0
      return PrimitiveType::kPrimitiveTypeUnspecified;
118
0
    case cel::expr::Type::BOOL:
119
0
      return PrimitiveType::kBool;
120
0
    case cel::expr::Type::INT64:
121
0
      return PrimitiveType::kInt64;
122
0
    case cel::expr::Type::UINT64:
123
0
      return PrimitiveType::kUint64;
124
0
    case cel::expr::Type::DOUBLE:
125
0
      return PrimitiveType::kDouble;
126
0
    case cel::expr::Type::STRING:
127
0
      return PrimitiveType::kString;
128
0
    case cel::expr::Type::BYTES:
129
0
      return PrimitiveType::kBytes;
130
0
    default:
131
0
      return absl::InvalidArgumentError(
132
0
          "Illegal type specified for "
133
0
          "cel::expr::Type::PrimitiveType.");
134
0
  }
135
0
}
136
137
absl::StatusOr<WellKnownTypeSpec> ToNative(
138
0
    cel::expr::Type::WellKnownType well_known_type) {
139
0
  switch (well_known_type) {
140
0
    case cel::expr::Type::WELL_KNOWN_TYPE_UNSPECIFIED:
141
0
      return WellKnownTypeSpec::kWellKnownTypeUnspecified;
142
0
    case cel::expr::Type::ANY:
143
0
      return WellKnownTypeSpec::kAny;
144
0
    case cel::expr::Type::TIMESTAMP:
145
0
      return WellKnownTypeSpec::kTimestamp;
146
0
    case cel::expr::Type::DURATION:
147
0
      return WellKnownTypeSpec::kDuration;
148
0
    default:
149
0
      return absl::InvalidArgumentError(
150
0
          "Illegal type specified for "
151
0
          "cel::expr::Type::WellKnownType.");
152
0
  }
153
0
}
154
155
absl::StatusOr<ListTypeSpec> ToNative(
156
0
    const cel::expr::Type::ListType& list_type) {
157
0
  auto native_elem_type = ConvertProtoTypeToNative(list_type.elem_type());
158
0
  if (!native_elem_type.ok()) {
159
0
    return native_elem_type.status();
160
0
  }
161
0
  return ListTypeSpec(
162
0
      std::make_unique<TypeSpec>(*(std::move(native_elem_type))));
163
0
}
164
165
absl::StatusOr<MapTypeSpec> ToNative(
166
0
    const cel::expr::Type::MapType& map_type) {
167
0
  auto native_key_type = ConvertProtoTypeToNative(map_type.key_type());
168
0
  if (!native_key_type.ok()) {
169
0
    return native_key_type.status();
170
0
  }
171
0
  auto native_value_type = ConvertProtoTypeToNative(map_type.value_type());
172
0
  if (!native_value_type.ok()) {
173
0
    return native_value_type.status();
174
0
  }
175
0
  return MapTypeSpec(
176
0
      std::make_unique<TypeSpec>(*(std::move(native_key_type))),
177
0
      std::make_unique<TypeSpec>(*(std::move(native_value_type))));
178
0
}
179
180
absl::StatusOr<FunctionTypeSpec> ToNative(
181
0
    const cel::expr::Type::FunctionType& function_type) {
182
0
  std::vector<TypeSpec> arg_types;
183
0
  arg_types.reserve(function_type.arg_types_size());
184
0
  for (const auto& arg_type : function_type.arg_types()) {
185
0
    auto native_arg = ConvertProtoTypeToNative(arg_type);
186
0
    if (!native_arg.ok()) {
187
0
      return native_arg.status();
188
0
    }
189
0
    arg_types.emplace_back(*(std::move(native_arg)));
190
0
  }
191
0
  auto native_result = ConvertProtoTypeToNative(function_type.result_type());
192
0
  if (!native_result.ok()) {
193
0
    return native_result.status();
194
0
  }
195
0
  return FunctionTypeSpec(
196
0
      std::make_unique<TypeSpec>(*(std::move(native_result))),
197
0
      std::move(arg_types));
198
0
}
199
200
absl::StatusOr<AbstractType> ToNative(
201
0
    const cel::expr::Type::AbstractType& abstract_type) {
202
0
  std::vector<TypeSpec> parameter_types;
203
0
  for (const auto& parameter_type : abstract_type.parameter_types()) {
204
0
    auto native_parameter_type = ConvertProtoTypeToNative(parameter_type);
205
0
    if (!native_parameter_type.ok()) {
206
0
      return native_parameter_type.status();
207
0
    }
208
0
    parameter_types.emplace_back(*(std::move(native_parameter_type)));
209
0
  }
210
0
  return AbstractType(abstract_type.name(), std::move(parameter_types));
211
0
}
212
213
absl::StatusOr<TypeSpec> ConvertProtoTypeToNative(
214
0
    const cel::expr::Type& type) {
215
0
  switch (type.type_kind_case()) {
216
0
    case cel::expr::Type::kDyn:
217
0
      return TypeSpec(DynTypeSpec());
218
0
    case cel::expr::Type::kNull:
219
0
      return TypeSpec(NullTypeSpec());
220
0
    case cel::expr::Type::kPrimitive: {
221
0
      auto native_primitive = ToNative(type.primitive());
222
0
      if (!native_primitive.ok()) {
223
0
        return native_primitive.status();
224
0
      }
225
0
      return TypeSpec(*(std::move(native_primitive)));
226
0
    }
227
0
    case cel::expr::Type::kWrapper: {
228
0
      auto native_wrapper = ToNative(type.wrapper());
229
0
      if (!native_wrapper.ok()) {
230
0
        return native_wrapper.status();
231
0
      }
232
0
      return TypeSpec(PrimitiveTypeWrapper(*(std::move(native_wrapper))));
233
0
    }
234
0
    case cel::expr::Type::kWellKnown: {
235
0
      auto native_well_known = ToNative(type.well_known());
236
0
      if (!native_well_known.ok()) {
237
0
        return native_well_known.status();
238
0
      }
239
0
      return TypeSpec(*std::move(native_well_known));
240
0
    }
241
0
    case cel::expr::Type::kListType: {
242
0
      auto native_list_type = ToNative(type.list_type());
243
0
      if (!native_list_type.ok()) {
244
0
        return native_list_type.status();
245
0
      }
246
0
      return TypeSpec(*(std::move(native_list_type)));
247
0
    }
248
0
    case cel::expr::Type::kMapType: {
249
0
      auto native_map_type = ToNative(type.map_type());
250
0
      if (!native_map_type.ok()) {
251
0
        return native_map_type.status();
252
0
      }
253
0
      return TypeSpec(*(std::move(native_map_type)));
254
0
    }
255
0
    case cel::expr::Type::kFunction: {
256
0
      auto native_function = ToNative(type.function());
257
0
      if (!native_function.ok()) {
258
0
        return native_function.status();
259
0
      }
260
0
      return TypeSpec(*(std::move(native_function)));
261
0
    }
262
0
    case cel::expr::Type::kMessageType:
263
0
      return TypeSpec(MessageTypeSpec(type.message_type()));
264
0
    case cel::expr::Type::kTypeParam:
265
0
      return TypeSpec(ParamTypeSpec(type.type_param()));
266
0
    case cel::expr::Type::kType: {
267
0
      if (type.type().type_kind_case() ==
268
0
          cel::expr::Type::TypeKindCase::TYPE_KIND_NOT_SET) {
269
0
        return TypeSpec(std::unique_ptr<TypeSpec>());
270
0
      }
271
0
      auto native_type = ConvertProtoTypeToNative(type.type());
272
0
      if (!native_type.ok()) {
273
0
        return native_type.status();
274
0
      }
275
0
      return TypeSpec(std::make_unique<TypeSpec>(*std::move(native_type)));
276
0
    }
277
0
    case cel::expr::Type::kError:
278
0
      return TypeSpec(ErrorTypeSpec::kValue);
279
0
    case cel::expr::Type::kAbstractType: {
280
0
      auto native_abstract = ToNative(type.abstract_type());
281
0
      if (!native_abstract.ok()) {
282
0
        return native_abstract.status();
283
0
      }
284
0
      return TypeSpec(*(std::move(native_abstract)));
285
0
    }
286
0
    case cel::expr::Type::TYPE_KIND_NOT_SET:
287
0
      return TypeSpec(UnsetTypeSpec());
288
0
    default:
289
0
      return absl::InvalidArgumentError(
290
0
          "Illegal type specified for cel::expr::Type.");
291
0
  }
292
0
}
293
294
absl::StatusOr<Reference> ConvertProtoReferenceToNative(
295
0
    const cel::expr::Reference& reference) {
296
0
  Reference ret_val;
297
0
  ret_val.set_name(reference.name());
298
0
  ret_val.mutable_overload_id().reserve(reference.overload_id_size());
299
0
  for (const auto& elem : reference.overload_id()) {
300
0
    ret_val.mutable_overload_id().emplace_back(elem);
301
0
  }
302
0
  if (reference.has_value()) {
303
0
    CEL_RETURN_IF_ERROR(
304
0
        ConstantFromProto(reference.value(), ret_val.mutable_value()));
305
0
  }
306
0
  return ret_val;
307
0
}
308
309
0
absl::StatusOr<ReferencePb> ReferenceToProto(const Reference& reference) {
310
0
  ReferencePb result;
311
312
0
  result.set_name(reference.name());
313
314
0
  for (const auto& overload_id : reference.overload_id()) {
315
0
    result.add_overload_id(overload_id);
316
0
  }
317
318
0
  if (reference.has_value()) {
319
0
    CEL_RETURN_IF_ERROR(
320
0
        ConstantToProto(reference.value(), result.mutable_value()));
321
0
  }
322
323
0
  return result;
324
0
}
325
326
absl::Status TypeToProto(const TypeSpec& type, TypePb* result);
327
328
struct TypeKindToProtoVisitor {
329
0
  absl::Status operator()(PrimitiveType primitive) {
330
0
    switch (primitive) {
331
0
      case PrimitiveType::kPrimitiveTypeUnspecified:
332
0
        result->set_primitive(TypePb::PRIMITIVE_TYPE_UNSPECIFIED);
333
0
        return absl::OkStatus();
334
0
      case PrimitiveType::kBool:
335
0
        result->set_primitive(TypePb::BOOL);
336
0
        return absl::OkStatus();
337
0
      case PrimitiveType::kInt64:
338
0
        result->set_primitive(TypePb::INT64);
339
0
        return absl::OkStatus();
340
0
      case PrimitiveType::kUint64:
341
0
        result->set_primitive(TypePb::UINT64);
342
0
        return absl::OkStatus();
343
0
      case PrimitiveType::kDouble:
344
0
        result->set_primitive(TypePb::DOUBLE);
345
0
        return absl::OkStatus();
346
0
      case PrimitiveType::kString:
347
0
        result->set_primitive(TypePb::STRING);
348
0
        return absl::OkStatus();
349
0
      case PrimitiveType::kBytes:
350
0
        result->set_primitive(TypePb::BYTES);
351
0
        return absl::OkStatus();
352
0
      default:
353
0
        break;
354
0
    }
355
0
    return absl::InvalidArgumentError("Unsupported primitive type");
356
0
  }
357
358
0
  absl::Status operator()(PrimitiveTypeWrapper wrapper) {
359
0
    CEL_RETURN_IF_ERROR(this->operator()(wrapper.type()));
360
0
    auto wrapped = result->primitive();
361
0
    result->set_wrapper(wrapped);
362
0
    return absl::OkStatus();
363
0
  }
364
365
0
  absl::Status operator()(UnsetTypeSpec) {
366
0
    result->clear_type_kind();
367
0
    return absl::OkStatus();
368
0
  }
369
370
0
  absl::Status operator()(DynTypeSpec) {
371
0
    result->mutable_dyn();
372
0
    return absl::OkStatus();
373
0
  }
374
375
0
  absl::Status operator()(ErrorTypeSpec) {
376
0
    result->mutable_error();
377
0
    return absl::OkStatus();
378
0
  }
379
380
0
  absl::Status operator()(NullTypeSpec) {
381
0
    result->set_null(google::protobuf::NULL_VALUE);
382
0
    return absl::OkStatus();
383
0
  }
384
385
0
  absl::Status operator()(const ListTypeSpec& list_type) {
386
0
    return TypeToProto(list_type.elem_type(),
387
0
                       result->mutable_list_type()->mutable_elem_type());
388
0
  }
389
390
0
  absl::Status operator()(const MapTypeSpec& map_type) {
391
0
    CEL_RETURN_IF_ERROR(TypeToProto(
392
0
        map_type.key_type(), result->mutable_map_type()->mutable_key_type()));
393
0
    return TypeToProto(map_type.value_type(),
394
0
                       result->mutable_map_type()->mutable_value_type());
395
0
  }
396
397
0
  absl::Status operator()(const MessageTypeSpec& message_type) {
398
0
    result->set_message_type(message_type.type());
399
0
    return absl::OkStatus();
400
0
  }
401
402
0
  absl::Status operator()(const WellKnownTypeSpec& well_known_type) {
403
0
    switch (well_known_type) {
404
0
      case WellKnownTypeSpec::kWellKnownTypeUnspecified:
405
0
        result->set_well_known(TypePb::WELL_KNOWN_TYPE_UNSPECIFIED);
406
0
        return absl::OkStatus();
407
0
      case WellKnownTypeSpec::kAny:
408
0
        result->set_well_known(TypePb::ANY);
409
0
        return absl::OkStatus();
410
411
0
      case WellKnownTypeSpec::kDuration:
412
0
        result->set_well_known(TypePb::DURATION);
413
0
        return absl::OkStatus();
414
0
      case WellKnownTypeSpec::kTimestamp:
415
0
        result->set_well_known(TypePb::TIMESTAMP);
416
0
        return absl::OkStatus();
417
0
      default:
418
0
        break;
419
0
    }
420
0
    return absl::InvalidArgumentError("Unsupported well-known type");
421
0
  }
422
423
0
  absl::Status operator()(const FunctionTypeSpec& function_type) {
424
0
    CEL_RETURN_IF_ERROR(
425
0
        TypeToProto(function_type.result_type(),
426
0
                    result->mutable_function()->mutable_result_type()));
427
428
0
    for (const TypeSpec& arg_type : function_type.arg_types()) {
429
0
      CEL_RETURN_IF_ERROR(
430
0
          TypeToProto(arg_type, result->mutable_function()->add_arg_types()));
431
0
    }
432
0
    return absl::OkStatus();
433
0
  }
434
435
0
  absl::Status operator()(const AbstractType& type) {
436
0
    auto* abstract_type_pb = result->mutable_abstract_type();
437
0
    abstract_type_pb->set_name(type.name());
438
0
    for (const TypeSpec& type_param : type.parameter_types()) {
439
0
      CEL_RETURN_IF_ERROR(
440
0
          TypeToProto(type_param, abstract_type_pb->add_parameter_types()));
441
0
    }
442
0
    return absl::OkStatus();
443
0
  }
444
445
0
  absl::Status operator()(const std::unique_ptr<TypeSpec>& type_type) {
446
0
    return TypeToProto((type_type != nullptr) ? *type_type : TypeSpec(),
447
0
                       result->mutable_type());
448
0
  }
449
450
0
  absl::Status operator()(const ParamTypeSpec& param_type) {
451
0
    result->set_type_param(param_type.type());
452
0
    return absl::OkStatus();
453
0
  }
454
455
  TypePb* result;
456
};
457
458
0
absl::Status TypeToProto(const TypeSpec& type, TypePb* result) {
459
0
  return absl::visit(TypeKindToProtoVisitor{result}, type.type_kind());
460
0
}
461
462
}  // namespace
463
464
absl::StatusOr<std::unique_ptr<Ast>> CreateAstFromParsedExpr(
465
    const cel::expr::Expr& expr,
466
10.3k
    const cel::expr::SourceInfo* source_info) {
467
10.3k
  CEL_ASSIGN_OR_RETURN(auto runtime_expr, ExprValueFromProto(expr));
468
10.3k
  SourceInfo runtime_source_info;
469
10.3k
  if (source_info != nullptr) {
470
10.3k
    CEL_ASSIGN_OR_RETURN(runtime_source_info,
471
10.3k
                         ConvertProtoSourceInfoToNative(*source_info));
472
10.3k
  }
473
10.3k
  return std::make_unique<Ast>(std::move(runtime_expr),
474
10.3k
                               std::move(runtime_source_info));
475
10.3k
}
476
477
absl::StatusOr<std::unique_ptr<Ast>> CreateAstFromParsedExpr(
478
0
    const ParsedExprPb& parsed_expr) {
479
0
  return CreateAstFromParsedExpr(parsed_expr.expr(),
480
0
                                 &parsed_expr.source_info());
481
0
}
482
483
absl::Status AstToParsedExpr(const Ast& ast,
484
0
                             cel::expr::ParsedExpr* absl_nonnull out) {
485
0
  ParsedExprPb& parsed_expr = *out;
486
0
  CEL_RETURN_IF_ERROR(ExprToProto(ast.root_expr(), parsed_expr.mutable_expr()));
487
0
  CEL_RETURN_IF_ERROR(ast_internal::SourceInfoToProto(
488
0
      ast.source_info(), parsed_expr.mutable_source_info()));
489
490
0
  return absl::OkStatus();
491
0
}
492
493
absl::StatusOr<std::unique_ptr<Ast>> CreateAstFromCheckedExpr(
494
0
    const CheckedExprPb& checked_expr) {
495
0
  CEL_ASSIGN_OR_RETURN(Expr expr, ExprValueFromProto(checked_expr.expr()));
496
0
  CEL_ASSIGN_OR_RETURN(SourceInfo source_info, ConvertProtoSourceInfoToNative(
497
0
                                                   checked_expr.source_info()));
498
499
0
  Ast::ReferenceMap reference_map;
500
0
  for (const auto& pair : checked_expr.reference_map()) {
501
0
    auto native_reference = ConvertProtoReferenceToNative(pair.second);
502
0
    if (!native_reference.ok()) {
503
0
      return native_reference.status();
504
0
    }
505
0
    reference_map.emplace(pair.first, *(std::move(native_reference)));
506
0
  }
507
0
  Ast::TypeMap type_map;
508
0
  for (const auto& pair : checked_expr.type_map()) {
509
0
    auto native_type = ConvertProtoTypeToNative(pair.second);
510
0
    if (!native_type.ok()) {
511
0
      return native_type.status();
512
0
    }
513
0
    type_map.emplace(pair.first, *(std::move(native_type)));
514
0
  }
515
516
0
  return std::make_unique<Ast>(std::move(expr), std::move(source_info),
517
0
                               std::move(reference_map), std::move(type_map),
518
0
                               checked_expr.expr_version());
519
0
}
520
521
absl::Status AstToCheckedExpr(
522
0
    const Ast& ast, cel::expr::CheckedExpr* absl_nonnull out) {
523
0
  if (!ast.is_checked()) {
524
0
    return absl::InvalidArgumentError("AST is not type-checked");
525
0
  }
526
0
  CheckedExprPb& checked_expr = *out;
527
0
  checked_expr.set_expr_version(ast.expr_version());
528
0
  CEL_RETURN_IF_ERROR(
529
0
      ExprToProto(ast.root_expr(), checked_expr.mutable_expr()));
530
0
  CEL_RETURN_IF_ERROR(ast_internal::SourceInfoToProto(
531
0
      ast.source_info(), checked_expr.mutable_source_info()));
532
0
  for (auto it = ast.reference_map().begin(); it != ast.reference_map().end();
533
0
       ++it) {
534
0
    ReferencePb& dest_reference =
535
0
        (*checked_expr.mutable_reference_map())[it->first];
536
0
    CEL_ASSIGN_OR_RETURN(dest_reference, ReferenceToProto(it->second));
537
0
  }
538
539
0
  for (auto it = ast.type_map().begin(); it != ast.type_map().end(); ++it) {
540
0
    TypePb& dest_type = (*checked_expr.mutable_type_map())[it->first];
541
0
    CEL_RETURN_IF_ERROR(TypeToProto(it->second, &dest_type));
542
0
  }
543
544
0
  return absl::OkStatus();
545
0
}
546
547
}  // namespace cel