Coverage Report

Created: 2025-11-29 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/ast/metadata.h
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
// Type definitions for auxiliary structures in the AST.
16
//
17
// These are more direct equivalents to the public protobuf definitions.
18
//
19
// IWYU pragma: private, include "common/ast.h"
20
#ifndef THIRD_PARTY_CEL_CPP_COMMON_AST_METADATA_H_
21
#define THIRD_PARTY_CEL_CPP_COMMON_AST_METADATA_H_
22
23
#include <cstdint>
24
#include <memory>
25
#include <string>
26
#include <utility>
27
#include <vector>
28
29
#include "absl/base/nullability.h"
30
#include "absl/container/flat_hash_map.h"
31
#include "absl/types/optional.h"
32
#include "absl/types/variant.h"
33
#include "common/constant.h"
34
#include "common/expr.h"
35
36
namespace cel {
37
38
// An extension that was requested for the source expression.
39
class ExtensionSpec {
40
 public:
41
  // Version
42
  class Version {
43
   public:
44
0
    Version() : major_(0), minor_(0) {}
45
0
    Version(int64_t major, int64_t minor) : major_(major), minor_(minor) {}
46
47
    Version(const Version& other) = default;
48
    Version(Version&& other) = default;
49
    Version& operator=(const Version& other) = default;
50
    Version& operator=(Version&& other) = default;
51
52
    static const Version& DefaultInstance();
53
54
    // Major version changes indicate different required support level from
55
    // the required components.
56
0
    int64_t major() const { return major_; }
57
0
    void set_major(int64_t val) { major_ = val; }
58
59
    // Minor version changes must not change the observed behavior from
60
    // existing implementations, but may be provided informationally.
61
0
    int64_t minor() const { return minor_; }
62
0
    void set_minor(int64_t val) { minor_ = val; }
63
64
0
    bool operator==(const Version& other) const {
65
0
      return major_ == other.major_ && minor_ == other.minor_;
66
0
    }
67
68
0
    bool operator!=(const Version& other) const { return !operator==(other); }
69
70
   private:
71
    int64_t major_;
72
    int64_t minor_;
73
  };
74
75
  // CEL component specifier.
76
  enum class Component {
77
    // Unspecified, default.
78
    kUnspecified,
79
    // Parser. Converts a CEL string to an AST.
80
    kParser,
81
    // Type checker. Checks that references in an AST are defined and types
82
    // agree.
83
    kTypeChecker,
84
    // Runtime. Evaluates a parsed and optionally checked CEL AST against a
85
    // context.
86
    kRuntime
87
  };
88
89
  static const ExtensionSpec& DefaultInstance();
90
91
0
  ExtensionSpec() = default;
92
  ExtensionSpec(std::string id, std::unique_ptr<Version> version,
93
                std::vector<Component> affected_components)
94
      : id_(std::move(id)),
95
        affected_components_(std::move(affected_components)),
96
0
        version_(std::move(version)) {}
97
98
  ExtensionSpec(const ExtensionSpec& other);
99
  ExtensionSpec(ExtensionSpec&& other) = default;
100
  ExtensionSpec& operator=(const ExtensionSpec& other);
101
  ExtensionSpec& operator=(ExtensionSpec&& other) = default;
102
103
  // Identifier for the extension. Example: constant_folding
104
0
  const std::string& id() const { return id_; }
105
0
  void set_id(std::string id) { id_ = std::move(id); }
106
107
  // If set, the listed components must understand the extension for the
108
  // expression to evaluate correctly.
109
  //
110
  // This field has set semantics, repeated values should be deduplicated.
111
0
  const std::vector<Component>& affected_components() const {
112
0
    return affected_components_;
113
0
  }
114
115
0
  std::vector<Component>& mutable_affected_components() {
116
0
    return affected_components_;
117
0
  }
118
119
  // Version info. May be skipped if it isn't meaningful for the extension.
120
  // (for example constant_folding might always be v0.0).
121
0
  const Version& version() const {
122
0
    if (version_ == nullptr) {
123
0
      return Version::DefaultInstance();
124
0
    }
125
0
    return *version_;
126
0
  }
127
128
0
  Version& mutable_version() {
129
0
    if (version_ == nullptr) {
130
0
      version_ = std::make_unique<Version>();
131
0
    }
132
0
    return *version_;
133
0
  }
134
135
0
  void set_version(std::unique_ptr<Version> version) {
136
0
    version_ = std::move(version);
137
0
  }
138
139
0
  bool operator==(const ExtensionSpec& other) const {
140
0
    return id_ == other.id_ &&
141
0
           affected_components_ == other.affected_components_ &&
142
0
           version() == other.version();
143
0
  }
144
145
0
  bool operator!=(const ExtensionSpec& other) const {
146
0
    return !operator==(other);
147
0
  }
148
149
 private:
150
  std::string id_;
151
  std::vector<Component> affected_components_;
152
  std::unique_ptr<Version> version_;
153
};
154
155
// Source information collected at parse time.
156
class SourceInfo {
157
 public:
158
1.32k
  SourceInfo() = default;
159
  SourceInfo(std::string syntax_version, std::string location,
160
             std::vector<int32_t> line_offsets,
161
             absl::flat_hash_map<int64_t, int32_t> positions,
162
             absl::flat_hash_map<int64_t, Expr> macro_calls,
163
             std::vector<ExtensionSpec> extensions)
164
      : syntax_version_(std::move(syntax_version)),
165
        location_(std::move(location)),
166
        line_offsets_(std::move(line_offsets)),
167
        positions_(std::move(positions)),
168
        macro_calls_(std::move(macro_calls)),
169
0
        extensions_(std::move(extensions)) {}
170
171
  SourceInfo(const SourceInfo& other) = default;
172
2.64k
  SourceInfo(SourceInfo&& other) = default;
173
  SourceInfo& operator=(const SourceInfo& other) = default;
174
  SourceInfo& operator=(SourceInfo&& other) = default;
175
176
0
  void set_syntax_version(std::string syntax_version) {
177
0
    syntax_version_ = std::move(syntax_version);
178
0
  }
179
180
1.32k
  void set_location(std::string location) { location_ = std::move(location); }
181
182
0
  void set_line_offsets(std::vector<int32_t> line_offsets) {
183
0
    line_offsets_ = std::move(line_offsets);
184
0
  }
185
186
0
  void set_positions(absl::flat_hash_map<int64_t, int32_t> positions) {
187
0
    positions_ = std::move(positions);
188
0
  }
189
190
0
  void set_macro_calls(absl::flat_hash_map<int64_t, Expr> macro_calls) {
191
0
    macro_calls_ = std::move(macro_calls);
192
0
  }
193
194
1.32k
  const std::string& syntax_version() const { return syntax_version_; }
195
196
1.32k
  const std::string& location() const { return location_; }
197
198
1.32k
  const std::vector<int32_t>& line_offsets() const { return line_offsets_; }
199
200
1.28M
  std::vector<int32_t>& mutable_line_offsets() { return line_offsets_; }
201
202
1.71M
  const absl::flat_hash_map<int64_t, int32_t>& positions() const {
203
1.71M
    return positions_;
204
1.71M
  }
205
206
1.71M
  absl::flat_hash_map<int64_t, int32_t>& mutable_positions() {
207
1.71M
    return positions_;
208
1.71M
  }
209
210
2.64k
  const absl::flat_hash_map<int64_t, Expr>& macro_calls() const {
211
2.64k
    return macro_calls_;
212
2.64k
  }
213
214
1.32k
  absl::flat_hash_map<int64_t, Expr>& mutable_macro_calls() {
215
1.32k
    return macro_calls_;
216
1.32k
  }
217
218
0
  bool operator==(const SourceInfo& other) const {
219
0
    return syntax_version_ == other.syntax_version_ &&
220
0
           location_ == other.location_ &&
221
0
           line_offsets_ == other.line_offsets_ &&
222
0
           positions_ == other.positions_ &&
223
0
           macro_calls_ == other.macro_calls_ &&
224
0
           extensions_ == other.extensions_;
225
0
  }
226
227
0
  bool operator!=(const SourceInfo& other) const { return !operator==(other); }
228
229
1.32k
  const std::vector<ExtensionSpec>& extensions() const { return extensions_; }
230
231
0
  std::vector<ExtensionSpec>& mutable_extensions() { return extensions_; }
232
233
 private:
234
  // The syntax version of the source, e.g. `cel1`.
235
  std::string syntax_version_;
236
237
  // The location name. All position information attached to an expression is
238
  // relative to this location.
239
  //
240
  // The location could be a file, UI element, or similar. For example,
241
  // `acme/app/AnvilPolicy.cel`.
242
  std::string location_;
243
244
  // Monotonically increasing list of code point offsets where newlines
245
  // `\n` appear.
246
  //
247
  // The line number of a given position is the index `i` where for a given
248
  // `id` the `line_offsets[i] < id_positions[id] < line_offsets[i+1]`. The
249
  // column may be derivd from `id_positions[id] - line_offsets[i]`.
250
  //
251
  // TODO(uncreated-issue/14): clarify this documentation
252
  std::vector<int32_t> line_offsets_;
253
254
  // A map from the parse node id (e.g. `Expr.id`) to the code point offset
255
  // within source.
256
  absl::flat_hash_map<int64_t, int32_t> positions_;
257
258
  // A map from the parse node id where a macro replacement was made to the
259
  // call `Expr` that resulted in a macro expansion.
260
  //
261
  // For example, `has(value.field)` is a function call that is replaced by a
262
  // `test_only` field selection in the AST. Likewise, the call
263
  // `list.exists(e, e > 10)` translates to a comprehension expression. The key
264
  // in the map corresponds to the expression id of the expanded macro, and the
265
  // value is the call `Expr` that was replaced.
266
  absl::flat_hash_map<int64_t, Expr> macro_calls_;
267
268
  // A list of tags for extensions that were used while parsing or type checking
269
  // the source expression. For example, optimizations that require special
270
  // runtime support may be specified.
271
  //
272
  // These are used to check feature support between components in separate
273
  // implementations. This can be used to either skip redundant work or
274
  // report an error if the extension is unsupported.
275
  std::vector<ExtensionSpec> extensions_;
276
};
277
278
// CEL primitive types.
279
enum class PrimitiveType {
280
  // Unspecified type.
281
  kPrimitiveTypeUnspecified = 0,
282
  // Boolean type.
283
  kBool = 1,
284
  // Int64 type.
285
  //
286
  // Proto-based integer values are widened to int64.
287
  kInt64 = 2,
288
  // Uint64 type.
289
  //
290
  // Proto-based unsigned integer values are widened to uint64.
291
  kUint64 = 3,
292
  // Double type.
293
  //
294
  // Proto-based float values are widened to double values.
295
  kDouble = 4,
296
  // String type.
297
  kString = 5,
298
  // Bytes type.
299
  kBytes = 6,
300
};
301
302
// Well-known protobuf types treated with first-class support in CEL.
303
//
304
// TODO(uncreated-issue/15): represent well-known via abstract types (or however)
305
//   they will be named.
306
enum class WellKnownTypeSpec {
307
  // Unspecified type.
308
  kWellKnownTypeUnspecified = 0,
309
  // Well-known protobuf.Any type.
310
  //
311
  // Any types are a polymorphic message type. During type-checking they are
312
  // treated like `DYN` types, but at runtime they are resolved to a specific
313
  // message type specified at evaluation time.
314
  kAny = 1,
315
  // Well-known protobuf.Timestamp type, internally referenced as `timestamp`.
316
  kTimestamp = 2,
317
  // Well-known protobuf.Duration type, internally referenced as `duration`.
318
  kDuration = 3,
319
};
320
321
// forward declare for recursive types.
322
class TypeSpec;
323
324
// List type with typed elements, e.g. `list<example.proto.MyMessage>`.
325
class ListTypeSpec {
326
 public:
327
  ListTypeSpec() = default;
328
329
  ListTypeSpec(const ListTypeSpec& rhs);
330
  ListTypeSpec& operator=(const ListTypeSpec& rhs);
331
0
  ListTypeSpec(ListTypeSpec&& rhs) = default;
332
0
  ListTypeSpec& operator=(ListTypeSpec&& rhs) = default;
333
334
  explicit ListTypeSpec(std::unique_ptr<TypeSpec> elem_type);
335
336
  void set_elem_type(std::unique_ptr<TypeSpec> elem_type);
337
338
0
  bool has_elem_type() const { return elem_type_ != nullptr; }
339
340
  const TypeSpec& elem_type() const;
341
342
  TypeSpec& mutable_elem_type();
343
344
  bool operator==(const ListTypeSpec& other) const;
345
346
 private:
347
  std::unique_ptr<TypeSpec> elem_type_;
348
};
349
350
// Map type specifier with parameterized key and value types, e.g.
351
// `map<string, int>`.
352
class MapTypeSpec {
353
 public:
354
  MapTypeSpec() = default;
355
  MapTypeSpec(std::unique_ptr<TypeSpec> key_type,
356
              std::unique_ptr<TypeSpec> value_type);
357
358
  MapTypeSpec(const MapTypeSpec& rhs);
359
  MapTypeSpec& operator=(const MapTypeSpec& rhs);
360
0
  MapTypeSpec(MapTypeSpec&& rhs) = default;
361
0
  MapTypeSpec& operator=(MapTypeSpec&& rhs) = default;
362
363
  void set_key_type(std::unique_ptr<TypeSpec> key_type);
364
365
  void set_value_type(std::unique_ptr<TypeSpec> value_type);
366
367
0
  bool has_key_type() const { return key_type_ != nullptr; }
368
369
0
  bool has_value_type() const { return value_type_ != nullptr; }
370
371
  const TypeSpec& key_type() const;
372
373
  const TypeSpec& value_type() const;
374
375
  bool operator==(const MapTypeSpec& other) const;
376
377
  TypeSpec& mutable_key_type();
378
379
  TypeSpec& mutable_value_type();
380
381
 private:
382
  // The type of the key.
383
  std::unique_ptr<TypeSpec> key_type_;
384
385
  // The type of the value.
386
  std::unique_ptr<TypeSpec> value_type_;
387
};
388
389
// Function type specifiers with result and arg types.
390
//
391
// NOTE: function type represents a lambda-style argument to another function.
392
// Supported through macros, but not yet a first-class concept in CEL.
393
class FunctionTypeSpec {
394
 public:
395
  FunctionTypeSpec() = default;
396
  FunctionTypeSpec(std::unique_ptr<TypeSpec> result_type,
397
                   std::vector<TypeSpec> arg_types);
398
399
  FunctionTypeSpec(const FunctionTypeSpec& other);
400
  FunctionTypeSpec& operator=(const FunctionTypeSpec& other);
401
0
  FunctionTypeSpec(FunctionTypeSpec&&) = default;
402
0
  FunctionTypeSpec& operator=(FunctionTypeSpec&&) = default;
403
404
  void set_result_type(std::unique_ptr<TypeSpec> result_type);
405
406
  void set_arg_types(std::vector<TypeSpec> arg_types);
407
408
0
  bool has_result_type() const { return result_type_ != nullptr; }
409
410
  const TypeSpec& result_type() const;
411
412
  TypeSpec& mutable_result_type();
413
414
0
  const std::vector<TypeSpec>& arg_types() const { return arg_types_; }
415
416
0
  std::vector<TypeSpec>& mutable_arg_types() { return arg_types_; }
417
418
  bool operator==(const FunctionTypeSpec& other) const;
419
420
 private:
421
  // Result type of the function.
422
  std::unique_ptr<TypeSpec> result_type_;
423
424
  // Argument types of the function.
425
  std::vector<TypeSpec> arg_types_;
426
};
427
428
// Application defined abstract type.
429
//
430
// Abstract types provide a name as an identifier for the application, and
431
// optionally one or more type parameters.
432
//
433
// For cel::Type representation, see OpaqueType.
434
class AbstractType {
435
 public:
436
  AbstractType() = default;
437
  AbstractType(std::string name, std::vector<TypeSpec> parameter_types);
438
439
0
  void set_name(std::string name) { name_ = std::move(name); }
440
441
  void set_parameter_types(std::vector<TypeSpec> parameter_types);
442
443
0
  const std::string& name() const { return name_; }
444
445
0
  const std::vector<TypeSpec>& parameter_types() const {
446
0
    return parameter_types_;
447
0
  }
448
449
0
  std::vector<TypeSpec>& mutable_parameter_types() { return parameter_types_; }
450
451
  bool operator==(const AbstractType& other) const;
452
453
 private:
454
  // The fully qualified name of this abstract type.
455
  std::string name_;
456
457
  // Parameter types for this abstract type.
458
  std::vector<TypeSpec> parameter_types_;
459
};
460
461
// Wrapper of a primitive type, e.g. `google.protobuf.Int64Value`.
462
class PrimitiveTypeWrapper {
463
 public:
464
0
  explicit PrimitiveTypeWrapper(PrimitiveType type) : type_(std::move(type)) {}
465
466
0
  void set_type(PrimitiveType type) { type_ = std::move(type); }
467
468
0
  const PrimitiveType& type() const { return type_; }
469
470
0
  PrimitiveType& mutable_type() { return type_; }
471
472
0
  bool operator==(const PrimitiveTypeWrapper& other) const {
473
0
    return type_ == other.type_;
474
0
  }
475
476
 private:
477
  PrimitiveType type_;
478
};
479
480
// Protocol buffer message type specifier.
481
//
482
// The `message_type` string specifies the qualified message type name. For
483
// example, `google.plus.Profile`. This must be mapped to a google::protobuf::Descriptor
484
// for type checking.
485
class MessageTypeSpec {
486
 public:
487
  MessageTypeSpec() = default;
488
0
  explicit MessageTypeSpec(std::string type) : type_(std::move(type)) {}
489
490
0
  void set_type(std::string type) { type_ = std::move(type); }
491
492
0
  const std::string& type() const { return type_; }
493
494
0
  bool operator==(const MessageTypeSpec& other) const {
495
0
    return type_ == other.type_;
496
0
  }
497
498
 private:
499
  std::string type_;
500
};
501
502
// TypeSpec param type.
503
//
504
// The `type_param` string specifies the type parameter name, e.g. `list<E>`
505
// would be a `list_type` whose element type was a `type_param` type
506
// named `E`.
507
class ParamTypeSpec {
508
 public:
509
  ParamTypeSpec() = default;
510
0
  explicit ParamTypeSpec(std::string type) : type_(std::move(type)) {}
511
512
0
  void set_type(std::string type) { type_ = std::move(type); }
513
514
0
  const std::string& type() const { return type_; }
515
516
0
  bool operator==(const ParamTypeSpec& other) const {
517
0
    return type_ == other.type_;
518
0
  }
519
520
 private:
521
  std::string type_;
522
};
523
524
// Error type specifier.
525
//
526
// During type-checking if an expression is an error, its type is propagated
527
// as the `ERROR` type. This permits the type-checker to discover other
528
// errors present in the expression.
529
enum class ErrorTypeSpec { kValue = 0 };
530
531
using UnsetTypeSpec = absl::monostate;
532
533
struct DynTypeSpec {};
534
535
0
inline bool operator==(const DynTypeSpec&, const DynTypeSpec&) { return true; }
536
0
inline bool operator!=(const DynTypeSpec&, const DynTypeSpec&) { return false; }
537
538
struct NullTypeSpec {};
539
0
inline bool operator==(const NullTypeSpec&, const NullTypeSpec&) {
540
0
  return true;
541
0
}
542
0
inline bool operator!=(const NullTypeSpec&, const NullTypeSpec&) {
543
0
  return false;
544
0
}
545
546
using TypeSpecKind =
547
    absl::variant<UnsetTypeSpec, DynTypeSpec, NullTypeSpec, PrimitiveType,
548
                  PrimitiveTypeWrapper, WellKnownTypeSpec, ListTypeSpec,
549
                  MapTypeSpec, FunctionTypeSpec, MessageTypeSpec, ParamTypeSpec,
550
                  absl_nullable std::unique_ptr<TypeSpec>, ErrorTypeSpec,
551
                  AbstractType>;
552
553
// Analogous to cel::expr::Type.
554
// Represents a CEL type.
555
//
556
// TODO(uncreated-issue/15): align with value.proto
557
class TypeSpec {
558
 public:
559
0
  TypeSpec() = default;
560
  explicit TypeSpec(TypeSpecKind type_kind)
561
0
      : type_kind_(std::move(type_kind)) {}
562
563
  TypeSpec(const TypeSpec& other);
564
  TypeSpec& operator=(const TypeSpec& other);
565
  TypeSpec(TypeSpec&&) = default;
566
  TypeSpec& operator=(TypeSpec&&) = default;
567
568
0
  void set_type_kind(TypeSpecKind type_kind) {
569
0
    type_kind_ = std::move(type_kind);
570
0
  }
571
572
0
  const TypeSpecKind& type_kind() const { return type_kind_; }
573
574
0
  TypeSpecKind& mutable_type_kind() { return type_kind_; }
575
576
0
  bool has_dyn() const {
577
0
    return absl::holds_alternative<DynTypeSpec>(type_kind_);
578
0
  }
579
580
0
  bool has_null() const {
581
0
    return absl::holds_alternative<NullTypeSpec>(type_kind_);
582
0
  }
583
584
0
  bool has_primitive() const {
585
0
    return absl::holds_alternative<PrimitiveType>(type_kind_);
586
0
  }
587
588
0
  bool has_wrapper() const {
589
0
    return absl::holds_alternative<PrimitiveTypeWrapper>(type_kind_);
590
0
  }
591
592
0
  bool has_well_known() const {
593
0
    return absl::holds_alternative<WellKnownTypeSpec>(type_kind_);
594
0
  }
595
596
0
  bool has_list_type() const {
597
0
    return absl::holds_alternative<ListTypeSpec>(type_kind_);
598
0
  }
599
600
0
  bool has_map_type() const {
601
0
    return absl::holds_alternative<MapTypeSpec>(type_kind_);
602
0
  }
603
604
0
  bool has_function() const {
605
0
    return absl::holds_alternative<FunctionTypeSpec>(type_kind_);
606
0
  }
607
608
0
  bool has_message_type() const {
609
0
    return absl::holds_alternative<MessageTypeSpec>(type_kind_);
610
0
  }
611
612
0
  bool has_type_param() const {
613
0
    return absl::holds_alternative<ParamTypeSpec>(type_kind_);
614
0
  }
615
616
0
  bool has_type() const {
617
0
    return absl::holds_alternative<std::unique_ptr<TypeSpec>>(type_kind_);
618
0
  }
619
620
0
  bool has_error() const {
621
0
    return absl::holds_alternative<ErrorTypeSpec>(type_kind_);
622
0
  }
623
624
0
  bool has_abstract_type() const {
625
0
    return absl::holds_alternative<AbstractType>(type_kind_);
626
0
  }
627
628
0
  NullTypeSpec null() const {
629
0
    auto* value = absl::get_if<NullTypeSpec>(&type_kind_);
630
0
    if (value != nullptr) {
631
0
      return *value;
632
0
    }
633
0
    return {};
634
0
  }
635
636
0
  PrimitiveType primitive() const {
637
0
    auto* value = absl::get_if<PrimitiveType>(&type_kind_);
638
0
    if (value != nullptr) {
639
0
      return *value;
640
0
    }
641
0
    return PrimitiveType::kPrimitiveTypeUnspecified;
642
0
  }
643
644
0
  PrimitiveType wrapper() const {
645
0
    auto* value = absl::get_if<PrimitiveTypeWrapper>(&type_kind_);
646
0
    if (value != nullptr) {
647
0
      return value->type();
648
0
    }
649
0
    return PrimitiveType::kPrimitiveTypeUnspecified;
650
0
  }
651
652
0
  WellKnownTypeSpec well_known() const {
653
0
    auto* value = absl::get_if<WellKnownTypeSpec>(&type_kind_);
654
0
    if (value != nullptr) {
655
0
      return *value;
656
0
    }
657
0
    return WellKnownTypeSpec::kWellKnownTypeUnspecified;
658
0
  }
659
660
0
  const ListTypeSpec& list_type() const {
661
0
    auto* value = absl::get_if<ListTypeSpec>(&type_kind_);
662
0
    if (value != nullptr) {
663
0
      return *value;
664
0
    }
665
0
    static const ListTypeSpec* default_list_type = new ListTypeSpec();
666
0
    return *default_list_type;
667
0
  }
668
669
0
  const MapTypeSpec& map_type() const {
670
0
    auto* value = absl::get_if<MapTypeSpec>(&type_kind_);
671
0
    if (value != nullptr) {
672
0
      return *value;
673
0
    }
674
0
    static const MapTypeSpec* default_map_type = new MapTypeSpec();
675
0
    return *default_map_type;
676
0
  }
677
678
0
  const FunctionTypeSpec& function() const {
679
0
    auto* value = absl::get_if<FunctionTypeSpec>(&type_kind_);
680
0
    if (value != nullptr) {
681
0
      return *value;
682
0
    }
683
0
    static const FunctionTypeSpec* default_function_type =
684
0
        new FunctionTypeSpec();
685
0
    return *default_function_type;
686
0
  }
687
688
0
  const MessageTypeSpec& message_type() const {
689
0
    auto* value = absl::get_if<MessageTypeSpec>(&type_kind_);
690
0
    if (value != nullptr) {
691
0
      return *value;
692
0
    }
693
0
    static const MessageTypeSpec* default_message_type = new MessageTypeSpec();
694
0
    return *default_message_type;
695
0
  }
696
697
0
  const ParamTypeSpec& type_param() const {
698
0
    auto* value = absl::get_if<ParamTypeSpec>(&type_kind_);
699
0
    if (value != nullptr) {
700
0
      return *value;
701
0
    }
702
0
    static const ParamTypeSpec* default_param_type = new ParamTypeSpec();
703
0
    return *default_param_type;
704
0
  }
705
706
  const TypeSpec& type() const;
707
708
0
  ErrorTypeSpec error_type() const {
709
0
    auto* value = absl::get_if<ErrorTypeSpec>(&type_kind_);
710
0
    if (value != nullptr) {
711
0
      return *value;
712
0
    }
713
0
    return ErrorTypeSpec::kValue;
714
0
  }
715
716
0
  const AbstractType& abstract_type() const {
717
0
    auto* value = absl::get_if<AbstractType>(&type_kind_);
718
0
    if (value != nullptr) {
719
0
      return *value;
720
0
    }
721
0
    static const AbstractType* default_abstract_type = new AbstractType();
722
0
    return *default_abstract_type;
723
0
  }
724
725
0
  bool operator==(const TypeSpec& other) const {
726
0
    if (absl::holds_alternative<std::unique_ptr<TypeSpec>>(type_kind_) &&
727
0
        absl::holds_alternative<std::unique_ptr<TypeSpec>>(other.type_kind_)) {
728
0
      const auto& self_type = absl::get<std::unique_ptr<TypeSpec>>(type_kind_);
729
0
      const auto& other_type =
730
0
          absl::get<std::unique_ptr<TypeSpec>>(other.type_kind_);
731
0
      if (self_type == nullptr || other_type == nullptr) {
732
0
        return self_type == other_type;
733
0
      }
734
0
      return *self_type == *other_type;
735
0
    }
736
0
    return type_kind_ == other.type_kind_;
737
0
  }
738
739
 private:
740
  TypeSpecKind type_kind_;
741
};
742
743
// Describes a resolved reference to a declaration.
744
class Reference {
745
 public:
746
  Reference() = default;
747
748
  Reference(std::string name, std::vector<std::string> overload_id,
749
            Constant value)
750
      : name_(std::move(name)),
751
        overload_id_(std::move(overload_id)),
752
0
        value_(std::move(value)) {}
753
754
  Reference(const Reference& other) = default;
755
  Reference& operator=(const Reference& other) = default;
756
  Reference(Reference&&) = default;
757
  Reference& operator=(Reference&&) = default;
758
759
0
  void set_name(std::string name) { name_ = std::move(name); }
760
761
0
  void set_overload_id(std::vector<std::string> overload_id) {
762
0
    overload_id_ = std::move(overload_id);
763
0
  }
764
765
0
  void set_value(Constant value) { value_ = std::move(value); }
766
767
0
  const std::string& name() const { return name_; }
768
769
0
  const std::vector<std::string>& overload_id() const { return overload_id_; }
770
771
0
  const Constant& value() const {
772
0
    if (value_.has_value()) {
773
0
      return value_.value();
774
0
    }
775
0
    static const Constant* default_constant = new Constant;
776
0
    return *default_constant;
777
0
  }
778
779
0
  std::vector<std::string>& mutable_overload_id() { return overload_id_; }
780
781
0
  Constant& mutable_value() {
782
0
    if (!value_.has_value()) {
783
0
      value_.emplace();
784
0
    }
785
0
    return *value_;
786
0
  }
787
788
0
  bool has_value() const { return value_.has_value(); }
789
790
0
  bool operator==(const Reference& other) const {
791
0
    return name_ == other.name_ && overload_id_ == other.overload_id_ &&
792
0
           value() == other.value();
793
0
  }
794
795
 private:
796
  // The fully qualified name of the declaration.
797
  std::string name_;
798
  // For references to functions, this is a list of `Overload.overload_id`
799
  // values which match according to typing rules.
800
  //
801
  // If the list has more than one element, overload resolution among the
802
  // presented candidates must happen at runtime because of dynamic types. The
803
  // type checker attempts to narrow down this list as much as possible.
804
  //
805
  // Empty if this is not a reference to a [Decl.FunctionDecl][].
806
  std::vector<std::string> overload_id_;
807
  // For references to constants, this may contain the value of the
808
  // constant if known at compile time.
809
  absl::optional<Constant> value_;
810
};
811
812
////////////////////////////////////////////////////////////////////////
813
// Out-of-line method declarations
814
////////////////////////////////////////////////////////////////////////
815
816
inline ListTypeSpec::ListTypeSpec(const ListTypeSpec& rhs)
817
0
    : elem_type_(std::make_unique<TypeSpec>(rhs.elem_type())) {}
818
819
0
inline ListTypeSpec& ListTypeSpec::operator=(const ListTypeSpec& rhs) {
820
0
  elem_type_ = std::make_unique<TypeSpec>(rhs.elem_type());
821
0
  return *this;
822
0
}
823
824
inline ListTypeSpec::ListTypeSpec(std::unique_ptr<TypeSpec> elem_type)
825
    : elem_type_(std::move(elem_type)) {}
826
827
0
inline void ListTypeSpec::set_elem_type(std::unique_ptr<TypeSpec> elem_type) {
828
0
  elem_type_ = std::move(elem_type);
829
0
}
830
831
0
inline TypeSpec& ListTypeSpec::mutable_elem_type() {
832
0
  if (elem_type_ == nullptr) {
833
0
    elem_type_ = std::make_unique<TypeSpec>();
834
0
  }
835
0
  return *elem_type_;
836
0
}
837
838
inline MapTypeSpec::MapTypeSpec(std::unique_ptr<TypeSpec> key_type,
839
                                std::unique_ptr<TypeSpec> value_type)
840
    : key_type_(std::move(key_type)), value_type_(std::move(value_type)) {}
841
842
inline MapTypeSpec::MapTypeSpec(const MapTypeSpec& rhs)
843
0
    : key_type_(std::make_unique<TypeSpec>(rhs.key_type())),
844
0
      value_type_(std::make_unique<TypeSpec>(rhs.value_type())) {}
845
846
0
inline MapTypeSpec& MapTypeSpec::operator=(const MapTypeSpec& rhs) {
847
0
  key_type_ = std::make_unique<TypeSpec>(rhs.key_type());
848
0
  value_type_ = std::make_unique<TypeSpec>(rhs.value_type());
849
0
  return *this;
850
0
}
851
852
0
inline void MapTypeSpec::set_key_type(std::unique_ptr<TypeSpec> key_type) {
853
0
  key_type_ = std::move(key_type);
854
0
}
855
856
0
inline void MapTypeSpec::set_value_type(std::unique_ptr<TypeSpec> value_type) {
857
0
  value_type_ = std::move(value_type);
858
0
}
859
860
0
inline TypeSpec& MapTypeSpec::mutable_key_type() {
861
0
  if (key_type_ == nullptr) {
862
0
    key_type_ = std::make_unique<TypeSpec>();
863
0
  }
864
0
  return *key_type_;
865
0
}
866
867
0
inline TypeSpec& MapTypeSpec::mutable_value_type() {
868
0
  if (value_type_ == nullptr) {
869
0
    value_type_ = std::make_unique<TypeSpec>();
870
0
  }
871
0
  return *value_type_;
872
0
}
873
874
inline void FunctionTypeSpec::set_result_type(
875
0
    std::unique_ptr<TypeSpec> result_type) {
876
0
  result_type_ = std::move(result_type);
877
0
}
878
879
0
inline TypeSpec& FunctionTypeSpec::mutable_result_type() {
880
0
  if (result_type_ == nullptr) {
881
0
    result_type_ = std::make_unique<TypeSpec>();
882
0
  }
883
0
  return *result_type_;
884
0
}
885
886
////////////////////////////////////////////////////////////////////////
887
// Implementation details
888
////////////////////////////////////////////////////////////////////////
889
890
inline FunctionTypeSpec::FunctionTypeSpec(std::unique_ptr<TypeSpec> result_type,
891
                                          std::vector<TypeSpec> arg_types)
892
    : result_type_(std::move(result_type)), arg_types_(std::move(arg_types)) {}
893
894
0
inline void FunctionTypeSpec::set_arg_types(std::vector<TypeSpec> arg_types) {
895
0
  arg_types_ = std::move(arg_types);
896
0
}
897
898
inline AbstractType::AbstractType(std::string name,
899
                                  std::vector<TypeSpec> parameter_types)
900
    : name_(std::move(name)), parameter_types_(std::move(parameter_types)) {}
901
902
inline void AbstractType::set_parameter_types(
903
0
    std::vector<TypeSpec> parameter_types) {
904
0
  parameter_types_ = std::move(parameter_types);
905
0
}
906
907
0
inline bool AbstractType::operator==(const AbstractType& other) const {
908
0
  return name_ == other.name_ && parameter_types_ == other.parameter_types_;
909
0
}
910
911
}  // namespace cel
912
913
#endif  // THIRD_PARTY_CEL_CPP_COMMON_AST_METADATA_H_