/proc/self/cwd/parser/internal/ast_factory.cc
Line | Count | Source |
1 | | // Copyright 2026 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 "parser/internal/ast_factory.h" |
16 | | |
17 | | #include <cstddef> |
18 | | #include <cstdint> |
19 | | #include <optional> |
20 | | #include <string> |
21 | | #include <utility> |
22 | | |
23 | | #include "absl/functional/function_ref.h" |
24 | | #include "absl/status/status.h" |
25 | | #include "absl/status/statusor.h" |
26 | | #include "absl/strings/string_view.h" |
27 | | #include "common/expr.h" |
28 | | #include "internal/status_macros.h" |
29 | | #include "parser/internal/ast_factory_interface.h" |
30 | | #include "parser/macro.h" |
31 | | |
32 | | namespace cel::parser_internal { |
33 | | |
34 | 0 | ListNodeBuilder<cel::Expr>::ListNodeBuilder(int64_t id) { |
35 | 0 | expr_.set_id(id); |
36 | 0 | expr_.mutable_list_expr(); |
37 | 0 | } |
38 | | |
39 | | ListNodeBuilder<cel::Expr>& ListNodeBuilder<cel::Expr>::Add(cel::Expr element, |
40 | 0 | bool optional) { |
41 | 0 | cel::ListExpr& list_val = expr_.mutable_list_expr(); |
42 | 0 | cel::ListExprElement expr_element; |
43 | 0 | expr_element.set_expr(std::move(element)); |
44 | 0 | expr_element.set_optional(optional); |
45 | 0 | list_val.mutable_elements().push_back(std::move(expr_element)); |
46 | 0 | return *this; |
47 | 0 | } |
48 | | |
49 | 0 | cel::Expr ListNodeBuilder<cel::Expr>::Build() { return std::move(expr_); } |
50 | | |
51 | 0 | MapNodeBuilder<cel::Expr>::MapNodeBuilder(int64_t id) { |
52 | 0 | expr_.set_id(id); |
53 | 0 | expr_.mutable_map_expr(); |
54 | 0 | } |
55 | | |
56 | | MapNodeBuilder<cel::Expr>& MapNodeBuilder<cel::Expr>::Add(int64_t id, |
57 | | cel::Expr key, |
58 | | cel::Expr value, |
59 | 0 | bool optional) { |
60 | 0 | cel::MapExpr& map_val = expr_.mutable_map_expr(); |
61 | 0 | cel::MapExprEntry entry; |
62 | 0 | entry.set_id(id); |
63 | 0 | entry.set_key(std::move(key)); |
64 | 0 | entry.set_value(std::move(value)); |
65 | 0 | entry.set_optional(optional); |
66 | 0 | map_val.mutable_entries().push_back(std::move(entry)); |
67 | 0 | return *this; |
68 | 0 | } |
69 | | |
70 | 0 | cel::Expr MapNodeBuilder<cel::Expr>::Build() { return std::move(expr_); } |
71 | | |
72 | 0 | StructNodeBuilder<cel::Expr>::StructNodeBuilder(int64_t id, std::string name) { |
73 | 0 | expr_.set_id(id); |
74 | 0 | expr_.mutable_struct_expr().set_name(std::move(name)); |
75 | 0 | } |
76 | | |
77 | | StructNodeBuilder<cel::Expr>& StructNodeBuilder<cel::Expr>::Add( |
78 | 0 | int64_t id, std::string name, cel::Expr value, bool optional) { |
79 | 0 | cel::StructExpr& struct_val = expr_.mutable_struct_expr(); |
80 | 0 | cel::StructExprField field; |
81 | 0 | field.set_id(id); |
82 | 0 | field.set_name(std::move(name)); |
83 | 0 | field.set_value(std::move(value)); |
84 | 0 | field.set_optional(optional); |
85 | 0 | struct_val.mutable_fields().push_back(std::move(field)); |
86 | 0 | return *this; |
87 | 0 | } |
88 | | |
89 | 0 | cel::Expr StructNodeBuilder<cel::Expr>::Build() { return std::move(expr_); } |
90 | | |
91 | 0 | int64_t AstFactoryInterface<cel::Expr>::GetId(const cel::Expr& expr) const { |
92 | 0 | return expr.id(); |
93 | 0 | } |
94 | | |
95 | 0 | bool AstFactoryInterface<cel::Expr>::IsEmpty(const cel::Expr& expr) const { |
96 | 0 | return expr.id() == 0; |
97 | 0 | } |
98 | | |
99 | 0 | bool AstFactoryInterface<cel::Expr>::IsConst(const cel::Expr& expr) const { |
100 | 0 | return expr.has_const_expr(); |
101 | 0 | } |
102 | | |
103 | 0 | bool AstFactoryInterface<cel::Expr>::IsIdent(const cel::Expr& expr) const { |
104 | 0 | return expr.has_ident_expr(); |
105 | 0 | } |
106 | | |
107 | | absl::string_view AstFactoryInterface<cel::Expr>::GetIdentName( |
108 | 0 | const cel::Expr& expr) const { |
109 | 0 | return expr.has_ident_expr() ? absl::string_view(expr.ident_expr().name()) |
110 | 0 | : absl::string_view(); |
111 | 0 | } |
112 | | |
113 | 0 | bool AstFactoryInterface<cel::Expr>::IsSelect(const cel::Expr& expr) const { |
114 | 0 | return expr.has_select_expr(); |
115 | 0 | } |
116 | | |
117 | | bool AstFactoryInterface<cel::Expr>::IsPresenceTest( |
118 | 0 | const cel::Expr& expr) const { |
119 | 0 | return expr.has_select_expr() && expr.select_expr().test_only(); |
120 | 0 | } |
121 | | |
122 | | const cel::Expr* AstFactoryInterface<cel::Expr>::GetSelectOperand( |
123 | 0 | const cel::Expr& expr) const { |
124 | 0 | return expr.has_select_expr() ? &expr.select_expr().operand() : nullptr; |
125 | 0 | } |
126 | | |
127 | | absl::string_view AstFactoryInterface<cel::Expr>::GetSelectField( |
128 | 0 | const cel::Expr& expr) const { |
129 | 0 | return expr.has_select_expr() ? absl::string_view(expr.select_expr().field()) |
130 | 0 | : absl::string_view(); |
131 | 0 | } |
132 | | |
133 | | absl::StatusOr<cel::Expr> AstFactoryInterface<cel::Expr>::CopyAndReplace( |
134 | | const cel::Expr& expr, |
135 | | absl::FunctionRef<std::optional<cel::Expr>(const cel::Expr&)> replacer, |
136 | 0 | int max_recursion_depth) const { |
137 | 0 | if (max_recursion_depth <= 0) { |
138 | 0 | return absl::InvalidArgumentError("recursion limit exceeded"); |
139 | 0 | } |
140 | 0 | std::optional<cel::Expr> replaced = replacer(expr); |
141 | 0 | if (replaced.has_value()) { |
142 | 0 | return std::move(*replaced); |
143 | 0 | } |
144 | | |
145 | 0 | cel::Expr new_expr; |
146 | 0 | new_expr.set_id(expr.id()); |
147 | |
|
148 | 0 | switch (expr.kind_case()) { |
149 | 0 | case cel::ExprKindCase::kUnspecifiedExpr: |
150 | 0 | break; |
151 | 0 | case cel::ExprKindCase::kConstant: |
152 | 0 | new_expr.set_const_expr(expr.const_expr()); |
153 | 0 | break; |
154 | 0 | case cel::ExprKindCase::kIdentExpr: |
155 | 0 | new_expr.set_ident_expr(cel::IdentExpr(expr.ident_expr().name())); |
156 | 0 | break; |
157 | 0 | case cel::ExprKindCase::kSelectExpr: { |
158 | 0 | cel::SelectExpr& select = new_expr.mutable_select_expr(); |
159 | 0 | select.set_field(expr.select_expr().field()); |
160 | 0 | select.set_test_only(expr.select_expr().test_only()); |
161 | 0 | if (expr.select_expr().has_operand()) { |
162 | 0 | CEL_ASSIGN_OR_RETURN(cel::Expr operand, |
163 | 0 | CopyAndReplace(expr.select_expr().operand(), |
164 | 0 | replacer, max_recursion_depth - 1)); |
165 | 0 | select.set_operand(std::move(operand)); |
166 | 0 | } |
167 | 0 | break; |
168 | 0 | } |
169 | 0 | case cel::ExprKindCase::kCallExpr: { |
170 | 0 | cel::CallExpr& call = new_expr.mutable_call_expr(); |
171 | 0 | call.set_function(expr.call_expr().function()); |
172 | 0 | if (expr.call_expr().has_target()) { |
173 | 0 | CEL_ASSIGN_OR_RETURN(cel::Expr target, |
174 | 0 | CopyAndReplace(expr.call_expr().target(), replacer, |
175 | 0 | max_recursion_depth - 1)); |
176 | 0 | call.set_target(std::move(target)); |
177 | 0 | } |
178 | 0 | call.mutable_args().reserve(expr.call_expr().args().size()); |
179 | 0 | for (const auto& arg : expr.call_expr().args()) { |
180 | 0 | CEL_ASSIGN_OR_RETURN( |
181 | 0 | cel::Expr new_arg, |
182 | 0 | CopyAndReplace(arg, replacer, max_recursion_depth - 1)); |
183 | 0 | call.mutable_args().push_back(std::move(new_arg)); |
184 | 0 | } |
185 | 0 | break; |
186 | 0 | } |
187 | 0 | case cel::ExprKindCase::kListExpr: { |
188 | 0 | cel::ListExpr& list = new_expr.mutable_list_expr(); |
189 | 0 | list.mutable_elements().reserve(expr.list_expr().elements().size()); |
190 | 0 | for (const auto& elem : expr.list_expr().elements()) { |
191 | 0 | cel::ListExprElement new_elem; |
192 | 0 | new_elem.set_optional(elem.optional()); |
193 | 0 | if (elem.has_expr()) { |
194 | 0 | CEL_ASSIGN_OR_RETURN( |
195 | 0 | cel::Expr new_child, |
196 | 0 | CopyAndReplace(elem.expr(), replacer, max_recursion_depth - 1)); |
197 | 0 | new_elem.set_expr(std::move(new_child)); |
198 | 0 | } |
199 | 0 | list.mutable_elements().push_back(std::move(new_elem)); |
200 | 0 | } |
201 | 0 | break; |
202 | 0 | } |
203 | 0 | case cel::ExprKindCase::kStructExpr: { |
204 | 0 | cel::StructExpr& str = new_expr.mutable_struct_expr(); |
205 | 0 | str.set_name(expr.struct_expr().name()); |
206 | 0 | str.mutable_fields().reserve(expr.struct_expr().fields().size()); |
207 | 0 | for (const auto& field : expr.struct_expr().fields()) { |
208 | 0 | cel::StructExprField new_field; |
209 | 0 | new_field.set_id(field.id()); |
210 | 0 | new_field.set_name(field.name()); |
211 | 0 | new_field.set_optional(field.optional()); |
212 | 0 | if (field.has_value()) { |
213 | 0 | CEL_ASSIGN_OR_RETURN( |
214 | 0 | cel::Expr new_val, |
215 | 0 | CopyAndReplace(field.value(), replacer, max_recursion_depth - 1)); |
216 | 0 | new_field.set_value(std::move(new_val)); |
217 | 0 | } |
218 | 0 | str.mutable_fields().push_back(std::move(new_field)); |
219 | 0 | } |
220 | 0 | break; |
221 | 0 | } |
222 | 0 | case cel::ExprKindCase::kMapExpr: { |
223 | 0 | cel::MapExpr& map = new_expr.mutable_map_expr(); |
224 | 0 | map.mutable_entries().reserve(expr.map_expr().entries().size()); |
225 | 0 | for (const auto& entry : expr.map_expr().entries()) { |
226 | 0 | cel::MapExprEntry new_entry; |
227 | 0 | new_entry.set_id(entry.id()); |
228 | 0 | new_entry.set_optional(entry.optional()); |
229 | 0 | if (entry.has_key()) { |
230 | 0 | CEL_ASSIGN_OR_RETURN( |
231 | 0 | cel::Expr new_key, |
232 | 0 | CopyAndReplace(entry.key(), replacer, max_recursion_depth - 1)); |
233 | 0 | new_entry.set_key(std::move(new_key)); |
234 | 0 | } |
235 | 0 | if (entry.has_value()) { |
236 | 0 | CEL_ASSIGN_OR_RETURN( |
237 | 0 | cel::Expr new_val, |
238 | 0 | CopyAndReplace(entry.value(), replacer, max_recursion_depth - 1)); |
239 | 0 | new_entry.set_value(std::move(new_val)); |
240 | 0 | } |
241 | 0 | map.mutable_entries().push_back(std::move(new_entry)); |
242 | 0 | } |
243 | 0 | break; |
244 | 0 | } |
245 | 0 | case cel::ExprKindCase::kComprehensionExpr: { |
246 | 0 | cel::ComprehensionExpr& comp = new_expr.mutable_comprehension_expr(); |
247 | 0 | comp.set_iter_var(expr.comprehension_expr().iter_var()); |
248 | 0 | comp.set_iter_var2(expr.comprehension_expr().iter_var2()); |
249 | 0 | comp.set_accu_var(expr.comprehension_expr().accu_var()); |
250 | 0 | if (expr.comprehension_expr().has_accu_init()) { |
251 | 0 | CEL_ASSIGN_OR_RETURN( |
252 | 0 | cel::Expr new_accu_init, |
253 | 0 | CopyAndReplace(expr.comprehension_expr().accu_init(), replacer, |
254 | 0 | max_recursion_depth - 1)); |
255 | 0 | comp.set_accu_init(std::move(new_accu_init)); |
256 | 0 | } |
257 | 0 | if (expr.comprehension_expr().has_iter_range()) { |
258 | 0 | CEL_ASSIGN_OR_RETURN( |
259 | 0 | cel::Expr new_iter_range, |
260 | 0 | CopyAndReplace(expr.comprehension_expr().iter_range(), replacer, |
261 | 0 | max_recursion_depth - 1)); |
262 | 0 | comp.set_iter_range(std::move(new_iter_range)); |
263 | 0 | } |
264 | 0 | if (expr.comprehension_expr().has_loop_condition()) { |
265 | 0 | CEL_ASSIGN_OR_RETURN( |
266 | 0 | cel::Expr new_loop_condition, |
267 | 0 | CopyAndReplace(expr.comprehension_expr().loop_condition(), replacer, |
268 | 0 | max_recursion_depth - 1)); |
269 | 0 | comp.set_loop_condition(std::move(new_loop_condition)); |
270 | 0 | } |
271 | 0 | if (expr.comprehension_expr().has_loop_step()) { |
272 | 0 | CEL_ASSIGN_OR_RETURN( |
273 | 0 | cel::Expr new_loop_step, |
274 | 0 | CopyAndReplace(expr.comprehension_expr().loop_step(), replacer, |
275 | 0 | max_recursion_depth - 1)); |
276 | 0 | comp.set_loop_step(std::move(new_loop_step)); |
277 | 0 | } |
278 | 0 | if (expr.comprehension_expr().has_result()) { |
279 | 0 | CEL_ASSIGN_OR_RETURN(cel::Expr new_result, |
280 | 0 | CopyAndReplace(expr.comprehension_expr().result(), |
281 | 0 | replacer, max_recursion_depth - 1)); |
282 | 0 | comp.set_result(std::move(new_result)); |
283 | 0 | } |
284 | 0 | break; |
285 | 0 | } |
286 | 0 | } |
287 | 0 | return new_expr; |
288 | 0 | } |
289 | | |
290 | | ListNodeBuilder<cel::Expr> AstFactoryInterface<cel::Expr>::NewListBuilder( |
291 | 0 | int64_t id) { |
292 | 0 | return ListNodeBuilder<cel::Expr>(id); |
293 | 0 | } |
294 | | |
295 | | StructNodeBuilder<cel::Expr> AstFactoryInterface<cel::Expr>::NewStructBuilder( |
296 | 0 | int64_t id, std::string name) { |
297 | 0 | return StructNodeBuilder<cel::Expr>(id, std::move(name)); |
298 | 0 | } |
299 | | |
300 | | MapNodeBuilder<cel::Expr> AstFactoryInterface<cel::Expr>::NewMapBuilder( |
301 | 0 | int64_t id) { |
302 | 0 | return MapNodeBuilder<cel::Expr>(id); |
303 | 0 | } |
304 | | |
305 | | std::optional<MacroExprExpander<cel::Expr>> |
306 | | AstFactoryInterface<cel::Expr>::NewMacroExprExpander(std::string_view name, |
307 | | size_t arg_count, |
308 | 0 | bool receiver_style) { |
309 | 0 | if (macro_registry_ == nullptr) { |
310 | 0 | return std::nullopt; |
311 | 0 | } |
312 | 0 | std::optional<cel::Macro> macro = |
313 | 0 | macro_registry_->FindMacro(name, arg_count, receiver_style); |
314 | 0 | if (!macro) { |
315 | 0 | return std::nullopt; |
316 | 0 | } |
317 | 0 | return std::optional<MacroExprExpander<cel::Expr>>(std::in_place, *macro); |
318 | 0 | } |
319 | | |
320 | | } // namespace cel::parser_internal |