/proc/self/cwd/parser/macro_expr_factory.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 "parser/macro_expr_factory.h" |
16 | | |
17 | | #include <utility> |
18 | | #include <vector> |
19 | | |
20 | | #include "absl/functional/overload.h" |
21 | | #include "absl/types/optional.h" |
22 | | #include "absl/types/variant.h" |
23 | | #include "common/constant.h" |
24 | | #include "common/expr.h" |
25 | | |
26 | | namespace cel { |
27 | | |
28 | 0 | Expr MacroExprFactory::Copy(const Expr& expr) { |
29 | | // Copying logic is recursive at the moment, we alter it to be iterative in |
30 | | // the future. |
31 | 0 | return absl::visit( |
32 | 0 | absl::Overload( |
33 | 0 | [this, &expr](const UnspecifiedExpr&) -> Expr { |
34 | 0 | return NewUnspecified(CopyId(expr)); |
35 | 0 | }, |
36 | 0 | [this, &expr](const Constant& const_expr) -> Expr { |
37 | 0 | return NewConst(CopyId(expr), const_expr); |
38 | 0 | }, |
39 | 0 | [this, &expr](const IdentExpr& ident_expr) -> Expr { |
40 | 0 | return NewIdent(CopyId(expr), ident_expr.name()); |
41 | 0 | }, |
42 | 0 | [this, &expr](const SelectExpr& select_expr) -> Expr { |
43 | 0 | const auto id = CopyId(expr); |
44 | 0 | return select_expr.test_only() |
45 | 0 | ? NewPresenceTest(id, Copy(select_expr.operand()), |
46 | 0 | select_expr.field()) |
47 | 0 | : NewSelect(id, Copy(select_expr.operand()), |
48 | 0 | select_expr.field()); |
49 | 0 | }, |
50 | 0 | [this, &expr](const CallExpr& call_expr) -> Expr { |
51 | 0 | const auto id = CopyId(expr); |
52 | 0 | absl::optional<Expr> target; |
53 | 0 | if (call_expr.has_target()) { |
54 | 0 | target = Copy(call_expr.target()); |
55 | 0 | } |
56 | 0 | std::vector<Expr> args; |
57 | 0 | args.reserve(call_expr.args().size()); |
58 | 0 | for (const auto& arg : call_expr.args()) { |
59 | 0 | args.push_back(Copy(arg)); |
60 | 0 | } |
61 | 0 | return target.has_value() |
62 | 0 | ? NewMemberCall(id, call_expr.function(), |
63 | 0 | std::move(*target), std::move(args)) |
64 | 0 | : NewCall(id, call_expr.function(), std::move(args)); |
65 | 0 | }, |
66 | 0 | [this, &expr](const ListExpr& list_expr) -> Expr { |
67 | 0 | const auto id = CopyId(expr); |
68 | 0 | std::vector<ListExprElement> elements; |
69 | 0 | elements.reserve(list_expr.elements().size()); |
70 | 0 | for (const auto& element : list_expr.elements()) { |
71 | 0 | elements.push_back(Copy(element)); |
72 | 0 | } |
73 | 0 | return NewList(id, std::move(elements)); |
74 | 0 | }, |
75 | 0 | [this, &expr](const StructExpr& struct_expr) -> Expr { |
76 | 0 | const auto id = CopyId(expr); |
77 | 0 | std::vector<StructExprField> fields; |
78 | 0 | fields.reserve(struct_expr.fields().size()); |
79 | 0 | for (const auto& field : struct_expr.fields()) { |
80 | 0 | fields.push_back(Copy(field)); |
81 | 0 | } |
82 | 0 | return NewStruct(id, struct_expr.name(), std::move(fields)); |
83 | 0 | }, |
84 | 0 | [this, &expr](const MapExpr& map_expr) -> Expr { |
85 | 0 | const auto id = CopyId(expr); |
86 | 0 | std::vector<MapExprEntry> entries; |
87 | 0 | entries.reserve(map_expr.entries().size()); |
88 | 0 | for (const auto& entry : map_expr.entries()) { |
89 | 0 | entries.push_back(Copy(entry)); |
90 | 0 | } |
91 | 0 | return NewMap(id, std::move(entries)); |
92 | 0 | }, |
93 | 0 | [this, &expr](const ComprehensionExpr& comprehension_expr) -> Expr { |
94 | 0 | const auto id = CopyId(expr); |
95 | 0 | auto iter_range = Copy(comprehension_expr.iter_range()); |
96 | 0 | auto accu_init = Copy(comprehension_expr.accu_init()); |
97 | 0 | auto loop_condition = Copy(comprehension_expr.loop_condition()); |
98 | 0 | auto loop_step = Copy(comprehension_expr.loop_step()); |
99 | 0 | auto result = Copy(comprehension_expr.result()); |
100 | 0 | return NewComprehension( |
101 | 0 | id, comprehension_expr.iter_var(), std::move(iter_range), |
102 | 0 | comprehension_expr.accu_var(), std::move(accu_init), |
103 | 0 | std::move(loop_condition), std::move(loop_step), |
104 | 0 | std::move(result)); |
105 | 0 | }), |
106 | 0 | expr.kind()); |
107 | 0 | } |
108 | | |
109 | 0 | ListExprElement MacroExprFactory::Copy(const ListExprElement& element) { |
110 | 0 | return NewListElement(Copy(element.expr()), element.optional()); |
111 | 0 | } |
112 | | |
113 | 0 | StructExprField MacroExprFactory::Copy(const StructExprField& field) { |
114 | 0 | auto field_id = CopyId(field.id()); |
115 | 0 | auto field_value = Copy(field.value()); |
116 | 0 | return NewStructField(field_id, field.name(), std::move(field_value), |
117 | 0 | field.optional()); |
118 | 0 | } |
119 | | |
120 | 0 | MapExprEntry MacroExprFactory::Copy(const MapExprEntry& entry) { |
121 | 0 | auto entry_id = CopyId(entry.id()); |
122 | 0 | auto entry_key = Copy(entry.key()); |
123 | 0 | auto entry_value = Copy(entry.value()); |
124 | 0 | return NewMapEntry(entry_id, std::move(entry_key), std::move(entry_value), |
125 | 0 | entry.optional()); |
126 | 0 | } |
127 | | |
128 | | } // namespace cel |