/proc/self/cwd/base/attribute.h
Line | Count | Source |
1 | | // Copyright 2022 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_BASE_ATTRIBUTE_H_ |
16 | | #define THIRD_PARTY_CEL_CPP_BASE_ATTRIBUTE_H_ |
17 | | |
18 | | #include <cstddef> |
19 | | #include <cstdint> |
20 | | #include <cstring> |
21 | | #include <memory> |
22 | | #include <optional> |
23 | | #include <string> |
24 | | #include <utility> |
25 | | #include <variant> |
26 | | #include <vector> |
27 | | |
28 | | #include "absl/base/attributes.h" |
29 | | #include "absl/base/macros.h" |
30 | | #include "absl/functional/overload.h" |
31 | | #include "absl/log/absl_check.h" |
32 | | #include "absl/status/statusor.h" |
33 | | #include "absl/strings/string_view.h" |
34 | | #include "absl/types/optional_ref.h" |
35 | | #include "absl/types/span.h" |
36 | | #include "base/kind.h" |
37 | | |
38 | | namespace cel { |
39 | | |
40 | | namespace common_internal { |
41 | | class AttributeMatcherNode; |
42 | | struct WildcardType {}; |
43 | | using AttributeQualifierVariant = |
44 | | std::variant<std::monostate, int64_t, uint64_t, std::string, bool>; |
45 | | using AttributeQualifierPatternVariant = |
46 | | std::variant<std::monostate, int64_t, uint64_t, std::string, bool, |
47 | | WildcardType>; |
48 | | using AttributeQualifierViewVariant = |
49 | | std::variant<std::monostate, int64_t, uint64_t, absl::string_view, bool>; |
50 | | } // namespace common_internal |
51 | | |
52 | | class AttributeQualifier; |
53 | | class AttributeQualifierPattern; |
54 | | class Attribute; |
55 | | class AttributePattern; |
56 | | class AttributeQualifierView; |
57 | | |
58 | | namespace common_internal { |
59 | | [[nodiscard]] |
60 | | const AttributeQualifierVariant& AsVariant( |
61 | | const AttributeQualifier& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND); |
62 | | [[nodiscard]] |
63 | | AttributeQualifierVariant&& AsVariant( |
64 | | AttributeQualifier&& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND); |
65 | | [[nodiscard]] |
66 | | const AttributeQualifierPatternVariant& AsVariant( |
67 | | const AttributeQualifierPattern& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND); |
68 | | [[nodiscard]] |
69 | | AttributeQualifierPatternVariant&& AsVariant( |
70 | | AttributeQualifierPattern&& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND); |
71 | | [[nodiscard]] |
72 | | const AttributeQualifierViewVariant& AsVariant( |
73 | | const AttributeQualifierView& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND); |
74 | | [[nodiscard]] |
75 | | AttributeQualifierViewVariant&& AsVariant( |
76 | | AttributeQualifierView&& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND); |
77 | | } // namespace common_internal |
78 | | |
79 | | // AttributeQualifier represents a segment in the |
80 | | // attribute resolution path. A segment can be qualified by values of |
81 | | // following types: string/int64_t/uint64_t/bool. |
82 | | class AttributeQualifier { |
83 | | public: |
84 | 0 | static AttributeQualifier OfInt(int64_t value) { |
85 | 0 | return AttributeQualifier(std::in_place_type<int64_t>, std::move(value)); |
86 | 0 | } |
87 | | |
88 | 0 | static AttributeQualifier OfUint(uint64_t value) { |
89 | 0 | return AttributeQualifier(std::in_place_type<uint64_t>, std::move(value)); |
90 | 0 | } |
91 | | |
92 | 0 | static AttributeQualifier OfString(const char* value) { |
93 | 0 | return OfString(absl::string_view(value)); |
94 | 0 | } |
95 | | |
96 | 0 | static AttributeQualifier OfString(std::string value) { |
97 | 0 | return AttributeQualifier(std::in_place_type<std::string>, |
98 | 0 | std::move(value)); |
99 | 0 | } |
100 | | |
101 | 0 | static AttributeQualifier OfString(absl::string_view value) { |
102 | 0 | return AttributeQualifier(std::in_place_type<std::string>, |
103 | 0 | std::string(value)); |
104 | 0 | } |
105 | | |
106 | 0 | static AttributeQualifier OfBool(bool value) { |
107 | 0 | return AttributeQualifier(std::in_place_type<bool>, std::move(value)); |
108 | 0 | } |
109 | | |
110 | 0 | AttributeQualifier() = default; |
111 | 0 | AttributeQualifier(const AttributeQualifier&) = default; |
112 | 0 | AttributeQualifier(AttributeQualifier&&) = default; |
113 | | AttributeQualifier& operator=(const AttributeQualifier&) = default; |
114 | 0 | AttributeQualifier& operator=(AttributeQualifier&&) = default; |
115 | | |
116 | | Kind kind() const; |
117 | | |
118 | | [[nodiscard]] |
119 | | std::string ToString() const; |
120 | | |
121 | | ABSL_DEPRECATE_AND_INLINE() |
122 | 0 | std::optional<int64_t> GetInt64Key() const { return AsInt(); } |
123 | | |
124 | | ABSL_DEPRECATE_AND_INLINE() |
125 | 0 | std::optional<uint64_t> GetUint64Key() const { return AsUint(); } |
126 | | |
127 | | ABSL_DEPRECATED("Use AsString") |
128 | 0 | std::optional<absl::string_view> GetStringKey() const { |
129 | 0 | if (auto string = AsString(); string.has_value()) { |
130 | 0 | return *string; |
131 | 0 | } |
132 | 0 | return std::nullopt; |
133 | 0 | } |
134 | | |
135 | | ABSL_DEPRECATE_AND_INLINE() |
136 | 0 | std::optional<bool> GetBoolKey() const { return AsBool(); } |
137 | | |
138 | 0 | explicit operator bool() const { |
139 | 0 | return !std::holds_alternative<std::monostate>(value_); |
140 | 0 | } |
141 | | |
142 | | [[nodiscard]] |
143 | 0 | bool IsBool() const { |
144 | 0 | return std::holds_alternative<bool>(value_); |
145 | 0 | } |
146 | | |
147 | | [[nodiscard]] |
148 | 0 | bool IsInt() const { |
149 | 0 | return std::holds_alternative<int64_t>(value_); |
150 | 0 | } |
151 | | |
152 | | [[nodiscard]] |
153 | 0 | bool IsUint() const { |
154 | 0 | return std::holds_alternative<uint64_t>(value_); |
155 | 0 | } |
156 | | |
157 | | [[nodiscard]] |
158 | 0 | bool IsString() const { |
159 | 0 | return std::holds_alternative<std::string>(value_); |
160 | 0 | } |
161 | | |
162 | | [[nodiscard]] |
163 | 0 | bool GetBool() const { |
164 | 0 | ABSL_DCHECK(IsBool()); |
165 | 0 | return std::get<bool>(value_); |
166 | 0 | } |
167 | | |
168 | | [[nodiscard]] |
169 | 0 | int64_t GetInt() const { |
170 | 0 | ABSL_DCHECK(IsInt()); |
171 | 0 | return std::get<int64_t>(value_); |
172 | 0 | } |
173 | | |
174 | | [[nodiscard]] |
175 | 0 | uint64_t GetUint() const { |
176 | 0 | ABSL_DCHECK(IsUint()); |
177 | 0 | return std::get<uint64_t>(value_); |
178 | 0 | } |
179 | | |
180 | | [[nodiscard]] |
181 | 0 | const std::string& GetString() const { |
182 | 0 | ABSL_DCHECK(IsString()); |
183 | 0 | return std::get<std::string>(value_); |
184 | 0 | } |
185 | | |
186 | | [[nodiscard]] |
187 | 0 | std::optional<bool> AsBool() const { |
188 | 0 | if (const auto* value = std::get_if<bool>(&value_); value != nullptr) { |
189 | 0 | return *value; |
190 | 0 | } |
191 | 0 | return std::nullopt; |
192 | 0 | } |
193 | | |
194 | | [[nodiscard]] |
195 | 0 | std::optional<int64_t> AsInt() const { |
196 | 0 | if (const auto* value = std::get_if<int64_t>(&value_); value != nullptr) { |
197 | 0 | return *value; |
198 | 0 | } |
199 | 0 | return std::nullopt; |
200 | 0 | } |
201 | | |
202 | | [[nodiscard]] |
203 | 0 | std::optional<uint64_t> AsUint() const { |
204 | 0 | if (const auto* value = std::get_if<uint64_t>(&value_); value != nullptr) { |
205 | 0 | return *value; |
206 | 0 | } |
207 | 0 | return std::nullopt; |
208 | 0 | } |
209 | | |
210 | | [[nodiscard]] |
211 | 0 | absl::optional_ref<const std::string> AsString() const { |
212 | 0 | if (const auto* value = std::get_if<std::string>(&value_); |
213 | 0 | value != nullptr) { |
214 | 0 | return *value; |
215 | 0 | } |
216 | 0 | return std::nullopt; |
217 | 0 | } |
218 | | |
219 | | [[nodiscard]] |
220 | | bool IsMatch(const AttributeQualifier& other) const; |
221 | | |
222 | | [[nodiscard]] |
223 | | bool IsMatch(absl::string_view other_key) const; |
224 | | |
225 | | private: |
226 | | friend const common_internal::AttributeQualifierVariant& |
227 | | common_internal::AsVariant(const AttributeQualifier& qualifier); |
228 | | friend common_internal::AttributeQualifierVariant&& |
229 | | common_internal::AsVariant(AttributeQualifier&& qualifier); |
230 | | |
231 | | template <typename T, typename... Args> |
232 | | explicit AttributeQualifier(std::in_place_type_t<T> in_place_type, |
233 | | Args&&... args) |
234 | 0 | : value_(in_place_type, std::forward<Args>(args)...) {}Unexecuted instantiation: cel::AttributeQualifier::AttributeQualifier<long, long>(std::__1::in_place_type_t<long>, long&&) Unexecuted instantiation: cel::AttributeQualifier::AttributeQualifier<unsigned long, unsigned long>(std::__1::in_place_type_t<unsigned long>, unsigned long&&) Unexecuted instantiation: cel::AttributeQualifier::AttributeQualifier<bool, bool>(std::__1::in_place_type_t<bool>, bool&&) Unexecuted instantiation: cel::AttributeQualifier::AttributeQualifier<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::in_place_type_t<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&) |
235 | | |
236 | | using Variant = common_internal::AttributeQualifierVariant; |
237 | | |
238 | | // The previous implementation of Attribute preserved all value |
239 | | // instances, regardless of whether they are supported in this context or not. |
240 | | // We represented unsupported types by using the first alternative and thus |
241 | | // preserve backwards compatibility with the result of `type()` above. |
242 | | Variant value_; |
243 | | }; |
244 | | |
245 | | class AttributeQualifierView { |
246 | | public: |
247 | 0 | static AttributeQualifierView OfInt(int64_t value) { |
248 | 0 | return AttributeQualifierView(std::in_place_type<int64_t>, |
249 | 0 | std::move(value)); |
250 | 0 | } |
251 | | |
252 | 0 | static AttributeQualifierView OfUint(uint64_t value) { |
253 | 0 | return AttributeQualifierView(std::in_place_type<uint64_t>, |
254 | 0 | std::move(value)); |
255 | 0 | } |
256 | | |
257 | 0 | static AttributeQualifierView OfString(const char* value) { |
258 | 0 | return OfString(absl::string_view(value)); |
259 | 0 | } |
260 | | |
261 | 0 | static AttributeQualifierView OfString(absl::string_view value) { |
262 | 0 | return AttributeQualifierView(std::in_place_type<absl::string_view>, |
263 | 0 | std::move(value)); |
264 | 0 | } |
265 | | |
266 | | static AttributeQualifierView OfString(std::string&&) = delete; |
267 | | |
268 | 0 | static AttributeQualifierView OfBool(bool value) { |
269 | 0 | return AttributeQualifierView(std::in_place_type<bool>, std::move(value)); |
270 | 0 | } |
271 | | |
272 | | AttributeQualifierView() = default; |
273 | | AttributeQualifierView(const AttributeQualifierView&) = default; |
274 | | AttributeQualifierView& operator=(const AttributeQualifierView&) = default; |
275 | | |
276 | | // NOLINTNEXTLINE(google-explicit-constructor) |
277 | | AttributeQualifierView( |
278 | | const AttributeQualifier& other ABSL_ATTRIBUTE_LIFETIME_BOUND) |
279 | | : value_(std::visit( |
280 | | absl::Overload( |
281 | | [](std::monostate value) -> Variant { |
282 | | return Variant(std::in_place_type<std::monostate>, value); |
283 | | }, |
284 | | [](bool value) -> Variant { |
285 | | return Variant(std::in_place_type<bool>, value); |
286 | | }, |
287 | | [](int64_t value) -> Variant { |
288 | | return Variant(std::in_place_type<int64_t>, value); |
289 | | }, |
290 | | [](uint64_t value) -> Variant { |
291 | | return Variant(std::in_place_type<uint64_t>, value); |
292 | | }, |
293 | | [](const std::string& value) -> Variant { |
294 | | return Variant(std::in_place_type<absl::string_view>, value); |
295 | | }), |
296 | 0 | common_internal::AsVariant(other))) {} |
297 | | |
298 | | // NOLINTNEXTLINE(google-explicit-constructor) |
299 | | AttributeQualifierView& operator=( |
300 | 0 | const AttributeQualifier& other ABSL_ATTRIBUTE_LIFETIME_BOUND) { |
301 | 0 | return *this = AttributeQualifierView(other); |
302 | 0 | } |
303 | | |
304 | | AttributeQualifierView& operator=(AttributeQualifier&&) = delete; |
305 | | |
306 | | ABSL_DEPRECATE_AND_INLINE() |
307 | 0 | std::optional<int64_t> GetInt64Key() const { return AsInt(); } |
308 | | |
309 | | ABSL_DEPRECATE_AND_INLINE() |
310 | 0 | std::optional<uint64_t> GetUint64Key() const { return AsUint(); } |
311 | | |
312 | | ABSL_DEPRECATE_AND_INLINE() |
313 | 0 | std::optional<absl::string_view> GetStringKey() const { return AsString(); } |
314 | | |
315 | | ABSL_DEPRECATE_AND_INLINE() |
316 | 0 | std::optional<bool> GetBoolKey() const { return AsBool(); } |
317 | | |
318 | | [[nodiscard]] |
319 | 0 | bool IsBool() const { |
320 | 0 | return std::holds_alternative<bool>(value_); |
321 | 0 | } |
322 | | |
323 | | [[nodiscard]] |
324 | 0 | bool IsInt() const { |
325 | 0 | return std::holds_alternative<int64_t>(value_); |
326 | 0 | } |
327 | | |
328 | | [[nodiscard]] |
329 | 0 | bool IsUint() const { |
330 | 0 | return std::holds_alternative<uint64_t>(value_); |
331 | 0 | } |
332 | | |
333 | | [[nodiscard]] |
334 | 0 | bool IsString() const { |
335 | 0 | return std::holds_alternative<absl::string_view>(value_); |
336 | 0 | } |
337 | | |
338 | | [[nodiscard]] |
339 | 0 | bool GetBool() const { |
340 | 0 | ABSL_DCHECK(IsBool()); |
341 | 0 | return std::get<bool>(value_); |
342 | 0 | } |
343 | | |
344 | | [[nodiscard]] |
345 | 0 | int64_t GetInt() const { |
346 | 0 | ABSL_DCHECK(IsInt()); |
347 | 0 | return std::get<int64_t>(value_); |
348 | 0 | } |
349 | | |
350 | | [[nodiscard]] |
351 | 0 | uint64_t GetUint() const { |
352 | 0 | ABSL_DCHECK(IsUint()); |
353 | 0 | return std::get<uint64_t>(value_); |
354 | 0 | } |
355 | | |
356 | | [[nodiscard]] |
357 | 0 | absl::string_view GetString() const { |
358 | 0 | ABSL_DCHECK(IsString()); |
359 | 0 | return std::get<absl::string_view>(value_); |
360 | 0 | } |
361 | | |
362 | | [[nodiscard]] |
363 | 0 | std::optional<bool> AsBool() const { |
364 | 0 | if (const auto* value = std::get_if<bool>(&value_); value != nullptr) { |
365 | 0 | return *value; |
366 | 0 | } |
367 | 0 | return std::nullopt; |
368 | 0 | } |
369 | | |
370 | | [[nodiscard]] |
371 | 0 | std::optional<int64_t> AsInt() const { |
372 | 0 | if (const auto* value = std::get_if<int64_t>(&value_); value != nullptr) { |
373 | 0 | return *value; |
374 | 0 | } |
375 | 0 | return std::nullopt; |
376 | 0 | } |
377 | | |
378 | | [[nodiscard]] |
379 | 0 | std::optional<uint64_t> AsUint() const { |
380 | 0 | if (const auto* value = std::get_if<uint64_t>(&value_); value != nullptr) { |
381 | 0 | return *value; |
382 | 0 | } |
383 | 0 | return std::nullopt; |
384 | 0 | } |
385 | | |
386 | | [[nodiscard]] |
387 | 0 | std::optional<absl::string_view> AsString() const { |
388 | 0 | if (const auto* value = std::get_if<absl::string_view>(&value_); |
389 | 0 | value != nullptr) { |
390 | 0 | return *value; |
391 | 0 | } |
392 | 0 | return std::nullopt; |
393 | 0 | } |
394 | | |
395 | | private: |
396 | | friend const common_internal::AttributeQualifierViewVariant& |
397 | | common_internal::AsVariant(const AttributeQualifierView& qualifier); |
398 | | friend common_internal::AttributeQualifierViewVariant&& |
399 | | common_internal::AsVariant(AttributeQualifierView&& qualifier); |
400 | | |
401 | | using Variant = common_internal::AttributeQualifierViewVariant; |
402 | | |
403 | | template <typename T> |
404 | | AttributeQualifierView(std::in_place_type_t<T> in_place_type, T&& value) |
405 | | : value_(in_place_type, std::forward<T>(value)) {} |
406 | | |
407 | | Variant value_; |
408 | | }; |
409 | | |
410 | | // AttributeQualifierPattern matches a segment in |
411 | | // attribute resolution path. AttributeQualifierPattern is capable of |
412 | | // matching path elements of types string/int64/uint64/bool. |
413 | | class AttributeQualifierPattern { |
414 | | public: |
415 | 0 | static AttributeQualifierPattern OfInt(int64_t value) { |
416 | 0 | return AttributeQualifierPattern(std::in_place_type<int64_t>, value); |
417 | 0 | } |
418 | | |
419 | 0 | static AttributeQualifierPattern OfUint(uint64_t value) { |
420 | 0 | return AttributeQualifierPattern(std::in_place_type<uint64_t>, value); |
421 | 0 | } |
422 | | |
423 | 0 | static AttributeQualifierPattern OfString(const char* value) { |
424 | 0 | return OfString(absl::string_view(value)); |
425 | 0 | } |
426 | | |
427 | 0 | static AttributeQualifierPattern OfString(std::string value) { |
428 | 0 | return AttributeQualifierPattern(std::in_place_type<std::string>, |
429 | 0 | std::move(value)); |
430 | 0 | } |
431 | | |
432 | 0 | static AttributeQualifierPattern OfString(absl::string_view value) { |
433 | 0 | return AttributeQualifierPattern(std::in_place_type<std::string>, |
434 | 0 | std::string(value)); |
435 | 0 | } |
436 | | |
437 | 0 | static AttributeQualifierPattern OfBool(bool value) { |
438 | 0 | return AttributeQualifierPattern(std::in_place_type<bool>, value); |
439 | 0 | } |
440 | | |
441 | | ABSL_DEPRECATE_AND_INLINE() |
442 | 0 | static AttributeQualifierPattern CreateWildcard() { return Wildcard(); } |
443 | | |
444 | 0 | static AttributeQualifierPattern Wildcard() { |
445 | 0 | return AttributeQualifierPattern(std::in_place_type<WildcardType>); |
446 | 0 | } |
447 | | |
448 | | AttributeQualifierPattern() = default; |
449 | 0 | AttributeQualifierPattern(const AttributeQualifierPattern&) = default; |
450 | | AttributeQualifierPattern(AttributeQualifierPattern&&) = default; |
451 | | AttributeQualifierPattern& operator=(const AttributeQualifierPattern&) = |
452 | | default; |
453 | | AttributeQualifierPattern& operator=(AttributeQualifierPattern&&) = default; |
454 | | |
455 | | // NOLINTNEXTLINE(google-explicit-constructor) |
456 | | AttributeQualifierPattern(const AttributeQualifier& value) |
457 | | : value_(std::visit( |
458 | | absl::Overload( |
459 | | [](std::monostate value) -> Variant { |
460 | | return Variant(std::in_place_type<std::monostate>, value); |
461 | | }, |
462 | | [](bool value) -> Variant { |
463 | | return Variant(std::in_place_type<bool>, value); |
464 | | }, |
465 | | [](int64_t value) -> Variant { |
466 | | return Variant(std::in_place_type<int64_t>, value); |
467 | | }, |
468 | | [](uint64_t value) -> Variant { |
469 | | return Variant(std::in_place_type<uint64_t>, value); |
470 | | }, |
471 | | [](const std::string& value) -> Variant { |
472 | | return Variant(std::in_place_type<std::string>, value); |
473 | | }), |
474 | 0 | common_internal::AsVariant(value))) {} |
475 | | |
476 | | // NOLINTNEXTLINE(google-explicit-constructor) |
477 | | AttributeQualifierPattern(AttributeQualifier&& value) |
478 | | : value_(std::visit( |
479 | | absl::Overload( |
480 | | [](std::monostate value) -> Variant { |
481 | | return Variant(std::in_place_type<std::monostate>, value); |
482 | | }, |
483 | | [](bool value) -> Variant { |
484 | | return Variant(std::in_place_type<bool>, value); |
485 | | }, |
486 | | [](int64_t value) -> Variant { |
487 | | return Variant(std::in_place_type<int64_t>, value); |
488 | | }, |
489 | | [](uint64_t value) -> Variant { |
490 | | return Variant(std::in_place_type<uint64_t>, value); |
491 | | }, |
492 | | [](std::string&& value) -> Variant { |
493 | | return Variant(std::in_place_type<std::string>, |
494 | | std::move(value)); |
495 | | }), |
496 | 0 | common_internal::AsVariant(std::move(value)))) {} |
497 | | |
498 | 0 | explicit operator bool() const { |
499 | 0 | return !std::holds_alternative<std::monostate>(value_); |
500 | 0 | } |
501 | | |
502 | | [[nodiscard]] |
503 | 0 | bool IsBool() const { |
504 | 0 | return std::holds_alternative<bool>(value_); |
505 | 0 | } |
506 | | |
507 | | [[nodiscard]] |
508 | 0 | bool IsInt() const { |
509 | 0 | return std::holds_alternative<int64_t>(value_); |
510 | 0 | } |
511 | | |
512 | | [[nodiscard]] |
513 | 0 | bool IsUint() const { |
514 | 0 | return std::holds_alternative<uint64_t>(value_); |
515 | 0 | } |
516 | | |
517 | | [[nodiscard]] |
518 | 0 | bool IsString() const { |
519 | 0 | return std::holds_alternative<std::string>(value_); |
520 | 0 | } |
521 | | |
522 | | [[nodiscard]] |
523 | 0 | bool IsWildcard() const { |
524 | 0 | return std::holds_alternative<WildcardType>(value_); |
525 | 0 | } |
526 | | |
527 | | [[nodiscard]] |
528 | 0 | bool GetBool() const { |
529 | 0 | ABSL_DCHECK(IsBool()); |
530 | 0 | return std::get<bool>(value_); |
531 | 0 | } |
532 | | |
533 | | [[nodiscard]] |
534 | 0 | int64_t GetInt() const { |
535 | 0 | ABSL_DCHECK(IsInt()); |
536 | 0 | return std::get<int64_t>(value_); |
537 | 0 | } |
538 | | |
539 | | [[nodiscard]] |
540 | 0 | uint64_t GetUint() const { |
541 | 0 | ABSL_DCHECK(IsUint()); |
542 | 0 | return std::get<uint64_t>(value_); |
543 | 0 | } |
544 | | |
545 | | [[nodiscard]] |
546 | 0 | const std::string& GetString() const { |
547 | 0 | ABSL_DCHECK(IsString()); |
548 | 0 | return std::get<std::string>(value_); |
549 | 0 | } |
550 | | |
551 | | [[nodiscard]] |
552 | 0 | std::optional<bool> AsBool() const { |
553 | 0 | if (const auto* value = std::get_if<bool>(&value_); value != nullptr) { |
554 | 0 | return *value; |
555 | 0 | } |
556 | 0 | return std::nullopt; |
557 | 0 | } |
558 | | |
559 | | [[nodiscard]] |
560 | 0 | std::optional<int64_t> AsInt() const { |
561 | 0 | if (const auto* value = std::get_if<int64_t>(&value_); value != nullptr) { |
562 | 0 | return *value; |
563 | 0 | } |
564 | 0 | return std::nullopt; |
565 | 0 | } |
566 | | |
567 | | [[nodiscard]] |
568 | 0 | std::optional<uint64_t> AsUint() const { |
569 | 0 | if (const auto* value = std::get_if<uint64_t>(&value_); value != nullptr) { |
570 | 0 | return *value; |
571 | 0 | } |
572 | 0 | return std::nullopt; |
573 | 0 | } |
574 | | |
575 | | [[nodiscard]] |
576 | 0 | absl::optional_ref<const std::string> AsString() const { |
577 | 0 | if (const auto* value = std::get_if<std::string>(&value_); |
578 | 0 | value != nullptr) { |
579 | 0 | return *value; |
580 | 0 | } |
581 | 0 | return std::nullopt; |
582 | 0 | } |
583 | | |
584 | | [[nodiscard]] |
585 | 0 | std::optional<AttributeQualifier> ToQualifier() const { |
586 | 0 | return std::visit( |
587 | 0 | absl::Overload( |
588 | 0 | [](std::monostate) -> std::optional<AttributeQualifier> { |
589 | 0 | return AttributeQualifier(); |
590 | 0 | }, |
591 | 0 | [](bool value) -> std::optional<AttributeQualifier> { |
592 | 0 | return AttributeQualifier::OfBool(value); |
593 | 0 | }, |
594 | 0 | [](int64_t value) -> std::optional<AttributeQualifier> { |
595 | 0 | return AttributeQualifier::OfInt(value); |
596 | 0 | }, |
597 | 0 | [](uint64_t value) -> std::optional<AttributeQualifier> { |
598 | 0 | return AttributeQualifier::OfUint(value); |
599 | 0 | }, |
600 | 0 | [](const std::string& value) -> std::optional<AttributeQualifier> { |
601 | 0 | return AttributeQualifier::OfString(value); |
602 | 0 | }, |
603 | 0 | [](common_internal::WildcardType value) |
604 | 0 | -> std::optional<AttributeQualifier> { return std::nullopt; }), |
605 | 0 | value_); |
606 | 0 | } |
607 | | |
608 | | [[nodiscard]] |
609 | | std::optional<AttributeQualifierView> ToQualifierView() const |
610 | 0 | ABSL_ATTRIBUTE_LIFETIME_BOUND { |
611 | 0 | return std::visit( |
612 | 0 | absl::Overload( |
613 | 0 | [](std::monostate) -> std::optional<AttributeQualifierView> { |
614 | 0 | return AttributeQualifierView(); |
615 | 0 | }, |
616 | 0 | [](bool value) -> std::optional<AttributeQualifierView> { |
617 | 0 | return AttributeQualifierView::OfBool(value); |
618 | 0 | }, |
619 | 0 | [](int64_t value) -> std::optional<AttributeQualifierView> { |
620 | 0 | return AttributeQualifierView::OfInt(value); |
621 | 0 | }, |
622 | 0 | [](uint64_t value) -> std::optional<AttributeQualifierView> { |
623 | 0 | return AttributeQualifierView::OfUint(value); |
624 | 0 | }, |
625 | 0 | [](const std::string& value) |
626 | 0 | -> std::optional<AttributeQualifierView> { |
627 | 0 | return AttributeQualifierView::OfString(value); |
628 | 0 | }, |
629 | 0 | [](common_internal::WildcardType value) |
630 | 0 | -> std::optional<AttributeQualifierView> { |
631 | 0 | return std::nullopt; |
632 | 0 | }), |
633 | 0 | value_); |
634 | 0 | } |
635 | | |
636 | | [[nodiscard]] |
637 | | bool IsMatch(const AttributeQualifier& qualifier) const; |
638 | | |
639 | | [[nodiscard]] |
640 | | bool IsMatch(absl::string_view other_key) const; |
641 | | |
642 | | private: |
643 | | friend const common_internal::AttributeQualifierPatternVariant& |
644 | | common_internal::AsVariant(const AttributeQualifierPattern& qualifier); |
645 | | friend common_internal::AttributeQualifierPatternVariant&& |
646 | | common_internal::AsVariant(AttributeQualifierPattern&& qualifier); |
647 | | |
648 | | using Variant = common_internal::AttributeQualifierPatternVariant; |
649 | | using WildcardType = common_internal::WildcardType; |
650 | | |
651 | | template <typename T, typename... Args> |
652 | | explicit AttributeQualifierPattern(std::in_place_type_t<T> in_place_type, |
653 | | Args&&... args) |
654 | | : value_(in_place_type, std::forward<Args>(args)...) {} |
655 | | |
656 | | // Qualifier value. If not set, treated as wildcard. |
657 | | common_internal::AttributeQualifierPatternVariant value_; |
658 | | }; |
659 | | |
660 | | [[nodiscard]] |
661 | | bool operator==(const AttributeQualifier& lhs, const AttributeQualifier& rhs); |
662 | | |
663 | | [[nodiscard]] |
664 | | bool operator==(const AttributeQualifierView& lhs, |
665 | | const AttributeQualifierView& rhs); |
666 | | |
667 | | [[nodiscard]] |
668 | | bool operator==(const AttributeQualifierPattern& lhs, |
669 | | const AttributeQualifierPattern& rhs); |
670 | | |
671 | | [[nodiscard]] |
672 | | bool operator==(const AttributeQualifier& lhs, |
673 | | const AttributeQualifierView& rhs); |
674 | | |
675 | | [[nodiscard]] |
676 | | bool operator==(const AttributeQualifier& lhs, |
677 | | const AttributeQualifierPattern& rhs); |
678 | | |
679 | | [[nodiscard]] |
680 | | bool operator==(const AttributeQualifierView& lhs, |
681 | | const AttributeQualifier& rhs); |
682 | | |
683 | | [[nodiscard]] |
684 | | bool operator==(const AttributeQualifierView& lhs, |
685 | | const AttributeQualifierPattern& rhs); |
686 | | |
687 | | [[nodiscard]] |
688 | | bool operator==(const AttributeQualifierPattern& lhs, |
689 | | const AttributeQualifier& rhs); |
690 | | |
691 | | [[nodiscard]] |
692 | | bool operator==(const AttributeQualifierPattern& lhs, |
693 | | const AttributeQualifierView& rhs); |
694 | | |
695 | | [[nodiscard]] |
696 | | inline bool operator!=(const AttributeQualifier& lhs, |
697 | 0 | const AttributeQualifier& rhs) { |
698 | 0 | return !operator==(lhs, rhs); |
699 | 0 | } |
700 | | |
701 | | [[nodiscard]] |
702 | | inline bool operator!=(const AttributeQualifierView& lhs, |
703 | 0 | const AttributeQualifierView& rhs) { |
704 | 0 | return !operator==(lhs, rhs); |
705 | 0 | } |
706 | | |
707 | | [[nodiscard]] |
708 | | inline bool operator!=(const AttributeQualifierPattern& lhs, |
709 | 0 | const AttributeQualifierPattern& rhs) { |
710 | 0 | return !operator==(lhs, rhs); |
711 | 0 | } |
712 | | |
713 | | [[nodiscard]] |
714 | | inline bool operator!=(const AttributeQualifier& lhs, |
715 | 0 | const AttributeQualifierView& rhs) { |
716 | 0 | return !operator==(lhs, rhs); |
717 | 0 | } |
718 | | |
719 | | [[nodiscard]] |
720 | | inline bool operator!=(const AttributeQualifier& lhs, |
721 | 0 | const AttributeQualifierPattern& rhs) { |
722 | 0 | return !operator==(lhs, rhs); |
723 | 0 | } |
724 | | |
725 | | [[nodiscard]] |
726 | | inline bool operator!=(const AttributeQualifierView& lhs, |
727 | 0 | const AttributeQualifier& rhs) { |
728 | 0 | return !operator==(lhs, rhs); |
729 | 0 | } |
730 | | |
731 | | [[nodiscard]] |
732 | | inline bool operator!=(const AttributeQualifierView& lhs, |
733 | 0 | const AttributeQualifierPattern& rhs) { |
734 | 0 | return !operator==(lhs, rhs); |
735 | 0 | } |
736 | | |
737 | | [[nodiscard]] |
738 | | inline bool operator!=(const AttributeQualifierPattern& lhs, |
739 | 0 | const AttributeQualifier& rhs) { |
740 | 0 | return !operator==(lhs, rhs); |
741 | 0 | } |
742 | | |
743 | | [[nodiscard]] |
744 | | inline bool operator!=(const AttributeQualifierPattern& lhs, |
745 | 0 | const AttributeQualifierView& rhs) { |
746 | 0 | return !operator==(lhs, rhs); |
747 | 0 | } |
748 | | |
749 | | [[nodiscard]] |
750 | | bool operator<(const AttributeQualifier& lhs, const AttributeQualifier& rhs); |
751 | | |
752 | | [[nodiscard]] |
753 | | bool operator<(const AttributeQualifierView& lhs, |
754 | | const AttributeQualifierView& rhs); |
755 | | |
756 | | [[nodiscard]] |
757 | | bool operator<(const AttributeQualifierPattern& lhs, |
758 | | const AttributeQualifierPattern& rhs); |
759 | | |
760 | | [[nodiscard]] |
761 | | bool operator<(const AttributeQualifier& lhs, |
762 | | const AttributeQualifierView& rhs); |
763 | | |
764 | | [[nodiscard]] |
765 | | bool operator<(const AttributeQualifier& lhs, |
766 | | const AttributeQualifierPattern& rhs); |
767 | | |
768 | | [[nodiscard]] |
769 | | bool operator<(const AttributeQualifierView& lhs, |
770 | | const AttributeQualifier& rhs); |
771 | | |
772 | | [[nodiscard]] |
773 | | bool operator<(const AttributeQualifierView& lhs, |
774 | | const AttributeQualifierPattern& rhs); |
775 | | |
776 | | [[nodiscard]] |
777 | | bool operator<(const AttributeQualifierPattern& lhs, |
778 | | const AttributeQualifier& rhs); |
779 | | |
780 | | [[nodiscard]] |
781 | | bool operator<(const AttributeQualifierPattern& lhs, |
782 | | const AttributeQualifierView& rhs); |
783 | | |
784 | | namespace common_internal { |
785 | | |
786 | | [[nodiscard]] |
787 | | inline const AttributeQualifierVariant& AsVariant( |
788 | 0 | const AttributeQualifier& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND) { |
789 | 0 | return qualifier.value_; |
790 | 0 | } |
791 | | |
792 | | [[nodiscard]] |
793 | | inline AttributeQualifierVariant&& AsVariant( |
794 | 0 | AttributeQualifier&& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND) { |
795 | 0 | return std::move(qualifier.value_); |
796 | 0 | } |
797 | | |
798 | | [[nodiscard]] |
799 | | inline const AttributeQualifierPatternVariant& AsVariant( |
800 | 0 | const AttributeQualifierPattern& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND) { |
801 | 0 | return qualifier.value_; |
802 | 0 | } |
803 | | |
804 | | [[nodiscard]] |
805 | | inline AttributeQualifierPatternVariant&& AsVariant( |
806 | 0 | AttributeQualifierPattern&& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND) { |
807 | 0 | return std::move(qualifier.value_); |
808 | 0 | } |
809 | | |
810 | | [[nodiscard]] |
811 | | inline const AttributeQualifierViewVariant& AsVariant( |
812 | 0 | const AttributeQualifierView& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND) { |
813 | 0 | return qualifier.value_; |
814 | 0 | } |
815 | | |
816 | | [[nodiscard]] |
817 | | inline AttributeQualifierViewVariant&& AsVariant( |
818 | 0 | AttributeQualifierView&& qualifier ABSL_ATTRIBUTE_LIFETIME_BOUND) { |
819 | 0 | return std::move(qualifier.value_); |
820 | 0 | } |
821 | | |
822 | | } // namespace common_internal |
823 | | |
824 | | // Attribute represents resolved attribute path. |
825 | | class Attribute { |
826 | | public: |
827 | | explicit Attribute(std::string variable_name) |
828 | 0 | : Attribute(std::move(variable_name), {}) {} |
829 | | |
830 | | Attribute(std::string variable_name, |
831 | | std::vector<AttributeQualifier> qualifier_path) |
832 | 0 | : impl_(std::make_shared<Impl>(std::move(variable_name), |
833 | 0 | std::move(qualifier_path))) {} |
834 | | |
835 | 0 | absl::string_view variable_name() const { return impl_->variable_name; } |
836 | | |
837 | 0 | bool has_variable_name() const { return !impl_->variable_name.empty(); } |
838 | | |
839 | 0 | absl::Span<const AttributeQualifier> qualifier_path() const { |
840 | 0 | return impl_->qualifier_path; |
841 | 0 | } |
842 | | |
843 | | bool operator==(const Attribute& other) const; |
844 | | |
845 | | bool operator<(const Attribute& other) const; |
846 | | |
847 | | absl::StatusOr<std::string> AsString() const; |
848 | | |
849 | | [[nodiscard]] |
850 | | std::string ToString() const; |
851 | | |
852 | | private: |
853 | | struct Impl final { |
854 | | Impl(std::string variable_name, |
855 | | std::vector<AttributeQualifier> qualifier_path) |
856 | 0 | : variable_name(std::move(variable_name)), |
857 | 0 | qualifier_path(std::move(qualifier_path)) {} |
858 | | |
859 | | std::string variable_name; |
860 | | std::vector<AttributeQualifier> qualifier_path; |
861 | | }; |
862 | | |
863 | | std::shared_ptr<const Impl> impl_; |
864 | | }; |
865 | | |
866 | | template <typename S> |
867 | | void AbslStringify(S& sink, const Attribute& attribute) { |
868 | | sink.Append(attribute.ToString()); |
869 | | } |
870 | | |
871 | | // AttributePattern is a fully-qualified absolute attribute path pattern. |
872 | | // Supported segments steps in the path are: |
873 | | // - field selection; |
874 | | // - map lookup by key; |
875 | | // - list access by index. |
876 | | class AttributePattern { |
877 | | public: |
878 | | // MatchType enum specifies how closely pattern is matching the attribute: |
879 | | enum class MatchType { |
880 | | NONE, // Pattern does not match attribute itself nor its children |
881 | | PARTIAL, // Pattern matches an entity nested within attribute; |
882 | | FULL // Pattern matches an attribute itself. |
883 | | }; |
884 | | |
885 | | explicit AttributePattern( |
886 | | std::string variable, |
887 | | std::vector<AttributeQualifierPattern> qualifier_path = {}) |
888 | | : variable_(std::move(variable)), |
889 | 0 | qualifier_path_(std::move(qualifier_path)) {} |
890 | | |
891 | 0 | absl::string_view variable() const { return variable_; } |
892 | | |
893 | 0 | absl::Span<const AttributeQualifierPattern> qualifier_path() const { |
894 | 0 | return qualifier_path_; |
895 | 0 | } |
896 | | |
897 | | // Matches the pattern to an attribute. |
898 | | // Distinguishes between no-match, partial match and full match cases. |
899 | 0 | MatchType IsMatch(const Attribute& attribute) const { |
900 | 0 | MatchType result = MatchType::NONE; |
901 | 0 | if (attribute.variable_name() != variable_) { |
902 | 0 | return result; |
903 | 0 | } |
904 | | |
905 | 0 | auto max_index = qualifier_path().size(); |
906 | 0 | result = MatchType::FULL; |
907 | 0 | if (qualifier_path().size() > attribute.qualifier_path().size()) { |
908 | 0 | max_index = attribute.qualifier_path().size(); |
909 | 0 | result = MatchType::PARTIAL; |
910 | 0 | } |
911 | |
|
912 | 0 | for (size_t i = 0; i < max_index; i++) { |
913 | 0 | if (!(qualifier_path()[i].IsMatch(attribute.qualifier_path()[i]))) { |
914 | 0 | return MatchType::NONE; |
915 | 0 | } |
916 | 0 | } |
917 | 0 | return result; |
918 | 0 | } |
919 | | |
920 | | [[nodiscard]] |
921 | | std::string ToString() const; |
922 | | |
923 | | private: |
924 | | std::string variable_; |
925 | | std::vector<AttributeQualifierPattern> qualifier_path_; |
926 | | }; |
927 | | |
928 | | template <typename S> |
929 | | void AbslStringify(S& sink, const AttributePattern& pattern) { |
930 | | sink.Append(pattern.ToString()); |
931 | | } |
932 | | |
933 | | [[nodiscard]] |
934 | | bool operator==(const AttributePattern& lhs, const AttributePattern& rhs); |
935 | | |
936 | | [[nodiscard]] |
937 | | inline bool operator!=(const AttributePattern& lhs, |
938 | 0 | const AttributePattern& rhs) { |
939 | 0 | return !operator==(lhs, rhs); |
940 | 0 | } |
941 | | |
942 | | struct FieldSpecifier { |
943 | | int64_t number; |
944 | | std::string name; |
945 | | }; |
946 | | |
947 | | using SelectQualifier = std::variant<FieldSpecifier, AttributeQualifier>; |
948 | | |
949 | | } // namespace cel |
950 | | |
951 | | #endif // THIRD_PARTY_CEL_CPP_BASE_ATTRIBUTE_H_ |