/proc/self/cwd/common/operators.cc
Line | Count | Source |
1 | | // Copyright 2019 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/operators.h" |
16 | | |
17 | | #include <string> |
18 | | |
19 | | #include "absl/container/flat_hash_map.h" |
20 | | #include "absl/strings/string_view.h" |
21 | | #include "absl/types/optional.h" |
22 | | |
23 | | #undef IN |
24 | | |
25 | | namespace google::api::expr::common { |
26 | | |
27 | | namespace { |
28 | | // These functions provide access to reverse mappings for operators. |
29 | | // Functions generally map from text expression to Expr representation, |
30 | | // e.g., from "&&" to "_&&_". Reverse operators provides a mapping from |
31 | | // Expr to textual mapping, e.g., from "_&&_" to "&&". |
32 | | |
33 | 0 | const absl::flat_hash_map<std::string, std::string>& UnaryOperators() { |
34 | 0 | static auto* unaries_map = new absl::flat_hash_map<std::string, std::string>{ |
35 | 0 | {CelOperator::NEGATE, "-"}, {CelOperator::LOGICAL_NOT, "!"}}; |
36 | 0 | return *unaries_map; |
37 | 0 | } |
38 | | |
39 | 0 | const absl::flat_hash_map<std::string, std::string>& BinaryOperators() { |
40 | 0 | static auto* binops_map = new absl::flat_hash_map<std::string, std::string>{ |
41 | 0 | {CelOperator::LOGICAL_OR, "||"}, |
42 | 0 | {CelOperator::LOGICAL_AND, "&&"}, |
43 | 0 | {CelOperator::LESS_EQUALS, "<="}, |
44 | 0 | {CelOperator::LESS, "<"}, |
45 | 0 | {CelOperator::GREATER_EQUALS, ">="}, |
46 | 0 | {CelOperator::GREATER, ">"}, |
47 | 0 | {CelOperator::EQUALS, "=="}, |
48 | 0 | {CelOperator::NOT_EQUALS, "!="}, |
49 | 0 | {CelOperator::IN_DEPRECATED, "in"}, |
50 | 0 | {CelOperator::IN, "in"}, |
51 | 0 | {CelOperator::ADD, "+"}, |
52 | 0 | {CelOperator::SUBTRACT, "-"}, |
53 | 0 | {CelOperator::MULTIPLY, "*"}, |
54 | 0 | {CelOperator::DIVIDE, "/"}, |
55 | 0 | {CelOperator::MODULO, "%"}}; |
56 | 0 | return *binops_map; |
57 | 0 | } |
58 | | |
59 | 734k | const absl::flat_hash_map<std::string, std::string>& ReverseOperators() { |
60 | 734k | static auto* operators_map = |
61 | 734k | new absl::flat_hash_map<std::string, std::string>{ |
62 | 734k | {"+", CelOperator::ADD}, |
63 | 734k | {"-", CelOperator::SUBTRACT}, |
64 | 734k | {"*", CelOperator::MULTIPLY}, |
65 | 734k | {"/", CelOperator::DIVIDE}, |
66 | 734k | {"%", CelOperator::MODULO}, |
67 | 734k | {"==", CelOperator::EQUALS}, |
68 | 734k | {"!=", CelOperator::NOT_EQUALS}, |
69 | 734k | {">", CelOperator::GREATER}, |
70 | 734k | {">=", CelOperator::GREATER_EQUALS}, |
71 | 734k | {"<", CelOperator::LESS}, |
72 | 734k | {"<=", CelOperator::LESS_EQUALS}, |
73 | 734k | {"&&", CelOperator::LOGICAL_AND}, |
74 | 734k | {"!", CelOperator::LOGICAL_NOT}, |
75 | 734k | {"||", CelOperator::LOGICAL_OR}, |
76 | 734k | {"in", CelOperator::IN}, |
77 | 734k | }; |
78 | 734k | return *operators_map; |
79 | 734k | } |
80 | | |
81 | 0 | const absl::flat_hash_map<std::string, std::string>& Operators() { |
82 | 0 | static auto* operators_map = |
83 | 0 | new absl::flat_hash_map<std::string, std::string>{ |
84 | 0 | {CelOperator::ADD, "+"}, |
85 | 0 | {CelOperator::SUBTRACT, "-"}, |
86 | 0 | {CelOperator::MULTIPLY, "*"}, |
87 | 0 | {CelOperator::DIVIDE, "/"}, |
88 | 0 | {CelOperator::MODULO, "%"}, |
89 | 0 | {CelOperator::EQUALS, "=="}, |
90 | 0 | {CelOperator::NOT_EQUALS, "!="}, |
91 | 0 | {CelOperator::GREATER, ">"}, |
92 | 0 | {CelOperator::GREATER_EQUALS, ">="}, |
93 | 0 | {CelOperator::LESS, "<"}, |
94 | 0 | {CelOperator::LESS_EQUALS, "<="}, |
95 | 0 | {CelOperator::LOGICAL_AND, "&&"}, |
96 | 0 | {CelOperator::LOGICAL_NOT, "!"}, |
97 | 0 | {CelOperator::LOGICAL_OR, "||"}, |
98 | 0 | {CelOperator::IN, "in"}, |
99 | 0 | {CelOperator::IN_DEPRECATED, "in"}, |
100 | 0 | {CelOperator::NEGATE, "-"}}; |
101 | 0 | return *operators_map; |
102 | 0 | } |
103 | | |
104 | | // precedence of the operator, where the higher value means higher. |
105 | 0 | const absl::flat_hash_map<std::string, int>& Precedences() { |
106 | 0 | static auto* precedence_map = new absl::flat_hash_map<std::string, int>{ |
107 | 0 | {CelOperator::CONDITIONAL, 8}, |
108 | |
|
109 | 0 | {CelOperator::LOGICAL_OR, 7}, |
110 | |
|
111 | 0 | {CelOperator::LOGICAL_AND, 6}, |
112 | |
|
113 | 0 | {CelOperator::EQUALS, 5}, |
114 | 0 | {CelOperator::GREATER, 5}, |
115 | 0 | {CelOperator::GREATER_EQUALS, 5}, |
116 | 0 | {CelOperator::IN, 5}, |
117 | 0 | {CelOperator::LESS, 5}, |
118 | 0 | {CelOperator::LESS_EQUALS, 5}, |
119 | 0 | {CelOperator::NOT_EQUALS, 5}, |
120 | 0 | {CelOperator::IN_DEPRECATED, 5}, |
121 | |
|
122 | 0 | {CelOperator::ADD, 4}, |
123 | 0 | {CelOperator::SUBTRACT, 4}, |
124 | |
|
125 | 0 | {CelOperator::DIVIDE, 3}, |
126 | 0 | {CelOperator::MODULO, 3}, |
127 | 0 | {CelOperator::MULTIPLY, 3}, |
128 | |
|
129 | 0 | {CelOperator::LOGICAL_NOT, 2}, |
130 | 0 | {CelOperator::NEGATE, 2}, |
131 | |
|
132 | 0 | {CelOperator::INDEX, 1}}; |
133 | 0 | return *precedence_map; |
134 | 0 | } |
135 | | |
136 | | } // namespace |
137 | | |
138 | | const char* CelOperator::CONDITIONAL = "_?_:_"; |
139 | | const char* CelOperator::LOGICAL_AND = "_&&_"; |
140 | | const char* CelOperator::LOGICAL_OR = "_||_"; |
141 | | const char* CelOperator::LOGICAL_NOT = "!_"; |
142 | | const char* CelOperator::IN_DEPRECATED = "_in_"; |
143 | | const char* CelOperator::EQUALS = "_==_"; |
144 | | const char* CelOperator::NOT_EQUALS = "_!=_"; |
145 | | const char* CelOperator::LESS = "_<_"; |
146 | | const char* CelOperator::LESS_EQUALS = "_<=_"; |
147 | | const char* CelOperator::GREATER = "_>_"; |
148 | | const char* CelOperator::GREATER_EQUALS = "_>=_"; |
149 | | const char* CelOperator::ADD = "_+_"; |
150 | | const char* CelOperator::SUBTRACT = "_-_"; |
151 | | const char* CelOperator::MULTIPLY = "_*_"; |
152 | | const char* CelOperator::DIVIDE = "_/_"; |
153 | | const char* CelOperator::MODULO = "_%_"; |
154 | | const char* CelOperator::NEGATE = "-_"; |
155 | | const char* CelOperator::INDEX = "_[_]"; |
156 | | const char* CelOperator::HAS = "has"; |
157 | | const char* CelOperator::ALL = "all"; |
158 | | const char* CelOperator::EXISTS = "exists"; |
159 | | const char* CelOperator::EXISTS_ONE = "exists_one"; |
160 | | const char* CelOperator::MAP = "map"; |
161 | | const char* CelOperator::FILTER = "filter"; |
162 | | const char* CelOperator::NOT_STRICTLY_FALSE = "@not_strictly_false"; |
163 | | const char* CelOperator::IN = "@in"; |
164 | | |
165 | | const absl::string_view CelOperator::OPT_INDEX = "_[?_]"; |
166 | | const absl::string_view CelOperator::OPT_SELECT = "_?._"; |
167 | | |
168 | 0 | int LookupPrecedence(const std::string& op) { |
169 | 0 | auto precs = Precedences(); |
170 | 0 | auto p = precs.find(op); |
171 | 0 | if (p != precs.end()) { |
172 | 0 | return p->second; |
173 | 0 | } |
174 | 0 | return 0; |
175 | 0 | } |
176 | | |
177 | 0 | absl::optional<std::string> LookupUnaryOperator(const std::string& op) { |
178 | 0 | auto unary_ops = UnaryOperators(); |
179 | 0 | auto o = unary_ops.find(op); |
180 | 0 | if (o == unary_ops.end()) { |
181 | 0 | return absl::optional<std::string>(); |
182 | 0 | } |
183 | 0 | return o->second; |
184 | 0 | } |
185 | | |
186 | 0 | absl::optional<std::string> LookupBinaryOperator(const std::string& op) { |
187 | 0 | auto bin_ops = BinaryOperators(); |
188 | 0 | auto o = bin_ops.find(op); |
189 | 0 | if (o == bin_ops.end()) { |
190 | 0 | return absl::optional<std::string>(); |
191 | 0 | } |
192 | 0 | return o->second; |
193 | 0 | } |
194 | | |
195 | 0 | absl::optional<std::string> LookupOperator(const std::string& op) { |
196 | 0 | auto ops = Operators(); |
197 | 0 | auto o = ops.find(op); |
198 | 0 | if (o == ops.end()) { |
199 | 0 | return absl::optional<std::string>(); |
200 | 0 | } |
201 | 0 | return o->second; |
202 | 0 | } |
203 | | |
204 | 734k | absl::optional<std::string> ReverseLookupOperator(const std::string& op) { |
205 | 734k | auto rev_ops = ReverseOperators(); |
206 | 734k | auto o = rev_ops.find(op); |
207 | 734k | if (o == rev_ops.end()) { |
208 | 0 | return absl::optional<std::string>(); |
209 | 0 | } |
210 | 734k | return o->second; |
211 | 734k | } |
212 | | |
213 | | bool IsOperatorSamePrecedence(const std::string& op, |
214 | 0 | const cel::expr::Expr& expr) { |
215 | 0 | if (!expr.has_call_expr()) { |
216 | 0 | return false; |
217 | 0 | } |
218 | 0 | return LookupPrecedence(op) == LookupPrecedence(expr.call_expr().function()); |
219 | 0 | } |
220 | | |
221 | | bool IsOperatorLowerPrecedence(const std::string& op, |
222 | 0 | const cel::expr::Expr& expr) { |
223 | 0 | if (!expr.has_call_expr()) { |
224 | 0 | return false; |
225 | 0 | } |
226 | 0 | return LookupPrecedence(op) < LookupPrecedence(expr.call_expr().function()); |
227 | 0 | } |
228 | | |
229 | 0 | bool IsOperatorLeftRecursive(const std::string& op) { |
230 | 0 | return op != CelOperator::LOGICAL_AND && op != CelOperator::LOGICAL_OR; |
231 | 0 | } |
232 | | |
233 | | } // namespace google::api::expr::common |