Coverage Report

Created: 2026-05-27 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/values/struct_value_variant.h
Line
Count
Source
1
// Copyright 2025 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_VALUES_STRUCT_VALUE_VARIANT_H_
16
#define THIRD_PARTY_CEL_CPP_COMMON_VALUES_STRUCT_VALUE_VARIANT_H_
17
18
#include <cstddef>
19
#include <cstdint>
20
#include <type_traits>
21
22
#include "absl/base/attributes.h"
23
#include "absl/base/nullability.h"
24
#include "absl/log/absl_check.h"
25
#include "absl/meta/type_traits.h"
26
#include "absl/utility/utility.h"
27
#include "common/values/custom_struct_value.h"
28
#include "common/values/legacy_struct_value.h"
29
#include "common/values/parsed_message_value.h"
30
31
namespace cel::common_internal {
32
33
enum class StructValueIndex : uint16_t {
34
  kParsedMessage = 0,
35
  kCustom,
36
  kLegacy,
37
};
38
39
template <typename T>
40
struct StructValueAlternative;
41
42
template <>
43
struct StructValueAlternative<CustomStructValue> {
44
  static constexpr StructValueIndex kIndex = StructValueIndex::kCustom;
45
};
46
47
template <>
48
struct StructValueAlternative<ParsedMessageValue> {
49
  static constexpr StructValueIndex kIndex = StructValueIndex::kParsedMessage;
50
};
51
52
template <>
53
struct StructValueAlternative<LegacyStructValue> {
54
  static constexpr StructValueIndex kIndex = StructValueIndex::kLegacy;
55
};
56
57
template <typename T, typename = void>
58
struct IsStructValueAlternative : std::false_type {};
59
60
template <typename T>
61
struct IsStructValueAlternative<
62
    T, std::void_t<decltype(StructValueAlternative<T>{})>> : std::true_type {};
63
64
template <typename T>
65
inline constexpr bool IsStructValueAlternativeV =
66
    IsStructValueAlternative<T>::value;
67
68
inline constexpr size_t kStructValueVariantAlign = 8;
69
inline constexpr size_t kStructValueVariantSize = 24;
70
71
// StructValueVariant is a subset of alternatives from the main ValueVariant
72
// that is only structs. It is not stored directly in ValueVariant.
73
class alignas(kStructValueVariantAlign) StructValueVariant final {
74
 public:
75
  StructValueVariant()
76
0
      : StructValueVariant(absl::in_place_type<ParsedMessageValue>) {}
77
78
  StructValueVariant(const StructValueVariant&) = default;
79
  StructValueVariant(StructValueVariant&&) = default;
80
  StructValueVariant& operator=(const StructValueVariant&) = default;
81
  StructValueVariant& operator=(StructValueVariant&&) = default;
82
83
  template <typename T, typename... Args>
84
  explicit StructValueVariant(absl::in_place_type_t<T>, Args&&... args)
85
284
      : index_(StructValueAlternative<T>::kIndex) {
86
284
    static_assert(alignof(T) <= kStructValueVariantAlign);
87
284
    static_assert(sizeof(T) <= kStructValueVariantSize);
88
284
    static_assert(std::is_trivially_copyable_v<T>);
89
90
284
    ::new (static_cast<void*>(&raw_[0])) T(std::forward<Args>(args)...);
91
284
  }
Unexecuted instantiation: cel::common_internal::StructValueVariant::StructValueVariant<cel::ParsedMessageValue>(std::__1::in_place_type_t<cel::ParsedMessageValue>)
Unexecuted instantiation: cel::common_internal::StructValueVariant::StructValueVariant<cel::ParsedMessageValue, cel::ParsedMessageValue const&>(std::__1::in_place_type_t<cel::ParsedMessageValue>, cel::ParsedMessageValue const&)
Unexecuted instantiation: cel::common_internal::StructValueVariant::StructValueVariant<cel::CustomStructValue, cel::CustomStructValue const&>(std::__1::in_place_type_t<cel::CustomStructValue>, cel::CustomStructValue const&)
Unexecuted instantiation: cel::common_internal::StructValueVariant::StructValueVariant<cel::ParsedMessageValue, cel::ParsedMessageValue>(std::__1::in_place_type_t<cel::ParsedMessageValue>, cel::ParsedMessageValue&&)
Unexecuted instantiation: cel::common_internal::StructValueVariant::StructValueVariant<cel::common_internal::LegacyStructValue, cel::common_internal::LegacyStructValue>(std::__1::in_place_type_t<cel::common_internal::LegacyStructValue>, cel::common_internal::LegacyStructValue&&)
cel::common_internal::StructValueVariant::StructValueVariant<cel::common_internal::LegacyStructValue, cel::common_internal::LegacyStructValue const&>(std::__1::in_place_type_t<cel::common_internal::LegacyStructValue>, cel::common_internal::LegacyStructValue const&)
Line
Count
Source
85
284
      : index_(StructValueAlternative<T>::kIndex) {
86
284
    static_assert(alignof(T) <= kStructValueVariantAlign);
87
284
    static_assert(sizeof(T) <= kStructValueVariantSize);
88
284
    static_assert(std::is_trivially_copyable_v<T>);
89
90
284
    ::new (static_cast<void*>(&raw_[0])) T(std::forward<Args>(args)...);
91
284
  }
Unexecuted instantiation: cel::common_internal::StructValueVariant::StructValueVariant<cel::CustomStructValue, cel::CustomStructValue>(std::__1::in_place_type_t<cel::CustomStructValue>, cel::CustomStructValue&&)
92
93
  template <typename T, typename = std::enable_if_t<
94
                            IsStructValueAlternativeV<absl::remove_cvref_t<T>>>>
95
  explicit StructValueVariant(T&& value)
96
      : StructValueVariant(absl::in_place_type<absl::remove_cvref_t<T>>,
97
                           std::forward<T>(value)) {}
98
99
  template <typename T>
100
  void Assign(T&& value) {
101
    using U = absl::remove_cvref_t<T>;
102
103
    static_assert(alignof(U) <= kStructValueVariantAlign);
104
    static_assert(sizeof(U) <= kStructValueVariantSize);
105
    static_assert(std::is_trivially_copyable_v<U>);
106
107
    index_ = StructValueAlternative<U>::kIndex;
108
    ::new (static_cast<void*>(&raw_[0])) U(std::forward<T>(value));
109
  }
110
111
  template <typename T>
112
0
  bool Is() const {
113
0
    return index_ == StructValueAlternative<T>::kIndex;
114
0
  }
Unexecuted instantiation: bool cel::common_internal::StructValueVariant::Is<cel::ParsedMessageValue>() const
Unexecuted instantiation: bool cel::common_internal::StructValueVariant::Is<cel::CustomStructValue>() const
Unexecuted instantiation: bool cel::common_internal::StructValueVariant::Is<cel::common_internal::LegacyStructValue>() const
115
116
  template <typename T>
117
      T& Get() & ABSL_ATTRIBUTE_LIFETIME_BOUND {
118
    ABSL_DCHECK(Is<T>());
119
120
    return *At<T>();
121
  }
122
123
  template <typename T>
124
284
  const T& Get() const& ABSL_ATTRIBUTE_LIFETIME_BOUND {
125
284
    ABSL_DCHECK(Is<T>());
126
127
284
    return *At<T>();
128
284
  }
Unexecuted instantiation: cel::CustomStructValue const& cel::common_internal::StructValueVariant::Get<cel::CustomStructValue>() const &
cel::common_internal::LegacyStructValue const& cel::common_internal::StructValueVariant::Get<cel::common_internal::LegacyStructValue>() const &
Line
Count
Source
124
284
  const T& Get() const& ABSL_ATTRIBUTE_LIFETIME_BOUND {
125
284
    ABSL_DCHECK(Is<T>());
126
127
284
    return *At<T>();
128
284
  }
Unexecuted instantiation: cel::ParsedMessageValue const& cel::common_internal::StructValueVariant::Get<cel::ParsedMessageValue>() const &
129
130
  template <typename T>
131
0
      T&& Get() && ABSL_ATTRIBUTE_LIFETIME_BOUND {
132
0
    ABSL_DCHECK(Is<T>());
133
134
0
    return std::move(*At<T>());
135
0
  }
136
137
  template <typename T>
138
  const T&& Get() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND {
139
    ABSL_DCHECK(Is<T>());
140
141
    return std::move(*At<T>());
142
  }
143
144
  template <typename T>
145
0
  T* absl_nullable As() ABSL_ATTRIBUTE_LIFETIME_BOUND {
146
0
    if (Is<T>()) {
147
0
      return At<T>();
148
0
    }
149
0
    return nullptr;
150
0
  }
151
152
  template <typename T>
153
0
  const T* absl_nullable As() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
154
0
    if (Is<T>()) {
155
0
      return At<T>();
156
0
    }
157
0
    return nullptr;
158
0
  }
159
160
  template <typename Visitor>
161
284
  decltype(auto) Visit(Visitor&& visitor) const {
162
284
    switch (index_) {
163
0
      case StructValueIndex::kCustom:
164
0
        return std::forward<Visitor>(visitor)(Get<CustomStructValue>());
165
0
      case StructValueIndex::kParsedMessage:
166
0
        return std::forward<Visitor>(visitor)(Get<ParsedMessageValue>());
167
284
      case StructValueIndex::kLegacy:
168
284
        return std::forward<Visitor>(visitor)(Get<LegacyStructValue>());
169
284
    }
170
284
  }
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::GetRuntimeType() const::$_0>(cel::StructValue::GetRuntimeType() const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::GetTypeName() const::$_0>(cel::StructValue::GetTypeName() const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::GetTypeId() const::$_0>(cel::StructValue::GetTypeId() const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::DebugString() const::$_0>(cel::StructValue::DebugString() const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::SerializeTo(google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::io::ZeroCopyOutputStream*) const::$_0>(cel::StructValue::SerializeTo(google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::io::ZeroCopyOutputStream*) const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::ConvertToJson(google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Message*) const::$_0>(cel::StructValue::ConvertToJson(google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Message*) const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::ConvertToJsonObject(google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Message*) const::$_0>(cel::StructValue::ConvertToJsonObject(google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Message*) const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0>(cel::StructValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::IsZeroValue() const::$_0>(cel::StructValue::IsZeroValue() const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::HasFieldByName(std::__1::basic_string_view<char, std::__1::char_traits<char> >) const::$_0>(cel::StructValue::HasFieldByName(std::__1::basic_string_view<char, std::__1::char_traits<char> >) const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::HasFieldByNumber(long) const::$_0>(cel::StructValue::HasFieldByNumber(long) const::$_0&&) const
struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::GetFieldByName(std::__1::basic_string_view<char, std::__1::char_traits<char> >, cel::ProtoWrapperTypeOptions, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0>(cel::StructValue::GetFieldByName(std::__1::basic_string_view<char, std::__1::char_traits<char> >, cel::ProtoWrapperTypeOptions, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0&&) const
Line
Count
Source
161
284
  decltype(auto) Visit(Visitor&& visitor) const {
162
284
    switch (index_) {
163
0
      case StructValueIndex::kCustom:
164
0
        return std::forward<Visitor>(visitor)(Get<CustomStructValue>());
165
0
      case StructValueIndex::kParsedMessage:
166
0
        return std::forward<Visitor>(visitor)(Get<ParsedMessageValue>());
167
284
      case StructValueIndex::kLegacy:
168
284
        return std::forward<Visitor>(visitor)(Get<LegacyStructValue>());
169
284
    }
170
284
  }
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::GetFieldByNumber(long, cel::ProtoWrapperTypeOptions, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0>(cel::StructValue::GetFieldByNumber(long, cel::ProtoWrapperTypeOptions, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::ForEachField(absl::lts_20260107::FunctionRef<absl::lts_20260107::StatusOr<bool> (std::__1::basic_string_view<char, std::__1::char_traits<char> >, cel::Value const&)>, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*) const::$_0>(cel::StructValue::ForEachField(absl::lts_20260107::FunctionRef<absl::lts_20260107::StatusOr<bool> (std::__1::basic_string_view<char, std::__1::char_traits<char> >, cel::Value const&)>, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*) const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::Qualify(absl::lts_20260107::Span<std::__1::variant<cel::FieldSpecifier, cel::AttributeQualifier> const>, bool, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*, int*) const::$_0>(cel::StructValue::Qualify(absl::lts_20260107::Span<std::__1::variant<cel::FieldSpecifier, cel::AttributeQualifier> const>, bool, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*, int*) const::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::ToValueVariant() const &::$_0>(cel::StructValue::ToValueVariant() const &::$_0&&) const
Unexecuted instantiation: struct_value.cc:decltype(auto) cel::common_internal::StructValueVariant::Visit<cel::StructValue::ToValueVariant() &&::$_0>(cel::StructValue::ToValueVariant() &&::$_0&&) const
171
172
0
  friend void swap(StructValueVariant& lhs, StructValueVariant& rhs) noexcept {
173
0
    using std::swap;
174
0
    swap(lhs.index_, rhs.index_);
175
0
    swap(lhs.raw_, rhs.raw_);
176
0
  }
177
178
 private:
179
  template <typename T>
180
  ABSL_ATTRIBUTE_ALWAYS_INLINE T* absl_nonnull At()
181
0
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
182
0
    static_assert(alignof(T) <= kStructValueVariantAlign);
183
0
    static_assert(sizeof(T) <= kStructValueVariantSize);
184
0
    static_assert(std::is_trivially_copyable_v<T>);
185
186
0
    return std::launder(reinterpret_cast<T*>(&raw_[0]));
187
0
  }
188
189
  template <typename T>
190
  ABSL_ATTRIBUTE_ALWAYS_INLINE const T* absl_nonnull At() const
191
284
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
192
284
    static_assert(alignof(T) <= kStructValueVariantAlign);
193
284
    static_assert(sizeof(T) <= kStructValueVariantSize);
194
284
    static_assert(std::is_trivially_copyable_v<T>);
195
196
284
    return std::launder(reinterpret_cast<const T*>(&raw_[0]));
197
284
  }
Unexecuted instantiation: cel::CustomStructValue const* cel::common_internal::StructValueVariant::At<cel::CustomStructValue>() const
cel::common_internal::LegacyStructValue const* cel::common_internal::StructValueVariant::At<cel::common_internal::LegacyStructValue>() const
Line
Count
Source
191
284
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
192
284
    static_assert(alignof(T) <= kStructValueVariantAlign);
193
284
    static_assert(sizeof(T) <= kStructValueVariantSize);
194
284
    static_assert(std::is_trivially_copyable_v<T>);
195
196
284
    return std::launder(reinterpret_cast<const T*>(&raw_[0]));
197
284
  }
Unexecuted instantiation: cel::ParsedMessageValue const* cel::common_internal::StructValueVariant::At<cel::ParsedMessageValue>() const
198
199
  StructValueIndex index_ = StructValueIndex::kCustom;
200
  alignas(8) std::byte raw_[kStructValueVariantSize];
201
};
202
203
}  // namespace cel::common_internal
204
205
#endif  // THIRD_PARTY_CEL_CPP_COMMON_VALUES_STRUCT_VALUE_VARIANT_H_