Coverage Report

Created: 2026-10-09 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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_