Coverage Report

Created: 2025-11-29 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/constant.h
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
#ifndef THIRD_PARTY_CEL_CPP_COMMON_CONSTANT_H_
16
#define THIRD_PARTY_CEL_CPP_COMMON_CONSTANT_H_
17
18
#include <cstddef>
19
#include <cstdint>
20
#include <string>
21
#include <type_traits>
22
#include <utility>
23
24
#include "absl/base/attributes.h"
25
#include "absl/functional/overload.h"
26
#include "absl/strings/string_view.h"
27
#include "absl/time/time.h"
28
#include "absl/types/variant.h"
29
30
namespace cel {
31
32
class Expr;
33
class Constant;
34
class BytesConstant;
35
class StringConstant;
36
class VariableDecl;
37
38
class BytesConstant final : public std::string {
39
 public:
40
1.35k
  explicit BytesConstant(std::string string) : std::string(std::move(string)) {}
41
42
  explicit BytesConstant(absl::string_view string)
43
0
      : BytesConstant(std::string(string)) {}
44
45
  explicit BytesConstant(const char* string)
46
0
      : BytesConstant(absl::NullSafeStringView(string)) {}
47
48
  BytesConstant() = default;
49
0
  BytesConstant(const BytesConstant&) = default;
50
8.25k
  BytesConstant(BytesConstant&&) = default;
51
0
  BytesConstant& operator=(const BytesConstant&) = default;
52
0
  BytesConstant& operator=(BytesConstant&&) = default;
53
54
  BytesConstant(const StringConstant&) = delete;
55
  BytesConstant(StringConstant&&) = delete;
56
  BytesConstant& operator=(const StringConstant&) = delete;
57
  BytesConstant& operator=(StringConstant&&) = delete;
58
59
 private:
60
  static const BytesConstant& default_instance();
61
62
  friend class Constant;
63
};
64
65
class StringConstant final : public std::string {
66
 public:
67
  explicit StringConstant(std::string string)
68
393k
      : std::string(std::move(string)) {}
69
70
  explicit StringConstant(absl::string_view string)
71
1.86k
      : StringConstant(std::string(string)) {}
72
73
  explicit StringConstant(const char* string)
74
0
      : StringConstant(absl::NullSafeStringView(string)) {}
75
76
  StringConstant() = default;
77
0
  StringConstant(const StringConstant&) = default;
78
3.14M
  StringConstant(StringConstant&&) = default;
79
0
  StringConstant& operator=(const StringConstant&) = default;
80
0
  StringConstant& operator=(StringConstant&&) = default;
81
82
  StringConstant(const BytesConstant&) = delete;
83
  StringConstant(BytesConstant&&) = delete;
84
  StringConstant& operator=(const BytesConstant&) = delete;
85
  StringConstant& operator=(BytesConstant&&) = delete;
86
87
 private:
88
  static const StringConstant& default_instance();
89
90
  friend class Constant;
91
};
92
93
namespace common_internal {
94
95
template <size_t I, typename U, typename T, typename... Ts>
96
struct ConstantKindIndexer {
97
  static constexpr size_t value =
98
      std::conditional_t<std::is_same_v<U, T>,
99
                         std::integral_constant<size_t, I>,
100
                         ConstantKindIndexer<I + 1, U, Ts...>>::value;
101
};
102
103
template <size_t I, typename U, typename T>
104
struct ConstantKindIndexer<I, U, T> {
105
  static constexpr size_t value = std::conditional_t<
106
      std::is_same_v<U, T>, std::integral_constant<size_t, I>,
107
      std::integral_constant<size_t, absl::variant_npos>>::value;
108
};
109
110
template <typename... Ts>
111
struct ConstantKindImpl {
112
  using VariantType = absl::variant<Ts...>;
113
114
  template <typename U>
115
0
  static constexpr size_t IndexOf() {
116
0
    return ConstantKindIndexer<0, U, Ts...>::value;
117
0
  }
Unexecuted instantiation: unsigned long cel::common_internal::ConstantKindImpl<std::__1::monostate, decltype(nullptr), bool, long, unsigned long, double, cel::BytesConstant, cel::StringConstant, absl::lts_20250512::Duration, absl::lts_20250512::Time>::IndexOf<std::__1::monostate>()
Unexecuted instantiation: unsigned long cel::common_internal::ConstantKindImpl<std::__1::monostate, decltype(nullptr), bool, long, unsigned long, double, cel::BytesConstant, cel::StringConstant, absl::lts_20250512::Duration, absl::lts_20250512::Time>::IndexOf<decltype(nullptr)>()
Unexecuted instantiation: unsigned long cel::common_internal::ConstantKindImpl<std::__1::monostate, decltype(nullptr), bool, long, unsigned long, double, cel::BytesConstant, cel::StringConstant, absl::lts_20250512::Duration, absl::lts_20250512::Time>::IndexOf<bool>()
Unexecuted instantiation: unsigned long cel::common_internal::ConstantKindImpl<std::__1::monostate, decltype(nullptr), bool, long, unsigned long, double, cel::BytesConstant, cel::StringConstant, absl::lts_20250512::Duration, absl::lts_20250512::Time>::IndexOf<long>()
Unexecuted instantiation: unsigned long cel::common_internal::ConstantKindImpl<std::__1::monostate, decltype(nullptr), bool, long, unsigned long, double, cel::BytesConstant, cel::StringConstant, absl::lts_20250512::Duration, absl::lts_20250512::Time>::IndexOf<unsigned long>()
Unexecuted instantiation: unsigned long cel::common_internal::ConstantKindImpl<std::__1::monostate, decltype(nullptr), bool, long, unsigned long, double, cel::BytesConstant, cel::StringConstant, absl::lts_20250512::Duration, absl::lts_20250512::Time>::IndexOf<double>()
Unexecuted instantiation: unsigned long cel::common_internal::ConstantKindImpl<std::__1::monostate, decltype(nullptr), bool, long, unsigned long, double, cel::BytesConstant, cel::StringConstant, absl::lts_20250512::Duration, absl::lts_20250512::Time>::IndexOf<cel::BytesConstant>()
Unexecuted instantiation: unsigned long cel::common_internal::ConstantKindImpl<std::__1::monostate, decltype(nullptr), bool, long, unsigned long, double, cel::BytesConstant, cel::StringConstant, absl::lts_20250512::Duration, absl::lts_20250512::Time>::IndexOf<cel::StringConstant>()
Unexecuted instantiation: unsigned long cel::common_internal::ConstantKindImpl<std::__1::monostate, decltype(nullptr), bool, long, unsigned long, double, cel::BytesConstant, cel::StringConstant, absl::lts_20250512::Duration, absl::lts_20250512::Time>::IndexOf<absl::lts_20250512::Duration>()
Unexecuted instantiation: unsigned long cel::common_internal::ConstantKindImpl<std::__1::monostate, decltype(nullptr), bool, long, unsigned long, double, cel::BytesConstant, cel::StringConstant, absl::lts_20250512::Duration, absl::lts_20250512::Time>::IndexOf<absl::lts_20250512::Time>()
Unexecuted instantiation: unsigned long cel::common_internal::ConstantKindImpl<std::__1::monostate, decltype(nullptr), bool, long, unsigned long, double, cel::BytesConstant, cel::StringConstant, absl::lts_20250512::Duration, absl::lts_20250512::Time>::IndexOf<void>()
118
};
119
120
using ConstantKind =
121
    ConstantKindImpl<absl::monostate, std::nullptr_t, bool, int64_t, uint64_t,
122
                     double, BytesConstant, StringConstant, absl::Duration,
123
                     absl::Time>;
124
125
static_assert(ConstantKind::IndexOf<absl::monostate>() == 0);
126
static_assert(ConstantKind::IndexOf<std::nullptr_t>() == 1);
127
static_assert(ConstantKind::IndexOf<bool>() == 2);
128
static_assert(ConstantKind::IndexOf<int64_t>() == 3);
129
static_assert(ConstantKind::IndexOf<uint64_t>() == 4);
130
static_assert(ConstantKind::IndexOf<double>() == 5);
131
static_assert(ConstantKind::IndexOf<BytesConstant>() == 6);
132
static_assert(ConstantKind::IndexOf<StringConstant>() == 7);
133
static_assert(ConstantKind::IndexOf<absl::Duration>() == 8);
134
static_assert(ConstantKind::IndexOf<absl::Time>() == 9);
135
static_assert(ConstantKind::IndexOf<void>() == absl::variant_npos);
136
137
}  // namespace common_internal
138
139
// Constant is a variant composed of all the literal types support by the Common
140
// Expression Language.
141
using ConstantKind = common_internal::ConstantKind::VariantType;
142
143
enum class ConstantKindCase {
144
  kUnspecified,
145
  kNull,
146
  kBool,
147
  kInt,
148
  kUint,
149
  kDouble,
150
  kBytes,
151
  kString,
152
  kDuration,
153
  kTimestamp,
154
};
155
156
template <typename U>
157
constexpr size_t ConstantKindIndexOf() {
158
  return common_internal::ConstantKind::IndexOf<U>();
159
}
160
161
// Returns the `null` literal.
162
std::string FormatNullConstant();
163
0
inline std::string FormatNullConstant(std::nullptr_t) {
164
0
  return FormatNullConstant();
165
0
}
166
167
// Formats `value` as a bool literal.
168
std::string FormatBoolConstant(bool value);
169
170
// Formats `value` as a int literal.
171
std::string FormatIntConstant(int64_t value);
172
173
// Formats `value` as a uint literal.
174
std::string FormatUintConstant(uint64_t value);
175
176
// Formats `value` as a double literal-like representation. Due to Common
177
// Expression Language not having NaN or infinity literals, the result will not
178
// always be syntactically valid.
179
std::string FormatDoubleConstant(double value);
180
181
// Formats `value` as a bytes literal.
182
std::string FormatBytesConstant(absl::string_view value);
183
184
// Formats `value` as a string literal.
185
std::string FormatStringConstant(absl::string_view value);
186
187
// Formats `value` as a duration constant.
188
std::string FormatDurationConstant(absl::Duration value);
189
190
// Formats `value` as a timestamp constant.
191
std::string FormatTimestampConstant(absl::Time value);
192
193
// Represents a primitive literal.
194
//
195
// This is similar as the primitives supported in the well-known type
196
// `google.protobuf.Value`, but richer so it can represent CEL's full range of
197
// primitives.
198
//
199
// Lists and structs are not included as constants as these aggregate types may
200
// contain [Expr][] elements which require evaluation and are thus not constant.
201
//
202
// Examples of constants include: `"hello"`, `b'bytes'`, `1u`, `4.2`, `-2`,
203
// `true`, `null`.
204
class Constant final {
205
 public:
206
2.21M
  Constant() = default;
207
0
  Constant(const Constant&) = default;
208
6.84M
  Constant(Constant&&) = default;
209
0
  Constant& operator=(const Constant&) = default;
210
1.10M
  Constant& operator=(Constant&&) = default;
211
212
0
  explicit Constant(ConstantKind kind) : kind_(std::move(kind)) {}
213
214
  ABSL_MUST_USE_RESULT const ConstantKind& kind() const
215
612k
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
216
612k
    return kind_;
217
612k
  }
218
219
  ABSL_DEPRECATED("Use kind()")
220
  ABSL_MUST_USE_RESULT const ConstantKind& constant_kind() const
221
0
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
222
0
    return kind();
223
0
  }
224
225
0
  ABSL_MUST_USE_RESULT bool has_value() const {
226
0
    return !absl::holds_alternative<absl::monostate>(kind());
227
0
  }
228
229
0
  ABSL_MUST_USE_RESULT bool has_null_value() const {
230
0
    return absl::holds_alternative<std::nullptr_t>(kind());
231
0
  }
232
233
0
  ABSL_MUST_USE_RESULT std::nullptr_t null_value() const { return nullptr; }
234
235
466
  void set_null_value() { mutable_kind().emplace<std::nullptr_t>(); }
236
237
0
  void set_null_value(std::nullptr_t) { set_null_value(); }
238
239
0
  ABSL_MUST_USE_RESULT bool has_bool_value() const {
240
0
    return absl::holds_alternative<bool>(kind());
241
0
  }
242
243
2.40k
  void set_bool_value(bool value) { mutable_kind().emplace<bool>(value); }
244
245
0
  ABSL_MUST_USE_RESULT bool bool_value() const { return get_value<bool>(); }
246
247
0
  ABSL_MUST_USE_RESULT bool has_int_value() const {
248
0
    return absl::holds_alternative<int64_t>(kind());
249
0
  }
250
251
696k
  void set_int_value(int64_t value) { mutable_kind().emplace<int64_t>(value); }
252
253
0
  ABSL_MUST_USE_RESULT int64_t int_value() const {
254
0
    return get_value<int64_t>();
255
0
  }
256
257
0
  ABSL_MUST_USE_RESULT bool has_uint_value() const {
258
0
    return absl::holds_alternative<uint64_t>(kind());
259
0
  }
260
261
1.71k
  void set_uint_value(uint64_t value) {
262
1.71k
    mutable_kind().emplace<uint64_t>(value);
263
1.71k
  }
264
265
0
  ABSL_MUST_USE_RESULT uint64_t uint_value() const {
266
0
    return get_value<uint64_t>();
267
0
  }
268
269
  ABSL_DEPRECATED("Use has_int_value")
270
0
  ABSL_MUST_USE_RESULT bool has_int64_value() const { return has_int_value(); }
271
272
  ABSL_DEPRECATED("Use set_int_value()")
273
0
  void set_int64_value(int64_t value) { set_int_value(value); }
274
275
  ABSL_DEPRECATED("Use int_value()")
276
0
  ABSL_MUST_USE_RESULT int64_t int64_value() const { return int_value(); }
277
278
  ABSL_DEPRECATED("Use has_uint_value()")
279
0
  ABSL_MUST_USE_RESULT bool has_uint64_value() const {
280
0
    return has_uint_value();
281
0
  }
282
283
  ABSL_DEPRECATED("Use set_uint_value()")
284
0
  void set_uint64_value(uint64_t value) { set_uint_value(value); }
285
286
  ABSL_DEPRECATED("Use uint_value()")
287
0
  ABSL_MUST_USE_RESULT uint64_t uint64_value() const { return uint_value(); }
288
289
0
  ABSL_MUST_USE_RESULT bool has_double_value() const {
290
0
    return absl::holds_alternative<double>(kind());
291
0
  }
292
293
10.6k
  void set_double_value(double value) { mutable_kind().emplace<double>(value); }
294
295
0
  ABSL_MUST_USE_RESULT double double_value() const {
296
0
    return get_value<double>();
297
0
  }
298
299
0
  ABSL_MUST_USE_RESULT bool has_bytes_value() const {
300
0
    return absl::holds_alternative<BytesConstant>(kind());
301
0
  }
302
303
1.35k
  void set_bytes_value(BytesConstant value) {
304
1.35k
    mutable_kind().emplace<BytesConstant>(std::move(value));
305
1.35k
  }
306
307
1.35k
  void set_bytes_value(std::string value) {
308
1.35k
    set_bytes_value(BytesConstant{std::move(value)});
309
1.35k
  }
310
311
0
  void set_bytes_value(absl::string_view value) {
312
0
    set_bytes_value(BytesConstant{value});
313
0
  }
314
315
0
  void set_bytes_value(const char* value) {
316
0
    set_bytes_value(absl::NullSafeStringView(value));
317
0
  }
318
319
  ABSL_MUST_USE_RESULT const std::string& bytes_value() const
320
0
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
321
0
    if (const auto* alt = absl::get_if<BytesConstant>(&kind()); alt) {
322
0
      return *alt;
323
0
    }
324
0
    return BytesConstant::default_instance();
325
0
  }
326
327
0
  ABSL_MUST_USE_RESULT std::string release_bytes_value() {
328
0
    std::string string;
329
0
    if (auto* alt = absl::get_if<BytesConstant>(&mutable_kind()); alt) {
330
0
      string.swap(*alt);
331
0
    }
332
0
    mutable_kind().emplace<absl::monostate>();
333
0
    return string;
334
0
  }
335
336
0
  ABSL_MUST_USE_RESULT bool has_string_value() const {
337
0
    return absl::holds_alternative<StringConstant>(kind());
338
0
  }
339
340
393k
  void set_string_value(StringConstant value) {
341
393k
    mutable_kind().emplace<StringConstant>(std::move(value));
342
393k
  }
343
344
391k
  void set_string_value(std::string value) {
345
391k
    set_string_value(StringConstant{std::move(value)});
346
391k
  }
347
348
1.86k
  void set_string_value(absl::string_view value) {
349
1.86k
    set_string_value(StringConstant{value});
350
1.86k
  }
351
352
1.86k
  void set_string_value(const char* value) {
353
1.86k
    set_string_value(absl::NullSafeStringView(value));
354
1.86k
  }
355
356
  ABSL_MUST_USE_RESULT const std::string& string_value() const
357
0
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
358
0
    if (const auto* alt = absl::get_if<StringConstant>(&kind()); alt) {
359
0
      return *alt;
360
0
    }
361
0
    return StringConstant::default_instance();
362
0
  }
363
364
0
  ABSL_MUST_USE_RESULT std::string release_string_value() {
365
0
    std::string string;
366
0
    if (auto* alt = absl::get_if<StringConstant>(&mutable_kind()); alt) {
367
0
      string.swap(*alt);
368
0
    }
369
0
    mutable_kind().emplace<absl::monostate>();
370
0
    return string;
371
0
  }
372
373
  ABSL_DEPRECATED("duration is no longer considered a builtin type")
374
0
  ABSL_MUST_USE_RESULT bool has_duration_value() const {
375
0
    return absl::holds_alternative<absl::Duration>(kind());
376
0
  }
377
378
  ABSL_DEPRECATED("duration is no longer considered a builtin type")
379
0
  void set_duration_value(absl::Duration value) {
380
0
    mutable_kind().emplace<absl::Duration>(value);
381
0
  }
382
383
  ABSL_DEPRECATED("duration is no longer considered a builtin type")
384
0
  ABSL_MUST_USE_RESULT absl::Duration duration_value() const {
385
0
    return get_value<absl::Duration>();
386
0
  }
387
388
  ABSL_DEPRECATED("timestamp is no longer considered a builtin type")
389
0
  ABSL_MUST_USE_RESULT bool has_timestamp_value() const {
390
0
    return absl::holds_alternative<absl::Time>(kind());
391
0
  }
392
393
  ABSL_DEPRECATED("timestamp is no longer considered a builtin type")
394
0
  void set_timestamp_value(absl::Time value) {
395
0
    mutable_kind().emplace<absl::Time>(value);
396
0
  }
397
398
  ABSL_DEPRECATED("timestamp is no longer considered a builtin type")
399
0
  ABSL_MUST_USE_RESULT absl::Time timestamp_value() const {
400
0
    return get_value<absl::Time>();
401
0
  }
402
403
  ABSL_DEPRECATED("Use has_timestamp_value()")
404
0
  ABSL_MUST_USE_RESULT bool has_time_value() const {
405
0
    return has_timestamp_value();
406
0
  }
407
408
  ABSL_DEPRECATED("Use set_timestamp_value()")
409
0
  void set_time_value(absl::Time value) { set_timestamp_value(value); }
410
411
  ABSL_DEPRECATED("Use timestamp_value()")
412
0
  ABSL_MUST_USE_RESULT absl::Time time_value() const {
413
0
    return timestamp_value();
414
0
  }
415
416
0
  ConstantKindCase kind_case() const {
417
0
    static_assert(absl::variant_size_v<ConstantKind> == 10);
418
0
    if (kind_.index() <= 10) {
419
0
      return static_cast<ConstantKindCase>(kind_.index());
420
0
    }
421
0
    return ConstantKindCase::kUnspecified;
422
0
  }
423
424
 private:
425
  friend class Expr;
426
  friend class VariableDecl;
427
428
  static const Constant& default_instance();
429
430
  ABSL_MUST_USE_RESULT ConstantKind& mutable_kind()
431
1.10M
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
432
1.10M
    return kind_;
433
1.10M
  }
434
435
  template <typename T>
436
0
  T get_value() const {
437
0
    if (const auto* alt = absl::get_if<T>(&kind()); alt) {
438
0
      return *alt;
439
0
    }
440
0
    return T{};
441
0
  }
Unexecuted instantiation: bool cel::Constant::get_value<bool>() const
Unexecuted instantiation: long cel::Constant::get_value<long>() const
Unexecuted instantiation: unsigned long cel::Constant::get_value<unsigned long>() const
Unexecuted instantiation: double cel::Constant::get_value<double>() const
Unexecuted instantiation: absl::lts_20250512::Duration cel::Constant::get_value<absl::lts_20250512::Duration>() const
Unexecuted instantiation: absl::lts_20250512::Time cel::Constant::get_value<absl::lts_20250512::Time>() const
442
443
  ConstantKind kind_;
444
};
445
446
0
inline bool operator==(const Constant& lhs, const Constant& rhs) {
447
0
  return lhs.kind() == rhs.kind();
448
0
}
449
450
0
inline bool operator!=(const Constant& lhs, const Constant& rhs) {
451
0
  return lhs.kind() != rhs.kind();
452
0
}
453
454
template <typename Sink>
455
void AbslStringify(Sink& sink, const Constant& constant) {
456
  absl::visit(
457
      absl::Overload(
458
          [&sink](absl::monostate) -> void { sink.Append("<unspecified>"); },
459
          [&sink](std::nullptr_t value) -> void {
460
            sink.Append(FormatNullConstant(value));
461
          },
462
          [&sink](bool value) -> void {
463
            sink.Append(FormatBoolConstant(value));
464
          },
465
          [&sink](int64_t value) -> void {
466
            sink.Append(FormatIntConstant(value));
467
          },
468
          [&sink](uint64_t value) -> void {
469
            sink.Append(FormatUintConstant(value));
470
          },
471
          [&sink](double value) -> void {
472
            sink.Append(FormatDoubleConstant(value));
473
          },
474
          [&sink](const BytesConstant& value) -> void {
475
            sink.Append(FormatBytesConstant(value));
476
          },
477
          [&sink](const StringConstant& value) -> void {
478
            sink.Append(FormatStringConstant(value));
479
          },
480
          [&sink](absl::Duration value) -> void {
481
            sink.Append(FormatDurationConstant(value));
482
          },
483
          [&sink](absl::Time value) -> void {
484
            sink.Append(FormatTimestampConstant(value));
485
          }),
486
      constant.kind());
487
}
488
489
}  // namespace cel
490
491
#endif  // THIRD_PARTY_CEL_CPP_COMMON_CONSTANT_H_