Coverage Report

Created: 2026-09-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/parser/macro_expr_factory.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_PARSER_MACRO_EXPR_FACTORY_H_
16
#define THIRD_PARTY_CEL_CPP_PARSER_MACRO_EXPR_FACTORY_H_
17
18
#include <algorithm>
19
#include <cstdint>
20
#include <string>
21
#include <type_traits>
22
#include <utility>
23
#include <vector>
24
25
#include "absl/base/attributes.h"
26
#include "absl/base/nullability.h"
27
#include "absl/strings/string_view.h"
28
#include "common/expr.h"
29
#include "common/expr_factory.h"
30
31
namespace cel {
32
33
class ParserMacroExprFactory;
34
class TestMacroExprFactory;
35
36
namespace parser_internal {
37
template <typename ExprNode>
38
class MacroExprExpanderSupport;
39
}  // namespace parser_internal
40
41
// `MacroExprFactory` is a specialization of `ExprFactory` for `MacroExpander`
42
// which disallows explicitly specifying IDs.
43
class MacroExprFactory : protected ExprFactory {
44
 protected:
45
  using ExprFactory::IsArrayLike;
46
  using ExprFactory::IsExprLike;
47
  using ExprFactory::IsStringLike;
48
49
  template <typename T, typename U>
50
  struct IsRValue
51
      : std::bool_constant<
52
            std::disjunction_v<std::is_same<T, U>, std::is_same<T, U&&>>> {};
53
54
 public:
55
  ABSL_MUST_USE_RESULT Expr Copy(const Expr& expr);
56
57
  ABSL_MUST_USE_RESULT ListExprElement Copy(const ListExprElement& element);
58
59
  ABSL_MUST_USE_RESULT StructExprField Copy(const StructExprField& field);
60
61
  ABSL_MUST_USE_RESULT MapExprEntry Copy(const MapExprEntry& entry);
62
63
0
  ABSL_MUST_USE_RESULT Expr NewUnspecified() {
64
0
    return NewUnspecified(NextId());
65
0
  }
66
67
0
  ABSL_MUST_USE_RESULT Expr NewNullConst() { return NewNullConst(NextId()); }
68
69
40.3k
  ABSL_MUST_USE_RESULT Expr NewBoolConst(bool value) {
70
40.3k
    return NewBoolConst(NextId(), value);
71
40.3k
  }
72
73
17.3k
  ABSL_MUST_USE_RESULT Expr NewIntConst(int64_t value) {
74
17.3k
    return NewIntConst(NextId(), value);
75
17.3k
  }
76
77
0
  ABSL_MUST_USE_RESULT Expr NewUintConst(uint64_t value) {
78
0
    return NewUintConst(NextId(), value);
79
0
  }
80
81
0
  ABSL_MUST_USE_RESULT Expr NewDoubleConst(double value) {
82
0
    return NewDoubleConst(NextId(), value);
83
0
  }
84
85
0
  ABSL_MUST_USE_RESULT Expr NewBytesConst(std::string value) {
86
0
    return NewBytesConst(NextId(), std::move(value));
87
0
  }
88
89
0
  ABSL_MUST_USE_RESULT Expr NewBytesConst(absl::string_view value) {
90
0
    return NewBytesConst(NextId(), value);
91
0
  }
92
93
0
  ABSL_MUST_USE_RESULT Expr NewBytesConst(const char* absl_nullable value) {
94
0
    return NewBytesConst(NextId(), value);
95
0
  }
96
97
0
  ABSL_MUST_USE_RESULT Expr NewStringConst(std::string value) {
98
0
    return NewStringConst(NextId(), std::move(value));
99
0
  }
100
101
0
  ABSL_MUST_USE_RESULT Expr NewStringConst(absl::string_view value) {
102
0
    return NewStringConst(NextId(), value);
103
0
  }
104
105
0
  ABSL_MUST_USE_RESULT Expr NewStringConst(const char* absl_nullable value) {
106
0
    return NewStringConst(NextId(), value);
107
0
  }
108
109
  template <typename Name,
110
            typename = std::enable_if_t<IsStringLike<Name>::value>>
111
0
  ABSL_MUST_USE_RESULT Expr NewIdent(Name name) {
112
0
    return NewIdent(NextId(), std::move(name));
113
0
  }
114
115
40.3k
  absl::string_view AccuVarName() { return ExprFactory::AccuVarName(); }
116
117
102k
  ABSL_MUST_USE_RESULT Expr NewAccuIdent() { return NewAccuIdent(NextId()); }
118
119
  template <typename Operand, typename Field,
120
            typename = std::enable_if_t<IsExprLike<Operand>::value>,
121
            typename = std::enable_if_t<IsStringLike<Field>::value>>
122
  ABSL_MUST_USE_RESULT Expr NewSelect(Operand operand, Field field) {
123
    return NewSelect(NextId(), std::move(operand), std::move(field));
124
  }
125
126
  template <typename Operand, typename Field,
127
            typename = std::enable_if_t<IsExprLike<Operand>::value>,
128
            typename = std::enable_if_t<IsStringLike<Field>::value>>
129
6.61k
  ABSL_MUST_USE_RESULT Expr NewPresenceTest(Operand operand, Field field) {
130
6.61k
    return NewPresenceTest(NextId(), std::move(operand), std::move(field));
131
6.61k
  }
132
133
  template <
134
      typename Function, typename... Args,
135
      typename = std::enable_if_t<IsStringLike<Function>::value>,
136
      typename = std::enable_if_t<std::conjunction_v<IsRValue<Expr, Args>...>>>
137
68.9k
  ABSL_MUST_USE_RESULT Expr NewCall(Function function, Args&&... args) {
138
68.9k
    std::vector<Expr> array;
139
68.9k
    array.reserve(sizeof...(Args));
140
68.9k
    (array.push_back(std::forward<Args>(args)), ...);
141
68.9k
    return NewCall(NextId(), std::move(function), std::move(array));
142
68.9k
  }
cel::Expr cel::MacroExprFactory::NewCall<char const*, cel::Expr, void, void>(char const*, cel::Expr&&)
Line
Count
Source
137
2.96k
  ABSL_MUST_USE_RESULT Expr NewCall(Function function, Args&&... args) {
138
2.96k
    std::vector<Expr> array;
139
2.96k
    array.reserve(sizeof...(Args));
140
2.96k
    (array.push_back(std::forward<Args>(args)), ...);
141
2.96k
    return NewCall(NextId(), std::move(function), std::move(array));
142
2.96k
  }
cel::Expr cel::MacroExprFactory::NewCall<char const*, cel::Expr, cel::Expr, void, void>(char const*, cel::Expr&&, cel::Expr&&)
Line
Count
Source
137
46.1k
  ABSL_MUST_USE_RESULT Expr NewCall(Function function, Args&&... args) {
138
46.1k
    std::vector<Expr> array;
139
46.1k
    array.reserve(sizeof...(Args));
140
46.1k
    (array.push_back(std::forward<Args>(args)), ...);
141
46.1k
    return NewCall(NextId(), std::move(function), std::move(array));
142
46.1k
  }
cel::Expr cel::MacroExprFactory::NewCall<char const*, cel::Expr, cel::Expr, cel::Expr, void, void>(char const*, cel::Expr&&, cel::Expr&&, cel::Expr&&)
Line
Count
Source
137
19.8k
  ABSL_MUST_USE_RESULT Expr NewCall(Function function, Args&&... args) {
138
19.8k
    std::vector<Expr> array;
139
19.8k
    array.reserve(sizeof...(Args));
140
19.8k
    (array.push_back(std::forward<Args>(args)), ...);
141
19.8k
    return NewCall(NextId(), std::move(function), std::move(array));
142
19.8k
  }
Unexecuted instantiation: cel::Expr cel::MacroExprFactory::NewCall<char const*, , void, void>(char const*)
143
144
  template <typename Function, typename Args,
145
            typename = std::enable_if_t<IsStringLike<Function>::value>,
146
            typename = std::enable_if_t<IsArrayLike<Expr, Args>::value>>
147
0
  ABSL_MUST_USE_RESULT Expr NewCall(Function function, Args args) {
148
0
    return NewCall(NextId(), std::move(function), std::move(args));
149
0
  }
150
151
  template <
152
      typename Function, typename Target, typename... Args,
153
      typename = std::enable_if_t<IsStringLike<Function>::value>,
154
      typename = std::enable_if_t<IsExprLike<Target>::value>,
155
      typename = std::enable_if_t<std::conjunction_v<IsRValue<Expr, Args>...>>>
156
  ABSL_MUST_USE_RESULT Expr NewMemberCall(Function function, Target target,
157
0
                                          Args&&... args) {
158
0
    std::vector<Expr> array;
159
0
    array.reserve(sizeof...(Args));
160
0
    (array.push_back(std::forward<Args>(args)), ...);
161
0
    return NewMemberCall(NextId(), std::move(function), std::move(target),
162
0
                         std::move(array));
163
0
  }
164
165
  template <typename Function, typename Target, typename Args,
166
            typename = std::enable_if_t<IsStringLike<Function>::value>,
167
            typename = std::enable_if_t<IsExprLike<Target>::value>,
168
            typename = std::enable_if_t<IsArrayLike<Expr, Args>::value>>
169
  ABSL_MUST_USE_RESULT Expr NewMemberCall(Function function, Target target,
170
                                          Args args) {
171
    return NewMemberCall(NextId(), std::move(function), std::move(target),
172
                         std::move(args));
173
  }
174
175
  using ExprFactory::NewListElement;
176
177
  template <typename... Elements,
178
            typename = std::enable_if_t<
179
                std::conjunction_v<IsRValue<ListExprElement, Elements>...>>>
180
65.2k
  ABSL_MUST_USE_RESULT Expr NewList(Elements&&... elements) {
181
65.2k
    std::vector<ListExprElement> array;
182
65.2k
    array.reserve(sizeof...(Elements));
183
65.2k
    (array.push_back(std::forward<Elements>(elements)), ...);
184
65.2k
    return NewList(NextId(), std::move(array));
185
65.2k
  }
cel::Expr cel::MacroExprFactory::NewList<, void>()
Line
Count
Source
180
32.6k
  ABSL_MUST_USE_RESULT Expr NewList(Elements&&... elements) {
181
32.6k
    std::vector<ListExprElement> array;
182
32.6k
    array.reserve(sizeof...(Elements));
183
32.6k
    (array.push_back(std::forward<Elements>(elements)), ...);
184
32.6k
    return NewList(NextId(), std::move(array));
185
32.6k
  }
cel::Expr cel::MacroExprFactory::NewList<cel::ListExprElement, void>(cel::ListExprElement&&)
Line
Count
Source
180
32.6k
  ABSL_MUST_USE_RESULT Expr NewList(Elements&&... elements) {
181
32.6k
    std::vector<ListExprElement> array;
182
32.6k
    array.reserve(sizeof...(Elements));
183
32.6k
    (array.push_back(std::forward<Elements>(elements)), ...);
184
32.6k
    return NewList(NextId(), std::move(array));
185
32.6k
  }
186
187
  template <typename Elements,
188
            typename =
189
                std::enable_if_t<IsArrayLike<ListExprElement, Elements>::value>>
190
  ABSL_MUST_USE_RESULT Expr NewList(Elements elements) {
191
    return NewList(NextId(), std::move(elements));
192
  }
193
194
  template <typename Name, typename Value,
195
            typename = std::enable_if_t<IsStringLike<Name>::value>,
196
            typename = std::enable_if_t<IsExprLike<Value>::value>>
197
  ABSL_MUST_USE_RESULT StructExprField NewStructField(Name name, Value value,
198
                                                      bool optional = false) {
199
    return NewStructField(NextId(), std::move(name), std::move(value),
200
                          optional);
201
  }
202
203
  template <typename Name, typename... Fields,
204
            typename = std::enable_if_t<IsStringLike<Name>::value>,
205
            typename = std::enable_if_t<
206
                std::conjunction_v<IsRValue<StructExprField, Fields>...>>>
207
  ABSL_MUST_USE_RESULT Expr NewStruct(Name name, Fields&&... fields) {
208
    std::vector<StructExprField> array;
209
    array.reserve(sizeof...(Fields));
210
    (array.push_back(std::forward<Fields>(fields)), ...);
211
    return NewStruct(NextId(), std::move(name), std::move(array));
212
  }
213
214
  template <
215
      typename Name, typename Fields,
216
      typename = std::enable_if_t<IsStringLike<Name>::value>,
217
      typename = std::enable_if_t<IsArrayLike<StructExprField, Fields>::value>>
218
  ABSL_MUST_USE_RESULT Expr NewStruct(Name name, Fields fields) {
219
    return NewStruct(NextId(), std::move(name), std::move(fields));
220
  }
221
222
  template <typename Key, typename Value,
223
            typename = std::enable_if_t<IsExprLike<Key>::value>,
224
            typename = std::enable_if_t<IsExprLike<Value>::value>>
225
  ABSL_MUST_USE_RESULT MapExprEntry NewMapEntry(Key key, Value value,
226
                                                bool optional = false) {
227
    return NewMapEntry(NextId(), std::move(key), std::move(value), optional);
228
  }
229
230
  template <typename... Entries, typename = std::enable_if_t<std::conjunction_v<
231
                                     IsRValue<MapExprEntry, Entries>...>>>
232
  ABSL_MUST_USE_RESULT Expr NewMap(Entries&&... entries) {
233
    std::vector<MapExprEntry> array;
234
    array.reserve(sizeof...(Entries));
235
    (array.push_back(std::forward<Entries>(entries)), ...);
236
    return NewMap(NextId(), std::move(array));
237
  }
238
239
  template <typename Entries, typename = std::enable_if_t<
240
                                  IsArrayLike<MapExprEntry, Entries>::value>>
241
  ABSL_MUST_USE_RESULT Expr NewMap(Entries entries) {
242
    return NewMap(NextId(), std::move(entries));
243
  }
244
245
  template <typename IterVar, typename IterRange, typename AccuVar,
246
            typename AccuInit, typename LoopCondition, typename LoopStep,
247
            typename Result,
248
            typename = std::enable_if_t<IsStringLike<IterVar>::value>,
249
            typename = std::enable_if_t<IsExprLike<IterRange>::value>,
250
            typename = std::enable_if_t<IsStringLike<AccuVar>::value>,
251
            typename = std::enable_if_t<IsExprLike<AccuInit>::value>,
252
            typename = std::enable_if_t<IsExprLike<LoopStep>::value>,
253
            typename = std::enable_if_t<IsExprLike<LoopCondition>::value>,
254
            typename = std::enable_if_t<IsExprLike<Result>::value>>
255
  ABSL_MUST_USE_RESULT Expr
256
  NewComprehension(IterVar iter_var, IterRange iter_range, AccuVar accu_var,
257
                   AccuInit accu_init, LoopCondition loop_condition,
258
40.3k
                   LoopStep loop_step, Result result) {
259
40.3k
    return NewComprehension(NextId(), std::move(iter_var),
260
40.3k
                            std::move(iter_range), std::move(accu_var),
261
40.3k
                            std::move(accu_init), std::move(loop_condition),
262
40.3k
                            std::move(loop_step), std::move(result));
263
40.3k
  }
cel::Expr cel::MacroExprFactory::NewComprehension<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cel::Expr, std::__1::basic_string_view<char, std::__1::char_traits<char> >, cel::Expr, cel::Expr, cel::Expr, cel::Expr, void, void, void, void, void, void, void>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cel::Expr, std::__1::basic_string_view<char, std::__1::char_traits<char> >, cel::Expr, cel::Expr, cel::Expr, cel::Expr)
Line
Count
Source
258
40.3k
                   LoopStep loop_step, Result result) {
259
40.3k
    return NewComprehension(NextId(), std::move(iter_var),
260
40.3k
                            std::move(iter_range), std::move(accu_var),
261
40.3k
                            std::move(accu_init), std::move(loop_condition),
262
40.3k
                            std::move(loop_step), std::move(result));
263
40.3k
  }
Unexecuted instantiation: cel::Expr cel::MacroExprFactory::NewComprehension<char const*, cel::Expr, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cel::Expr, cel::Expr, cel::Expr, cel::Expr, void, void, void, void, void, void, void>(char const*, cel::Expr, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, cel::Expr, cel::Expr, cel::Expr, cel::Expr)
Unexecuted instantiation: cel::Expr cel::MacroExprFactory::NewComprehension<char const*, cel::Expr, std::__1::basic_string_view<char, std::__1::char_traits<char> >, cel::Expr, cel::Expr, cel::Expr, cel::Expr, void, void, void, void, void, void, void>(char const*, cel::Expr, std::__1::basic_string_view<char, std::__1::char_traits<char> >, cel::Expr, cel::Expr, cel::Expr, cel::Expr)
264
265
  template <typename IterVar, typename IterVar2, typename IterRange,
266
            typename AccuVar, typename AccuInit, typename LoopCondition,
267
            typename LoopStep, typename Result,
268
            typename = std::enable_if_t<IsStringLike<IterVar>::value>,
269
            typename = std::enable_if_t<IsStringLike<IterVar2>::value>,
270
            typename = std::enable_if_t<IsExprLike<IterRange>::value>,
271
            typename = std::enable_if_t<IsStringLike<AccuVar>::value>,
272
            typename = std::enable_if_t<IsExprLike<AccuInit>::value>,
273
            typename = std::enable_if_t<IsExprLike<LoopStep>::value>,
274
            typename = std::enable_if_t<IsExprLike<LoopCondition>::value>,
275
            typename = std::enable_if_t<IsExprLike<Result>::value>>
276
  ABSL_MUST_USE_RESULT Expr NewComprehension(
277
      IterVar iter_var, IterVar2 iter_var2, IterRange iter_range,
278
      AccuVar accu_var, AccuInit accu_init, LoopCondition loop_condition,
279
      LoopStep loop_step, Result result) {
280
    return NewComprehension(NextId(), std::move(iter_var), std::move(iter_var2),
281
                            std::move(iter_range), std::move(accu_var),
282
                            std::move(accu_init), std::move(loop_condition),
283
                            std::move(loop_step), std::move(result));
284
  }
285
286
  ABSL_MUST_USE_RESULT virtual Expr ReportError(absl::string_view message) = 0;
287
288
  ABSL_MUST_USE_RESULT virtual Expr ReportErrorAt(
289
      const Expr& expr, absl::string_view message) = 0;
290
291
 protected:
292
  using ExprFactory::AccuVarName;
293
  using ExprFactory::NewAccuIdent;
294
  using ExprFactory::NewBoolConst;
295
  using ExprFactory::NewBytesConst;
296
  using ExprFactory::NewCall;
297
  using ExprFactory::NewComprehension;
298
  using ExprFactory::NewConst;
299
  using ExprFactory::NewDoubleConst;
300
  using ExprFactory::NewIdent;
301
  using ExprFactory::NewIntConst;
302
  using ExprFactory::NewList;
303
  using ExprFactory::NewMap;
304
  using ExprFactory::NewMapEntry;
305
  using ExprFactory::NewMemberCall;
306
  using ExprFactory::NewNullConst;
307
  using ExprFactory::NewPresenceTest;
308
  using ExprFactory::NewSelect;
309
  using ExprFactory::NewStringConst;
310
  using ExprFactory::NewStruct;
311
  using ExprFactory::NewStructField;
312
  using ExprFactory::NewUintConst;
313
  using ExprFactory::NewUnspecified;
314
315
  ABSL_MUST_USE_RESULT virtual ExprId NextId() = 0;
316
317
  ABSL_MUST_USE_RESULT virtual ExprId CopyId(ExprId id) = 0;
318
319
0
  ABSL_MUST_USE_RESULT ExprId CopyId(const Expr& expr) {
320
0
    return CopyId(expr.id());
321
0
  }
322
323
 private:
324
  friend class ParserMacroExprFactory;
325
  friend class TestMacroExprFactory;
326
  friend class parser_internal::MacroExprExpanderSupport<Expr>;
327
328
35.3k
  explicit MacroExprFactory() = default;
329
};
330
331
}  // namespace cel
332
333
#endif  // THIRD_PARTY_CEL_CPP_PARSER_MACRO_EXPR_FACTORY_H_