Coverage Report

Created: 2025-11-29 07:01

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