/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_ |