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