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/values.h
Line
Count
Source
1
// Copyright 2023 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
// IWYU pragma: private
16
17
#ifndef THIRD_PARTY_CEL_CPP_COMMON_VALUES_VALUES_H_
18
#define THIRD_PARTY_CEL_CPP_COMMON_VALUES_VALUES_H_
19
20
#include <cstddef>
21
#include <cstdint>
22
#include <memory>
23
#include <utility>
24
25
#include "absl/base/attributes.h"
26
#include "absl/base/nullability.h"
27
#include "absl/functional/function_ref.h"
28
#include "absl/status/status.h"
29
#include "absl/status/statusor.h"
30
#include "absl/strings/string_view.h"
31
#include "absl/types/optional.h"
32
#include "absl/types/span.h"
33
#include "base/attribute.h"
34
#include "runtime/runtime_options.h"
35
#include "google/protobuf/arena.h"
36
#include "google/protobuf/descriptor.h"
37
#include "google/protobuf/message.h"
38
39
// absl::Cord is trivially relocatable IFF we are not using ASan or MSan. When
40
// using ASan or MSan absl::Cord will poison/unpoison its inline storage.
41
#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || defined(ABSL_HAVE_MEMORY_SANITIZER)
42
#define CEL_COMMON_INTERNAL_VALUE_VARIANT_TRIVIAL_ABI
43
#else
44
#define CEL_COMMON_INTERNAL_VALUE_VARIANT_TRIVIAL_ABI ABSL_ATTRIBUTE_TRIVIAL_ABI
45
#endif
46
47
namespace cel {
48
49
class ValueInterface;
50
class ListValueInterface;
51
class StructValueInterface;
52
53
class Value;
54
class BoolValue;
55
class BytesValue;
56
class DoubleValue;
57
class DurationValue;
58
class ABSL_ATTRIBUTE_TRIVIAL_ABI ErrorValue;
59
class IntValue;
60
class ListValue;
61
class MapValue;
62
class NullValue;
63
class OpaqueValue;
64
class OptionalValue;
65
class StringValue;
66
class StructValue;
67
class TimestampValue;
68
class TypeValue;
69
class UintValue;
70
class UnknownValue;
71
class ParsedMessageValue;
72
class ParsedMapFieldValue;
73
class ParsedRepeatedFieldValue;
74
class ParsedJsonListValue;
75
class ParsedJsonMapValue;
76
77
class CustomListValue;
78
class CustomListValueInterface;
79
80
class CustomMapValue;
81
class CustomMapValueInterface;
82
83
class CustomStructValue;
84
class CustomStructValueInterface;
85
86
class ValueIterator;
87
using ValueIteratorPtr = std::unique_ptr<ValueIterator>;
88
89
class ValueIterator {
90
 public:
91
228
  virtual ~ValueIterator() = default;
92
93
  virtual bool HasNext() = 0;
94
95
  // Returns a view of the next value. If the underlying implementation cannot
96
  // directly return a view of a value, the value will be stored in `scratch`,
97
  // and the returned view will be that of `scratch`.
98
  virtual absl::Status Next(
99
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
100
      google::protobuf::MessageFactory* absl_nonnull message_factory,
101
      google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) = 0;
102
103
  absl::StatusOr<Value> Next(
104
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
105
      google::protobuf::MessageFactory* absl_nonnull message_factory,
106
      google::protobuf::Arena* absl_nonnull arena);
107
108
  // Next1 returns values for lists and keys for maps.
109
  virtual absl::StatusOr<bool> Next1(
110
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
111
      google::protobuf::MessageFactory* absl_nonnull message_factory,
112
      google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull key_or_value);
113
114
  absl::StatusOr<absl::optional<Value>> Next1(
115
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
116
      google::protobuf::MessageFactory* absl_nonnull message_factory,
117
      google::protobuf::Arena* absl_nonnull arena);
118
119
  // Next2 returns indices (in ascending order) and values for lists and keys
120
  // (in any order) and values for maps.
121
  virtual absl::StatusOr<bool> Next2(
122
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
123
      google::protobuf::MessageFactory* absl_nonnull message_factory,
124
      google::protobuf::Arena* absl_nonnull arena, Value* absl_nullable key,
125
      Value* absl_nullable value) = 0;
126
127
  absl::StatusOr<absl::optional<std::pair<Value, Value>>> Next2(
128
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
129
      google::protobuf::MessageFactory* absl_nonnull message_factory,
130
      google::protobuf::Arena* absl_nonnull arena);
131
};
132
133
namespace common_internal {
134
135
class SharedByteString;
136
class SharedByteStringView;
137
138
class LegacyListValue;
139
140
class LegacyMapValue;
141
142
class LegacyStructValue;
143
144
class ListValueVariant;
145
146
class MapValueVariant;
147
148
class StructValueVariant;
149
150
class CEL_COMMON_INTERNAL_VALUE_VARIANT_TRIVIAL_ABI ValueVariant;
151
152
ErrorValue GetDefaultErrorValue();
153
154
CustomListValue GetEmptyDynListValue();
155
156
CustomMapValue GetEmptyDynDynMapValue();
157
158
OptionalValue GetEmptyDynOptionalValue();
159
160
absl::Status ListValueEqual(
161
    const ListValue& lhs, const ListValue& rhs,
162
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
163
    google::protobuf::MessageFactory* absl_nonnull message_factory,
164
    google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result);
165
166
absl::Status ListValueEqual(
167
    const CustomListValueInterface& lhs, const ListValue& rhs,
168
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
169
    google::protobuf::MessageFactory* absl_nonnull message_factory,
170
    google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result);
171
172
absl::Status MapValueEqual(
173
    const MapValue& lhs, const MapValue& rhs,
174
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
175
    google::protobuf::MessageFactory* absl_nonnull message_factory,
176
    google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result);
177
178
absl::Status MapValueEqual(
179
    const CustomMapValueInterface& lhs, const MapValue& rhs,
180
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
181
    google::protobuf::MessageFactory* absl_nonnull message_factory,
182
    google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result);
183
184
absl::Status StructValueEqual(
185
    const StructValue& lhs, const StructValue& rhs,
186
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
187
    google::protobuf::MessageFactory* absl_nonnull message_factory,
188
    google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result);
189
190
absl::Status StructValueEqual(
191
    const CustomStructValueInterface& lhs, const StructValue& rhs,
192
    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
193
    google::protobuf::MessageFactory* absl_nonnull message_factory,
194
    google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result);
195
196
const SharedByteString& AsSharedByteString(const BytesValue& value);
197
198
const SharedByteString& AsSharedByteString(const StringValue& value);
199
200
using ListValueForEachCallback =
201
    absl::FunctionRef<absl::StatusOr<bool>(const Value&)>;
202
using ListValueForEach2Callback =
203
    absl::FunctionRef<absl::StatusOr<bool>(size_t, const Value&)>;
204
205
template <typename Base>
206
class ValueMixin {
207
 public:
208
  absl::StatusOr<Value> Equal(
209
      const Value& other,
210
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
211
      google::protobuf::MessageFactory* absl_nonnull message_factory,
212
      google::protobuf::Arena* absl_nonnull arena) const;
213
214
  friend Base;
215
};
216
217
template <typename Base>
218
class ListValueMixin : public ValueMixin<Base> {
219
 public:
220
  using ValueMixin<Base>::Equal;
221
222
  absl::StatusOr<Value> Get(
223
      size_t index, const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
224
      google::protobuf::MessageFactory* absl_nonnull message_factory,
225
      google::protobuf::Arena* absl_nonnull arena) const;
226
227
  using ForEachCallback = absl::FunctionRef<absl::StatusOr<bool>(const Value&)>;
228
229
  absl::Status ForEach(
230
      ForEachCallback callback,
231
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
232
      google::protobuf::MessageFactory* absl_nonnull message_factory,
233
0
      google::protobuf::Arena* absl_nonnull arena) const {
234
0
    return static_cast<const Base*>(this)->ForEach(
235
0
        [callback](size_t, const Value& value) -> absl::StatusOr<bool> {
236
0
          return callback(value);
237
0
        },
Unexecuted instantiation: cel::common_internal::ListValueMixin<cel::ListValue>::ForEach(absl::lts_20260107::FunctionRef<absl::lts_20260107::StatusOr<bool> (cel::Value const&)>, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*) const::{lambda(unsigned long, cel::Value const&)#1}::operator()(unsigned long, cel::Value const&) const
Unexecuted instantiation: cel::common_internal::ListValueMixin<cel::CustomListValue>::ForEach(absl::lts_20260107::FunctionRef<absl::lts_20260107::StatusOr<bool> (cel::Value const&)>, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*) const::{lambda(unsigned long, cel::Value const&)#1}::operator()(unsigned long, cel::Value const&) const
238
0
        descriptor_pool, message_factory, arena);
239
0
  }
Unexecuted instantiation: cel::common_internal::ListValueMixin<cel::ListValue>::ForEach(absl::lts_20260107::FunctionRef<absl::lts_20260107::StatusOr<bool> (cel::Value const&)>, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*) const
Unexecuted instantiation: cel::common_internal::ListValueMixin<cel::CustomListValue>::ForEach(absl::lts_20260107::FunctionRef<absl::lts_20260107::StatusOr<bool> (cel::Value const&)>, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*) const
240
241
  absl::StatusOr<Value> Contains(
242
      const Value& other,
243
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
244
      google::protobuf::MessageFactory* absl_nonnull message_factory,
245
      google::protobuf::Arena* absl_nonnull arena) const;
246
247
  friend Base;
248
};
249
250
template <typename Base>
251
class MapValueMixin : public ValueMixin<Base> {
252
 public:
253
  using ValueMixin<Base>::Equal;
254
255
  absl::StatusOr<Value> Get(
256
      const Value& key,
257
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
258
      google::protobuf::MessageFactory* absl_nonnull message_factory,
259
      google::protobuf::Arena* absl_nonnull arena) const;
260
261
  absl::StatusOr<absl::optional<Value>> Find(
262
      const Value& other,
263
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
264
      google::protobuf::MessageFactory* absl_nonnull message_factory,
265
      google::protobuf::Arena* absl_nonnull arena) const;
266
267
  absl::StatusOr<Value> Has(
268
      const Value& key,
269
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
270
      google::protobuf::MessageFactory* absl_nonnull message_factory,
271
      google::protobuf::Arena* absl_nonnull arena) const;
272
273
  absl::StatusOr<ListValue> ListKeys(
274
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
275
      google::protobuf::MessageFactory* absl_nonnull message_factory,
276
      google::protobuf::Arena* absl_nonnull arena) const;
277
278
  friend Base;
279
};
280
281
template <typename Base>
282
class StructValueMixin : public ValueMixin<Base> {
283
 public:
284
  using ValueMixin<Base>::Equal;
285
286
  absl::StatusOr<Value> GetFieldByName(
287
      absl::string_view name,
288
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
289
      google::protobuf::MessageFactory* absl_nonnull message_factory,
290
      google::protobuf::Arena* absl_nonnull arena) const;
291
292
  absl::Status GetFieldByName(
293
      absl::string_view name,
294
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
295
      google::protobuf::MessageFactory* absl_nonnull message_factory,
296
      google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const {
297
    return static_cast<const Base*>(this)->GetFieldByName(
298
        name, ProtoWrapperTypeOptions::kUnsetNull, descriptor_pool,
299
        message_factory, arena, result);
300
  }
301
302
  absl::StatusOr<Value> GetFieldByName(
303
      absl::string_view name, ProtoWrapperTypeOptions unboxing_options,
304
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
305
      google::protobuf::MessageFactory* absl_nonnull message_factory,
306
      google::protobuf::Arena* absl_nonnull arena) const;
307
308
  absl::StatusOr<Value> GetFieldByNumber(
309
      int64_t number,
310
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
311
      google::protobuf::MessageFactory* absl_nonnull message_factory,
312
      google::protobuf::Arena* absl_nonnull arena) const;
313
314
  absl::Status GetFieldByNumber(
315
      int64_t number,
316
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
317
      google::protobuf::MessageFactory* absl_nonnull message_factory,
318
      google::protobuf::Arena* absl_nonnull arena, Value* absl_nonnull result) const {
319
    return static_cast<const Base*>(this)->GetFieldByNumber(
320
        number, ProtoWrapperTypeOptions::kUnsetNull, descriptor_pool,
321
        message_factory, arena, result);
322
  }
323
324
  absl::StatusOr<Value> GetFieldByNumber(
325
      int64_t number, ProtoWrapperTypeOptions unboxing_options,
326
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
327
      google::protobuf::MessageFactory* absl_nonnull message_factory,
328
      google::protobuf::Arena* absl_nonnull arena) const;
329
330
  absl::StatusOr<std::pair<Value, int>> Qualify(
331
      absl::Span<const SelectQualifier> qualifiers, bool presence_test,
332
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
333
      google::protobuf::MessageFactory* absl_nonnull message_factory,
334
      google::protobuf::Arena* absl_nonnull arena) const;
335
336
  friend Base;
337
};
338
339
template <typename Base>
340
class OpaqueValueMixin : public ValueMixin<Base> {
341
 public:
342
  using ValueMixin<Base>::Equal;
343
344
  friend Base;
345
};
346
347
}  // namespace common_internal
348
349
}  // namespace cel
350
351
#endif  // THIRD_PARTY_CEL_CPP_COMMON_VALUES_VALUES_H_