Coverage Report

Created: 2026-04-21 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/ast.h
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
#ifndef THIRD_PARTY_CEL_CPP_COMMON_AST_H_
16
#define THIRD_PARTY_CEL_CPP_COMMON_AST_H_
17
18
#include <cstdint>
19
#include <string>
20
#include <utility>
21
22
#include "absl/base/nullability.h"
23
#include "absl/container/flat_hash_map.h"
24
#include "absl/strings/string_view.h"
25
#include "common/ast/metadata.h"  // IWYU pragma: export
26
#include "common/expr.h"
27
#include "common/source.h"
28
29
namespace cel {
30
31
// In memory representation of a CEL abstract syntax tree.
32
//
33
// If AST inspection or manipulation is needed, prefer to use an existing tool
34
// or traverse the protobuf representation rather than directly manipulating
35
// through this class. See `cel::NavigableAst` and `cel::AstTraverse`.
36
//
37
// Type and reference maps are only populated if the AST is checked. Any changes
38
// to the AST are not automatically reflected in the type or reference maps.
39
//
40
// To create a new instance from a protobuf representation, use the conversion
41
// utilities in `common/ast_proto.h`.
42
class Ast final {
43
 public:
44
  using ReferenceMap = absl::flat_hash_map<int64_t, Reference>;
45
  using TypeMap = absl::flat_hash_map<int64_t, TypeSpec>;
46
47
0
  Ast() : is_checked_(false) {}
48
49
  Ast(Expr expr, SourceInfo source_info)
50
0
      : root_expr_(std::move(expr)),
51
0
        source_info_(std::move(source_info)),
52
0
        is_checked_(false) {}
53
54
  Ast(Expr expr, SourceInfo source_info, ReferenceMap reference_map,
55
      TypeMap type_map, std::string expr_version)
56
      : root_expr_(std::move(expr)),
57
        source_info_(std::move(source_info)),
58
        reference_map_(std::move(reference_map)),
59
        type_map_(std::move(type_map)),
60
        expr_version_(std::move(expr_version)),
61
0
        is_checked_(true) {}
62
63
  Ast(const Ast& other) = default;
64
  Ast& operator=(const Ast& other) = default;
65
  Ast(Ast&& other) = default;
66
  Ast& operator=(Ast&& other) = default;
67
68
  // Deprecated. Use `is_checked()` instead.
69
0
  bool IsChecked() const { return is_checked_; }
70
71
0
  bool is_checked() const { return is_checked_; }
72
0
  void set_is_checked(bool is_checked) { is_checked_ = is_checked; }
73
74
  // The root expression of the AST.
75
  //
76
  // This is the entry point for evaluation and determines the overall result
77
  // of the expression given a context.
78
0
  const Expr& root_expr() const { return root_expr_; }
79
0
  Expr& mutable_root_expr() { return root_expr_; }
80
81
  // Metadata about the source expression.
82
0
  const SourceInfo& source_info() const { return source_info_; }
83
0
  SourceInfo& mutable_source_info() { return source_info_; }
84
85
  // Returns the type of the expression with the given `expr_id`.
86
  //
87
  // Returns `nullptr` if the expression node is not found or has dynamic type.
88
  const TypeSpec* absl_nullable GetType(int64_t expr_id) const;
89
  const TypeSpec& GetTypeOrDyn(int64_t expr_id) const;
90
  const TypeSpec& GetReturnType() const;
91
92
  // Returns the resolved reference for the expression with the given `expr_id`.
93
  //
94
  // Returns `nullptr` if the expression node is not found or no reference was
95
  // resolved.
96
  const Reference* absl_nullable GetReference(int64_t expr_id) const;
97
98
  // A map from expression ids to resolved references.
99
  //
100
  // The following entries are in this table:
101
  //
102
  // - An Ident or Select expression is represented here if it resolves to a
103
  //   declaration. For instance, if `a.b.c` is represented by
104
  //   `select(select(id(a), b), c)`, and `a.b` resolves to a declaration,
105
  //   while `c` is a field selection, then the reference is attached to the
106
  //   nested select expression (but not to the id or or the outer select).
107
  //   In turn, if `a` resolves to a declaration and `b.c` are field selections,
108
  //   the reference is attached to the ident expression.
109
  // - Every Call expression has an entry here, identifying the function being
110
  //   called.
111
  // - Every CreateStruct expression for a message has an entry, identifying
112
  //   the message.
113
  //
114
  // Unpopulated if the AST is not checked.
115
0
  const ReferenceMap& reference_map() const { return reference_map_; }
116
0
  ReferenceMap& mutable_reference_map() { return reference_map_; }
117
118
  // A map from expression ids to types.
119
  //
120
  // Every expression node which has a type different than DYN has a mapping
121
  // here. If an expression has type DYN, it is omitted from this map to save
122
  // space.
123
  //
124
  // Unpopulated if the AST is not checked.
125
0
  const TypeMap& type_map() const { return type_map_; }
126
0
  TypeMap& mutable_type_map() { return type_map_; }
127
128
  // The expr version indicates the major / minor version number of the `expr`
129
  // representation.
130
  //
131
  // The most common reason for a version change will be to indicate to the CEL
132
  // runtimes that transformations have been performed on the expr during static
133
  // analysis.
134
0
  absl::string_view expr_version() const { return expr_version_; }
135
0
  void set_expr_version(absl::string_view expr_version) {
136
0
    expr_version_ = expr_version;
137
0
  }
138
139
  // Computes the source location (line and column) for the given expression ID
140
  // from the source info (which stores absolute positions).
141
  //
142
  // Returns a default (empty) source location if the expression ID is not found
143
  // or the source info is not populated correctly.
144
  SourceLocation ComputeSourceLocation(int64_t expr_id) const;
145
146
 private:
147
  Expr root_expr_;
148
  SourceInfo source_info_;
149
  ReferenceMap reference_map_;
150
  TypeMap type_map_;
151
  std::string expr_version_;
152
  bool is_checked_;
153
};
154
155
}  // namespace cel
156
157
#endif  // THIRD_PARTY_CEL_CPP_COMMON_AST_H_