/proc/self/cwd/common/ast/expr_proto.cc
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 | | #include "common/ast/expr_proto.h" |
16 | | |
17 | | #include <algorithm> |
18 | | #include <cstddef> |
19 | | #include <cstdint> |
20 | | #include <stack> |
21 | | #include <vector> |
22 | | |
23 | | #include "cel/expr/syntax.pb.h" |
24 | | #include "google/protobuf/struct.pb.h" |
25 | | #include "absl/base/attributes.h" |
26 | | #include "absl/base/nullability.h" |
27 | | #include "absl/functional/overload.h" |
28 | | #include "absl/status/status.h" |
29 | | #include "absl/strings/str_cat.h" |
30 | | #include "absl/types/variant.h" |
31 | | #include "common/ast/constant_proto.h" |
32 | | #include "common/constant.h" |
33 | | #include "common/expr.h" |
34 | | #include "internal/status_macros.h" |
35 | | |
36 | | namespace cel::ast_internal { |
37 | | |
38 | | namespace { |
39 | | |
40 | | using ExprProto = cel::expr::Expr; |
41 | | using ConstantProto = cel::expr::Constant; |
42 | | using StructExprProto = cel::expr::Expr::CreateStruct; |
43 | | |
44 | | class ExprToProtoState final { |
45 | | private: |
46 | | struct Frame final { |
47 | | const Expr* absl_nonnull expr; |
48 | | cel::expr::Expr* absl_nonnull proto; |
49 | | }; |
50 | | |
51 | | public: |
52 | | absl::Status ExprToProto(const Expr& expr, |
53 | 12.4k | cel::expr::Expr* absl_nonnull proto) { |
54 | 12.4k | Push(expr, proto); |
55 | 12.4k | Frame frame; |
56 | 3.14M | while (Pop(frame)) { |
57 | 3.13M | CEL_RETURN_IF_ERROR(ExprToProtoImpl(*frame.expr, frame.proto)); |
58 | 3.13M | } |
59 | 12.4k | return absl::OkStatus(); |
60 | 12.4k | } |
61 | | |
62 | | private: |
63 | | absl::Status ExprToProtoImpl(const Expr& expr, |
64 | 3.13M | cel::expr::Expr* absl_nonnull proto) { |
65 | 3.13M | return absl::visit( |
66 | 3.13M | absl::Overload( |
67 | 3.13M | [&expr, proto](const UnspecifiedExpr&) -> absl::Status { |
68 | 0 | proto->Clear(); |
69 | 0 | proto->set_id(expr.id()); |
70 | 0 | return absl::OkStatus(); |
71 | 0 | }, |
72 | 3.13M | [this, &expr, proto](const Constant& const_expr) -> absl::Status { |
73 | 422k | return ConstExprToProto(expr, const_expr, proto); |
74 | 422k | }, |
75 | 3.13M | [this, &expr, proto](const IdentExpr& ident_expr) -> absl::Status { |
76 | 1.24M | return IdentExprToProto(expr, ident_expr, proto); |
77 | 1.24M | }, |
78 | 3.13M | [this, &expr, |
79 | 3.13M | proto](const SelectExpr& select_expr) -> absl::Status { |
80 | 14.8k | return SelectExprToProto(expr, select_expr, proto); |
81 | 14.8k | }, |
82 | 3.13M | [this, &expr, proto](const CallExpr& call_expr) -> absl::Status { |
83 | 1.40M | return CallExprToProto(expr, call_expr, proto); |
84 | 1.40M | }, |
85 | 3.13M | [this, &expr, proto](const ListExpr& list_expr) -> absl::Status { |
86 | 24.5k | return ListExprToProto(expr, list_expr, proto); |
87 | 24.5k | }, |
88 | 3.13M | [this, &expr, |
89 | 3.13M | proto](const StructExpr& struct_expr) -> absl::Status { |
90 | 2.41k | return StructExprToProto(expr, struct_expr, proto); |
91 | 2.41k | }, |
92 | 3.13M | [this, &expr, proto](const MapExpr& map_expr) -> absl::Status { |
93 | 8.21k | return MapExprToProto(expr, map_expr, proto); |
94 | 8.21k | }, |
95 | 3.13M | [this, &expr, proto]( |
96 | 3.13M | const ComprehensionExpr& comprehension_expr) -> absl::Status { |
97 | 5.44k | return ComprehensionExprToProto(expr, comprehension_expr, proto); |
98 | 5.44k | }), |
99 | 3.13M | expr.kind()); |
100 | 3.13M | } |
101 | | |
102 | | absl::Status ConstExprToProto(const Expr& expr, const Constant& const_expr, |
103 | 422k | ExprProto* absl_nonnull proto) { |
104 | 422k | proto->Clear(); |
105 | 422k | proto->set_id(expr.id()); |
106 | 422k | return ConstantToProto(const_expr, proto->mutable_const_expr()); |
107 | 422k | } |
108 | | |
109 | | absl::Status IdentExprToProto(const Expr& expr, const IdentExpr& ident_expr, |
110 | 1.24M | ExprProto* absl_nonnull proto) { |
111 | 1.24M | proto->Clear(); |
112 | 1.24M | auto* ident_proto = proto->mutable_ident_expr(); |
113 | 1.24M | proto->set_id(expr.id()); |
114 | 1.24M | ident_proto->set_name(ident_expr.name()); |
115 | 1.24M | return absl::OkStatus(); |
116 | 1.24M | } |
117 | | |
118 | | absl::Status SelectExprToProto(const Expr& expr, |
119 | | const SelectExpr& select_expr, |
120 | 14.8k | ExprProto* absl_nonnull proto) { |
121 | 14.8k | proto->Clear(); |
122 | 14.8k | auto* select_proto = proto->mutable_select_expr(); |
123 | 14.8k | proto->set_id(expr.id()); |
124 | 14.8k | if (select_expr.has_operand()) { |
125 | 14.8k | Push(select_expr.operand(), select_proto->mutable_operand()); |
126 | 14.8k | } |
127 | 14.8k | select_proto->set_field(select_expr.field()); |
128 | 14.8k | select_proto->set_test_only(select_expr.test_only()); |
129 | 14.8k | return absl::OkStatus(); |
130 | 14.8k | } |
131 | | |
132 | | absl::Status CallExprToProto(const Expr& expr, const CallExpr& call_expr, |
133 | 1.40M | ExprProto* absl_nonnull proto) { |
134 | 1.40M | proto->Clear(); |
135 | 1.40M | auto* call_proto = proto->mutable_call_expr(); |
136 | 1.40M | proto->set_id(expr.id()); |
137 | 1.40M | if (call_expr.has_target()) { |
138 | 3.09k | Push(call_expr.target(), call_proto->mutable_target()); |
139 | 3.09k | } |
140 | 1.40M | call_proto->set_function(call_expr.function()); |
141 | 1.40M | if (!call_expr.args().empty()) { |
142 | 1.40M | call_proto->mutable_args()->Reserve( |
143 | 1.40M | static_cast<int>(call_expr.args().size())); |
144 | 2.70M | for (const auto& argument : call_expr.args()) { |
145 | 2.70M | Push(argument, call_proto->add_args()); |
146 | 2.70M | } |
147 | 1.40M | } |
148 | 1.40M | return absl::OkStatus(); |
149 | 1.40M | } |
150 | | |
151 | | absl::Status ListExprToProto(const Expr& expr, const ListExpr& list_expr, |
152 | 24.5k | ExprProto* absl_nonnull proto) { |
153 | 24.5k | proto->Clear(); |
154 | 24.5k | auto* list_proto = proto->mutable_list_expr(); |
155 | 24.5k | proto->set_id(expr.id()); |
156 | 24.5k | if (!list_expr.elements().empty()) { |
157 | 17.1k | list_proto->mutable_elements()->Reserve( |
158 | 17.1k | static_cast<int>(list_expr.elements().size())); |
159 | 95.7k | for (size_t i = 0; i < list_expr.elements().size(); ++i) { |
160 | 78.5k | const auto& element_expr = list_expr.elements()[i]; |
161 | 78.5k | auto* element_proto = list_proto->add_elements(); |
162 | 78.5k | if (element_expr.has_expr()) { |
163 | 78.5k | Push(element_expr.expr(), element_proto); |
164 | 78.5k | } |
165 | 78.5k | if (element_expr.optional()) { |
166 | 0 | list_proto->add_optional_indices(static_cast<int32_t>(i)); |
167 | 0 | } |
168 | 78.5k | } |
169 | 17.1k | } |
170 | 24.5k | return absl::OkStatus(); |
171 | 24.5k | } |
172 | | |
173 | | absl::Status StructExprToProto(const Expr& expr, |
174 | | const StructExpr& struct_expr, |
175 | 2.41k | ExprProto* absl_nonnull proto) { |
176 | 2.41k | proto->Clear(); |
177 | 2.41k | auto* struct_proto = proto->mutable_struct_expr(); |
178 | 2.41k | proto->set_id(expr.id()); |
179 | 2.41k | struct_proto->set_message_name(struct_expr.name()); |
180 | 2.41k | if (!struct_expr.fields().empty()) { |
181 | 177 | struct_proto->mutable_entries()->Reserve( |
182 | 177 | static_cast<int>(struct_expr.fields().size())); |
183 | 4.69k | for (const auto& field_expr : struct_expr.fields()) { |
184 | 4.69k | auto* field_proto = struct_proto->add_entries(); |
185 | 4.69k | field_proto->set_id(field_expr.id()); |
186 | 4.69k | field_proto->set_field_key(field_expr.name()); |
187 | 4.69k | if (field_expr.has_value()) { |
188 | 4.69k | Push(field_expr.value(), field_proto->mutable_value()); |
189 | 4.69k | } |
190 | 4.69k | if (field_expr.optional()) { |
191 | 0 | field_proto->set_optional_entry(true); |
192 | 0 | } |
193 | 4.69k | } |
194 | 177 | } |
195 | 2.41k | return absl::OkStatus(); |
196 | 2.41k | } |
197 | | |
198 | | absl::Status MapExprToProto(const Expr& expr, const MapExpr& map_expr, |
199 | 8.21k | ExprProto* absl_nonnull proto) { |
200 | 8.21k | proto->Clear(); |
201 | 8.21k | auto* map_proto = proto->mutable_struct_expr(); |
202 | 8.21k | proto->set_id(expr.id()); |
203 | 8.21k | if (!map_expr.entries().empty()) { |
204 | 3.55k | map_proto->mutable_entries()->Reserve( |
205 | 3.55k | static_cast<int>(map_expr.entries().size())); |
206 | 143k | for (const auto& entry_expr : map_expr.entries()) { |
207 | 143k | auto* entry_proto = map_proto->add_entries(); |
208 | 143k | entry_proto->set_id(entry_expr.id()); |
209 | 143k | if (entry_expr.has_key()) { |
210 | 143k | Push(entry_expr.key(), entry_proto->mutable_map_key()); |
211 | 143k | } |
212 | 143k | if (entry_expr.has_value()) { |
213 | 143k | Push(entry_expr.value(), entry_proto->mutable_value()); |
214 | 143k | } |
215 | 143k | if (entry_expr.optional()) { |
216 | 0 | entry_proto->set_optional_entry(true); |
217 | 0 | } |
218 | 143k | } |
219 | 3.55k | } |
220 | 8.21k | return absl::OkStatus(); |
221 | 8.21k | } |
222 | | |
223 | | absl::Status ComprehensionExprToProto( |
224 | | const Expr& expr, const ComprehensionExpr& comprehension_expr, |
225 | 5.44k | ExprProto* absl_nonnull proto) { |
226 | 5.44k | proto->Clear(); |
227 | 5.44k | auto* comprehension_proto = proto->mutable_comprehension_expr(); |
228 | 5.44k | proto->set_id(expr.id()); |
229 | 5.44k | comprehension_proto->set_iter_var(comprehension_expr.iter_var()); |
230 | 5.44k | comprehension_proto->set_iter_var2(comprehension_expr.iter_var2()); |
231 | 5.44k | if (comprehension_expr.has_iter_range()) { |
232 | 5.44k | Push(comprehension_expr.iter_range(), |
233 | 5.44k | comprehension_proto->mutable_iter_range()); |
234 | 5.44k | } |
235 | 5.44k | comprehension_proto->set_accu_var(comprehension_expr.accu_var()); |
236 | 5.44k | if (comprehension_expr.has_accu_init()) { |
237 | 5.44k | Push(comprehension_expr.accu_init(), |
238 | 5.44k | comprehension_proto->mutable_accu_init()); |
239 | 5.44k | } |
240 | 5.44k | if (comprehension_expr.has_loop_condition()) { |
241 | 5.44k | Push(comprehension_expr.loop_condition(), |
242 | 5.44k | comprehension_proto->mutable_loop_condition()); |
243 | 5.44k | } |
244 | 5.44k | if (comprehension_expr.has_loop_step()) { |
245 | 5.44k | Push(comprehension_expr.loop_step(), |
246 | 5.44k | comprehension_proto->mutable_loop_step()); |
247 | 5.44k | } |
248 | 5.44k | if (comprehension_expr.has_result()) { |
249 | 5.44k | Push(comprehension_expr.result(), comprehension_proto->mutable_result()); |
250 | 5.44k | } |
251 | 5.44k | return absl::OkStatus(); |
252 | 5.44k | } |
253 | | |
254 | 3.13M | void Push(const Expr& expr, ExprProto* absl_nonnull proto) { |
255 | 3.13M | frames_.push(Frame{&expr, proto}); |
256 | 3.13M | } |
257 | | |
258 | 3.14M | bool Pop(Frame& frame) { |
259 | 3.14M | if (frames_.empty()) { |
260 | 12.4k | return false; |
261 | 12.4k | } |
262 | 3.13M | frame = frames_.top(); |
263 | 3.13M | frames_.pop(); |
264 | 3.13M | return true; |
265 | 3.14M | } |
266 | | |
267 | | std::stack<Frame, std::vector<Frame>> frames_; |
268 | | }; |
269 | | |
270 | | class ExprFromProtoState final { |
271 | | private: |
272 | | struct Frame final { |
273 | | const ExprProto* absl_nonnull proto; |
274 | | Expr* absl_nonnull expr; |
275 | | }; |
276 | | |
277 | | public: |
278 | 10.7k | absl::Status ExprFromProto(const ExprProto& proto, Expr& expr) { |
279 | 10.7k | Push(proto, expr); |
280 | 10.7k | Frame frame; |
281 | 361k | while (Pop(frame)) { |
282 | 350k | CEL_RETURN_IF_ERROR(ExprFromProtoImpl(*frame.proto, *frame.expr)); |
283 | 350k | } |
284 | 10.7k | return absl::OkStatus(); |
285 | 10.7k | } |
286 | | |
287 | | private: |
288 | 350k | absl::Status ExprFromProtoImpl(const ExprProto& proto, Expr& expr) { |
289 | 350k | switch (proto.expr_kind_case()) { |
290 | 0 | case ExprProto::EXPR_KIND_NOT_SET: |
291 | 0 | expr.Clear(); |
292 | 0 | expr.set_id(proto.id()); |
293 | 0 | return absl::OkStatus(); |
294 | 125k | case ExprProto::kConstExpr: |
295 | 125k | return ConstExprFromProto(proto, proto.const_expr(), expr); |
296 | 60.5k | case ExprProto::kIdentExpr: |
297 | 60.5k | return IdentExprFromProto(proto, proto.ident_expr(), expr); |
298 | 11.7k | case ExprProto::kSelectExpr: |
299 | 11.7k | return SelectExprFromProto(proto, proto.select_expr(), expr); |
300 | 120k | case ExprProto::kCallExpr: |
301 | 120k | return CallExprFromProto(proto, proto.call_expr(), expr); |
302 | 20.2k | case ExprProto::kListExpr: |
303 | 20.2k | return ListExprFromProto(proto, proto.list_expr(), expr); |
304 | 7.93k | case ExprProto::kStructExpr: |
305 | 7.93k | if (proto.struct_expr().message_name().empty()) { |
306 | 6.03k | return MapExprFromProto(proto, proto.struct_expr(), expr); |
307 | 6.03k | } |
308 | 1.90k | return StructExprFromProto(proto, proto.struct_expr(), expr); |
309 | 4.52k | case ExprProto::kComprehensionExpr: |
310 | 4.52k | return ComprehensionExprFromProto(proto, proto.comprehension_expr(), |
311 | 4.52k | expr); |
312 | 0 | default: |
313 | 0 | return absl::InvalidArgumentError( |
314 | 0 | absl::StrCat("unexpected ExprKindCase: ", |
315 | 0 | static_cast<int>(proto.expr_kind_case()))); |
316 | 350k | } |
317 | 350k | } |
318 | | |
319 | | absl::Status ConstExprFromProto(const ExprProto& proto, |
320 | | const ConstantProto& const_proto, |
321 | 125k | Expr& expr) { |
322 | 125k | expr.Clear(); |
323 | 125k | expr.set_id(proto.id()); |
324 | 125k | return ConstantFromProto(const_proto, expr.mutable_const_expr()); |
325 | 125k | } |
326 | | |
327 | | absl::Status IdentExprFromProto(const ExprProto& proto, |
328 | | const ExprProto::Ident& ident_proto, |
329 | 60.5k | Expr& expr) { |
330 | 60.5k | expr.Clear(); |
331 | 60.5k | expr.set_id(proto.id()); |
332 | 60.5k | auto& ident_expr = expr.mutable_ident_expr(); |
333 | 60.5k | ident_expr.set_name(ident_proto.name()); |
334 | 60.5k | return absl::OkStatus(); |
335 | 60.5k | } |
336 | | |
337 | | absl::Status SelectExprFromProto(const ExprProto& proto, |
338 | | const ExprProto::Select& select_proto, |
339 | 11.7k | Expr& expr) { |
340 | 11.7k | expr.Clear(); |
341 | 11.7k | expr.set_id(proto.id()); |
342 | 11.7k | auto& select_expr = expr.mutable_select_expr(); |
343 | 11.7k | if (select_proto.has_operand()) { |
344 | 11.7k | Push(select_proto.operand(), select_expr.mutable_operand()); |
345 | 11.7k | } |
346 | 11.7k | select_expr.set_field(select_proto.field()); |
347 | 11.7k | select_expr.set_test_only(select_proto.test_only()); |
348 | 11.7k | return absl::OkStatus(); |
349 | 11.7k | } |
350 | | |
351 | | absl::Status CallExprFromProto(const ExprProto& proto, |
352 | | const ExprProto::Call& call_proto, |
353 | 120k | Expr& expr) { |
354 | 120k | expr.Clear(); |
355 | 120k | expr.set_id(proto.id()); |
356 | 120k | auto& call_expr = expr.mutable_call_expr(); |
357 | 120k | call_expr.set_function(call_proto.function()); |
358 | 120k | if (call_proto.has_target()) { |
359 | 962 | Push(call_proto.target(), call_expr.mutable_target()); |
360 | 962 | } |
361 | 120k | call_expr.mutable_args().reserve( |
362 | 120k | static_cast<size_t>(call_proto.args().size())); |
363 | 226k | for (const auto& argument_proto : call_proto.args()) { |
364 | 226k | Push(argument_proto, call_expr.add_args()); |
365 | 226k | } |
366 | 120k | return absl::OkStatus(); |
367 | 120k | } |
368 | | |
369 | | absl::Status ListExprFromProto(const ExprProto& proto, |
370 | | const ExprProto::CreateList& list_proto, |
371 | 20.2k | Expr& expr) { |
372 | 20.2k | expr.Clear(); |
373 | 20.2k | expr.set_id(proto.id()); |
374 | 20.2k | auto& list_expr = expr.mutable_list_expr(); |
375 | 20.2k | list_expr.mutable_elements().reserve( |
376 | 20.2k | static_cast<size_t>(list_proto.elements().size())); |
377 | 88.9k | for (int i = 0; i < list_proto.elements().size(); ++i) { |
378 | 68.6k | const auto& element_proto = list_proto.elements()[i]; |
379 | 68.6k | auto& element_expr = list_expr.add_elements(); |
380 | 68.6k | Push(element_proto, element_expr.mutable_expr()); |
381 | 68.6k | const auto& optional_indicies_proto = list_proto.optional_indices(); |
382 | 68.6k | element_expr.set_optional(std::find(optional_indicies_proto.begin(), |
383 | 68.6k | optional_indicies_proto.end(), |
384 | 68.6k | i) != optional_indicies_proto.end()); |
385 | 68.6k | } |
386 | 20.2k | return absl::OkStatus(); |
387 | 20.2k | } |
388 | | |
389 | | absl::Status StructExprFromProto(const ExprProto& proto, |
390 | | const StructExprProto& struct_proto, |
391 | 1.90k | Expr& expr) { |
392 | 1.90k | expr.Clear(); |
393 | 1.90k | expr.set_id(proto.id()); |
394 | 1.90k | auto& struct_expr = expr.mutable_struct_expr(); |
395 | 1.90k | struct_expr.set_name(struct_proto.message_name()); |
396 | 1.90k | struct_expr.mutable_fields().reserve( |
397 | 1.90k | static_cast<size_t>(struct_proto.entries().size())); |
398 | 1.90k | for (const auto& field_proto : struct_proto.entries()) { |
399 | 695 | switch (field_proto.key_kind_case()) { |
400 | 0 | case StructExprProto::Entry::KEY_KIND_NOT_SET: |
401 | 0 | ABSL_FALLTHROUGH_INTENDED; |
402 | 695 | case StructExprProto::Entry::kFieldKey: |
403 | 695 | break; |
404 | 0 | case StructExprProto::Entry::kMapKey: |
405 | 0 | return absl::InvalidArgumentError("encountered map entry in struct"); |
406 | 0 | default: |
407 | 0 | return absl::InvalidArgumentError(absl::StrCat( |
408 | 0 | "unexpected struct field kind: ", field_proto.key_kind_case())); |
409 | 695 | } |
410 | 695 | auto& field_expr = struct_expr.add_fields(); |
411 | 695 | field_expr.set_id(field_proto.id()); |
412 | 695 | field_expr.set_name(field_proto.field_key()); |
413 | 695 | if (field_proto.has_value()) { |
414 | 695 | Push(field_proto.value(), field_expr.mutable_value()); |
415 | 695 | } |
416 | 695 | field_expr.set_optional(field_proto.optional_entry()); |
417 | 695 | } |
418 | 1.90k | return absl::OkStatus(); |
419 | 1.90k | } |
420 | | |
421 | | absl::Status MapExprFromProto(const ExprProto& proto, |
422 | | const ExprProto::CreateStruct& map_proto, |
423 | 6.03k | Expr& expr) { |
424 | 6.03k | expr.Clear(); |
425 | 6.03k | expr.set_id(proto.id()); |
426 | 6.03k | auto& map_expr = expr.mutable_map_expr(); |
427 | 6.03k | map_expr.mutable_entries().reserve( |
428 | 6.03k | static_cast<size_t>(map_proto.entries().size())); |
429 | 6.03k | for (const auto& entry_proto : map_proto.entries()) { |
430 | 4.51k | switch (entry_proto.key_kind_case()) { |
431 | 0 | case StructExprProto::Entry::KEY_KIND_NOT_SET: |
432 | 0 | ABSL_FALLTHROUGH_INTENDED; |
433 | 4.51k | case StructExprProto::Entry::kMapKey: |
434 | 4.51k | break; |
435 | 0 | case StructExprProto::Entry::kFieldKey: |
436 | 0 | return absl::InvalidArgumentError("encountered struct field in map"); |
437 | 0 | default: |
438 | 0 | return absl::InvalidArgumentError(absl::StrCat( |
439 | 0 | "unexpected map entry kind: ", entry_proto.key_kind_case())); |
440 | 4.51k | } |
441 | 4.51k | auto& entry_expr = map_expr.add_entries(); |
442 | 4.51k | entry_expr.set_id(entry_proto.id()); |
443 | 4.51k | if (entry_proto.has_map_key()) { |
444 | 4.51k | Push(entry_proto.map_key(), entry_expr.mutable_key()); |
445 | 4.51k | } |
446 | 4.51k | if (entry_proto.has_value()) { |
447 | 4.51k | Push(entry_proto.value(), entry_expr.mutable_value()); |
448 | 4.51k | } |
449 | 4.51k | entry_expr.set_optional(entry_proto.optional_entry()); |
450 | 4.51k | } |
451 | 6.03k | return absl::OkStatus(); |
452 | 6.03k | } |
453 | | |
454 | | absl::Status ComprehensionExprFromProto( |
455 | | const ExprProto& proto, |
456 | 4.52k | const ExprProto::Comprehension& comprehension_proto, Expr& expr) { |
457 | 4.52k | expr.Clear(); |
458 | 4.52k | expr.set_id(proto.id()); |
459 | 4.52k | auto& comprehension_expr = expr.mutable_comprehension_expr(); |
460 | 4.52k | comprehension_expr.set_iter_var(comprehension_proto.iter_var()); |
461 | 4.52k | comprehension_expr.set_iter_var2(comprehension_proto.iter_var2()); |
462 | 4.52k | comprehension_expr.set_accu_var(comprehension_proto.accu_var()); |
463 | 4.52k | if (comprehension_proto.has_iter_range()) { |
464 | 4.52k | Push(comprehension_proto.iter_range(), |
465 | 4.52k | comprehension_expr.mutable_iter_range()); |
466 | 4.52k | } |
467 | 4.52k | if (comprehension_proto.has_accu_init()) { |
468 | 4.52k | Push(comprehension_proto.accu_init(), |
469 | 4.52k | comprehension_expr.mutable_accu_init()); |
470 | 4.52k | } |
471 | 4.52k | if (comprehension_proto.has_loop_condition()) { |
472 | 4.52k | Push(comprehension_proto.loop_condition(), |
473 | 4.52k | comprehension_expr.mutable_loop_condition()); |
474 | 4.52k | } |
475 | 4.52k | if (comprehension_proto.has_loop_step()) { |
476 | 4.52k | Push(comprehension_proto.loop_step(), |
477 | 4.52k | comprehension_expr.mutable_loop_step()); |
478 | 4.52k | } |
479 | 4.52k | if (comprehension_proto.has_result()) { |
480 | 4.52k | Push(comprehension_proto.result(), comprehension_expr.mutable_result()); |
481 | 4.52k | } |
482 | 4.52k | return absl::OkStatus(); |
483 | 4.52k | } |
484 | | |
485 | 350k | void Push(const ExprProto& proto, Expr& expr) { |
486 | 350k | frames_.push(Frame{&proto, &expr}); |
487 | 350k | } |
488 | | |
489 | 361k | bool Pop(Frame& frame) { |
490 | 361k | if (frames_.empty()) { |
491 | 10.7k | return false; |
492 | 10.7k | } |
493 | 350k | frame = frames_.top(); |
494 | 350k | frames_.pop(); |
495 | 350k | return true; |
496 | 361k | } |
497 | | |
498 | | std::stack<Frame, std::vector<Frame>> frames_; |
499 | | }; |
500 | | |
501 | | } // namespace |
502 | | |
503 | | absl::Status ExprToProto(const Expr& expr, |
504 | 12.4k | cel::expr::Expr* absl_nonnull proto) { |
505 | 12.4k | ExprToProtoState state; |
506 | 12.4k | return state.ExprToProto(expr, proto); |
507 | 12.4k | } |
508 | | |
509 | 10.7k | absl::Status ExprFromProto(const cel::expr::Expr& proto, Expr& expr) { |
510 | 10.7k | ExprFromProtoState state; |
511 | 10.7k | return state.ExprFromProto(proto, expr); |
512 | 10.7k | } |
513 | | |
514 | | } // namespace cel::ast_internal |