Coverage Report

Created: 2026-09-03 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/parser/macro.cc
Line
Count
Source
1
// Copyright 2021 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
#include "parser/macro.h"
16
17
#include <cstddef>
18
#include <functional>
19
#include <memory>
20
#include <string>
21
#include <utility>
22
#include <vector>
23
24
#include "absl/base/no_destructor.h"
25
#include "absl/log/absl_check.h"
26
#include "absl/status/status.h"
27
#include "absl/status/statusor.h"
28
#include "absl/strings/match.h"
29
#include "absl/strings/str_cat.h"
30
#include "absl/strings/string_view.h"
31
#include "absl/types/optional.h"
32
#include "absl/types/span.h"
33
#include "common/expr.h"
34
#include "common/operators.h"
35
#include "internal/lexis.h"
36
#include "parser/macro_expr_factory.h"
37
38
namespace cel {
39
40
namespace {
41
42
constexpr absl::string_view kOptionalMapVar = "@target";
43
44
using google::api::expr::common::CelOperator;
45
46
25.5k
bool IsSimpleIdentifier(const Expr& expr) {
47
25.5k
  return expr.has_ident_expr() && !expr.ident_expr().name().empty() &&
48
24.2k
         !absl::StartsWith(expr.ident_expr().name(), ".");
49
25.5k
}
50
51
1
inline MacroExpander ToMacroExpander(GlobalMacroExpander expander) {
52
1
  ABSL_DCHECK(expander);
53
1
  return [expander = std::move(expander)](
54
1
             MacroExprFactory& factory,
55
1
             absl::optional<std::reference_wrapper<Expr>> target,
56
10.4k
             absl::Span<Expr> arguments) -> absl::optional<Expr> {
57
10.4k
    ABSL_DCHECK(!target.has_value());
58
10.4k
    return (expander)(factory, arguments);
59
10.4k
  };
60
1
}
61
62
6
inline MacroExpander ToMacroExpander(ReceiverMacroExpander expander) {
63
6
  ABSL_DCHECK(expander);
64
6
  return [expander = std::move(expander)](
65
6
             MacroExprFactory& factory,
66
6
             absl::optional<std::reference_wrapper<Expr>> target,
67
25.5k
             absl::Span<Expr> arguments) -> absl::optional<Expr> {
68
25.5k
    ABSL_DCHECK(target.has_value());
69
25.5k
    return (expander)(factory, *target, arguments);
70
25.5k
  };
71
6
}
72
73
absl::optional<Expr> ExpandHasMacro(MacroExprFactory& factory,
74
10.4k
                                    absl::Span<Expr> args) {
75
10.4k
  if (args.size() != 1) {
76
0
    return factory.ReportError("has() requires 1 arguments");
77
0
  }
78
10.4k
  if (!args[0].has_select_expr() || args[0].select_expr().test_only()) {
79
7.41k
    return factory.ReportErrorAt(args[0],
80
7.41k
                                 "has() argument must be a field selection");
81
7.41k
  }
82
3.01k
  return factory.NewPresenceTest(
83
3.01k
      args[0].mutable_select_expr().release_operand(),
84
3.01k
      args[0].mutable_select_expr().release_field());
85
10.4k
}
86
87
1
Macro MakeHasMacro() {
88
1
  auto macro_or_status = Macro::Global(CelOperator::HAS, 1, ExpandHasMacro);
89
1
  ABSL_CHECK_OK(macro_or_status);  // Crash OK
90
1
  return std::move(*macro_or_status);
91
1
}
92
93
absl::optional<Expr> ExpandAllMacro(MacroExprFactory& factory, Expr& target,
94
1.53k
                                    absl::Span<Expr> args) {
95
1.53k
  if (args.size() != 2) {
96
0
    return factory.ReportError("all() requires 2 arguments");
97
0
  }
98
1.53k
  if (!IsSimpleIdentifier(args[0])) {
99
912
    return factory.ReportErrorAt(
100
912
        args[0], "all() variable name must be a simple identifier");
101
912
  }
102
621
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
103
35
    return factory.ReportErrorAt(
104
35
        args[1], absl::StrCat("all() variable name cannot be ",
105
35
                              kDeprecatedAccumulatorVariableName));
106
35
  }
107
586
  auto init = factory.NewBoolConst(true);
108
586
  auto condition =
109
586
      factory.NewCall(CelOperator::NOT_STRICTLY_FALSE, factory.NewAccuIdent());
110
586
  auto step = factory.NewCall(CelOperator::LOGICAL_AND, factory.NewAccuIdent(),
111
586
                              std::move(args[1]));
112
586
  auto result = factory.NewAccuIdent();
113
586
  return factory.NewComprehension(args[0].ident_expr().name(),
114
586
                                  std::move(target), factory.AccuVarName(),
115
586
                                  std::move(init), std::move(condition),
116
586
                                  std::move(step), std::move(result));
117
621
}
118
119
1
Macro MakeAllMacro() {
120
1
  auto status_or_macro = Macro::Receiver(CelOperator::ALL, 2, ExpandAllMacro);
121
1
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
122
1
  return std::move(*status_or_macro);
123
1
}
124
125
absl::optional<Expr> ExpandExistsMacro(MacroExprFactory& factory, Expr& target,
126
898
                                       absl::Span<Expr> args) {
127
898
  if (args.size() != 2) {
128
0
    return factory.ReportError("exists() requires 2 arguments");
129
0
  }
130
898
  if (!IsSimpleIdentifier(args[0])) {
131
59
    return factory.ReportErrorAt(
132
59
        args[0], "exists() variable name must be a simple identifier");
133
59
  }
134
839
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
135
81
    return factory.ReportErrorAt(
136
81
        args[1], absl::StrCat("exists() variable name cannot be ",
137
81
                              kDeprecatedAccumulatorVariableName));
138
81
  }
139
758
  auto init = factory.NewBoolConst(false);
140
758
  auto condition = factory.NewCall(
141
758
      CelOperator::NOT_STRICTLY_FALSE,
142
758
      factory.NewCall(CelOperator::LOGICAL_NOT, factory.NewAccuIdent()));
143
758
  auto step = factory.NewCall(CelOperator::LOGICAL_OR, factory.NewAccuIdent(),
144
758
                              std::move(args[1]));
145
758
  auto result = factory.NewAccuIdent();
146
758
  return factory.NewComprehension(args[0].ident_expr().name(),
147
758
                                  std::move(target), factory.AccuVarName(),
148
758
                                  std::move(init), std::move(condition),
149
758
                                  std::move(step), std::move(result));
150
839
}
151
152
1
Macro MakeExistsMacro() {
153
1
  auto status_or_macro =
154
1
      Macro::Receiver(CelOperator::EXISTS, 2, ExpandExistsMacro);
155
1
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
156
1
  return std::move(*status_or_macro);
157
1
}
158
159
absl::optional<Expr> ExpandExistsOneMacro(MacroExprFactory& factory,
160
8.66k
                                          Expr& target, absl::Span<Expr> args) {
161
8.66k
  if (args.size() != 2) {
162
0
    return factory.ReportError("exists_one() requires 2 arguments");
163
0
  }
164
8.66k
  if (!IsSimpleIdentifier(args[0])) {
165
260
    return factory.ReportErrorAt(
166
260
        args[0], "exists_one() variable name must be a simple identifier");
167
260
  }
168
8.40k
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
169
22
    return factory.ReportErrorAt(
170
22
        args[1], absl::StrCat("exists_one() variable name cannot be ",
171
22
                              kDeprecatedAccumulatorVariableName));
172
22
  }
173
8.38k
  auto init = factory.NewIntConst(0);
174
8.38k
  auto condition = factory.NewBoolConst(true);
175
8.38k
  auto accu_ident = factory.NewAccuIdent();
176
8.38k
  auto const_1 = factory.NewIntConst(1);
177
8.38k
  auto inc_step = factory.NewCall(CelOperator::ADD, std::move(accu_ident),
178
8.38k
                                  std::move(const_1));
179
180
8.38k
  auto step = factory.NewCall(CelOperator::CONDITIONAL, std::move(args[1]),
181
8.38k
                              std::move(inc_step), factory.NewAccuIdent());
182
8.38k
  accu_ident = factory.NewAccuIdent();
183
8.38k
  auto result = factory.NewCall(CelOperator::EQUALS, std::move(accu_ident),
184
8.38k
                                factory.NewIntConst(1));
185
8.38k
  return factory.NewComprehension(args[0].ident_expr().name(),
186
8.38k
                                  std::move(target), factory.AccuVarName(),
187
8.38k
                                  std::move(init), std::move(condition),
188
8.38k
                                  std::move(step), std::move(result));
189
8.40k
}
190
191
1
Macro MakeExistsOneMacro() {
192
1
  auto status_or_macro =
193
1
      Macro::Receiver(CelOperator::EXISTS_ONE, 2, ExpandExistsOneMacro);
194
1
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
195
1
  return std::move(*status_or_macro);
196
1
}
197
198
absl::optional<Expr> ExpandMap2Macro(MacroExprFactory& factory, Expr& target,
199
2.90k
                                     absl::Span<Expr> args) {
200
2.90k
  if (args.size() != 2) {
201
0
    return factory.ReportError("map() requires 2 arguments");
202
0
  }
203
2.90k
  if (!IsSimpleIdentifier(args[0])) {
204
103
    return factory.ReportErrorAt(
205
103
        args[0], "map() variable name must be a simple identifier");
206
103
  }
207
2.80k
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
208
16
    return factory.ReportErrorAt(
209
16
        args[1], absl::StrCat("map() variable name cannot be ",
210
16
                              kDeprecatedAccumulatorVariableName));
211
16
  }
212
2.79k
  auto init = factory.NewList();
213
2.79k
  auto condition = factory.NewBoolConst(true);
214
2.79k
  auto accu_ref = factory.NewAccuIdent();
215
2.79k
  auto accu_update =
216
2.79k
      factory.NewList(factory.NewListElement(std::move(args[1])));
217
2.79k
  auto step = factory.NewCall(CelOperator::ADD, std::move(accu_ref),
218
2.79k
                              std::move(accu_update));
219
2.79k
  return factory.NewComprehension(args[0].ident_expr().name(),
220
2.79k
                                  std::move(target), factory.AccuVarName(),
221
2.79k
                                  std::move(init), std::move(condition),
222
2.79k
                                  std::move(step), factory.NewAccuIdent());
223
2.80k
}
224
225
1
Macro MakeMap2Macro() {
226
1
  auto status_or_macro = Macro::Receiver(CelOperator::MAP, 2, ExpandMap2Macro);
227
1
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
228
1
  return std::move(*status_or_macro);
229
1
}
230
231
absl::optional<Expr> ExpandMap3Macro(MacroExprFactory& factory, Expr& target,
232
10.9k
                                     absl::Span<Expr> args) {
233
10.9k
  if (args.size() != 3) {
234
0
    return factory.ReportError("map() requires 3 arguments");
235
0
  }
236
10.9k
  if (!IsSimpleIdentifier(args[0])) {
237
103
    return factory.ReportErrorAt(
238
103
        args[0], "map() variable name must be a simple identifier");
239
103
  }
240
10.8k
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
241
298
    return factory.ReportErrorAt(
242
298
        args[1], absl::StrCat("map() variable name cannot be ",
243
298
                              kDeprecatedAccumulatorVariableName));
244
298
  }
245
10.5k
  auto init = factory.NewList();
246
10.5k
  auto condition = factory.NewBoolConst(true);
247
10.5k
  auto accu_ref = factory.NewAccuIdent();
248
10.5k
  auto accu_update =
249
10.5k
      factory.NewList(factory.NewListElement(std::move(args[2])));
250
10.5k
  auto step = factory.NewCall(CelOperator::ADD, std::move(accu_ref),
251
10.5k
                              std::move(accu_update));
252
10.5k
  step = factory.NewCall(CelOperator::CONDITIONAL, std::move(args[1]),
253
10.5k
                         std::move(step), factory.NewAccuIdent());
254
10.5k
  return factory.NewComprehension(args[0].ident_expr().name(),
255
10.5k
                                  std::move(target), factory.AccuVarName(),
256
10.5k
                                  std::move(init), std::move(condition),
257
10.5k
                                  std::move(step), factory.NewAccuIdent());
258
10.8k
}
259
260
1
Macro MakeMap3Macro() {
261
1
  auto status_or_macro = Macro::Receiver(CelOperator::MAP, 3, ExpandMap3Macro);
262
1
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
263
1
  return std::move(*status_or_macro);
264
1
}
265
266
absl::optional<Expr> ExpandFilterMacro(MacroExprFactory& factory, Expr& target,
267
667
                                       absl::Span<Expr> args) {
268
667
  if (args.size() != 2) {
269
0
    return factory.ReportError("filter() requires 2 arguments");
270
0
  }
271
667
  if (!IsSimpleIdentifier(args[0])) {
272
135
    return factory.ReportErrorAt(
273
135
        args[0], "filter() variable name must be a simple identifier");
274
135
  }
275
532
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
276
46
    return factory.ReportErrorAt(
277
46
        args[1], absl::StrCat("filter() variable name cannot be ",
278
46
                              kDeprecatedAccumulatorVariableName));
279
46
  }
280
486
  auto name = args[0].ident_expr().name();
281
282
486
  auto init = factory.NewList();
283
486
  auto condition = factory.NewBoolConst(true);
284
486
  auto accu_ref = factory.NewAccuIdent();
285
486
  auto accu_update =
286
486
      factory.NewList(factory.NewListElement(std::move(args[0])));
287
486
  auto step = factory.NewCall(CelOperator::ADD, std::move(accu_ref),
288
486
                              std::move(accu_update));
289
486
  step = factory.NewCall(CelOperator::CONDITIONAL, std::move(args[1]),
290
486
                         std::move(step), factory.NewAccuIdent());
291
486
  return factory.NewComprehension(std::move(name), std::move(target),
292
486
                                  factory.AccuVarName(), std::move(init),
293
486
                                  std::move(condition), std::move(step),
294
486
                                  factory.NewAccuIdent());
295
532
}
296
297
1
Macro MakeFilterMacro() {
298
1
  auto status_or_macro =
299
1
      Macro::Receiver(CelOperator::FILTER, 2, ExpandFilterMacro);
300
1
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
301
1
  return std::move(*status_or_macro);
302
1
}
303
304
absl::optional<Expr> ExpandOptMapMacro(MacroExprFactory& factory, Expr& target,
305
0
                                       absl::Span<Expr> args) {
306
0
  if (args.size() != 2) {
307
0
    return factory.ReportError("optMap() requires 2 arguments");
308
0
  }
309
0
  if (!IsSimpleIdentifier(args[0])) {
310
0
    return factory.ReportErrorAt(
311
0
        args[0], "optMap() variable name must be a simple identifier");
312
0
  }
313
0
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
314
0
    return factory.ReportErrorAt(
315
0
        args[1], absl::StrCat("optMap() variable name cannot be ",
316
0
                              kDeprecatedAccumulatorVariableName));
317
0
  }
318
0
  auto var_name = args[0].ident_expr().name();
319
320
0
  if (target.has_ident_expr()) {
321
0
    auto target_copy = factory.Copy(target);
322
0
    std::vector<Expr> call_args;
323
0
    call_args.reserve(3);
324
0
    call_args.push_back(factory.NewMemberCall("hasValue", std::move(target)));
325
0
    auto iter_range = factory.NewList();
326
0
    auto accu_init = factory.NewMemberCall("value", std::move(target_copy));
327
0
    auto condition = factory.NewBoolConst(false);
328
0
    auto fold = factory.NewComprehension(
329
0
        "#unused", std::move(iter_range), std::move(var_name),
330
0
        std::move(accu_init), std::move(condition), std::move(args[0]),
331
0
        std::move(args[1]));
332
0
    call_args.push_back(factory.NewCall("optional.of", std::move(fold)));
333
0
    call_args.push_back(factory.NewCall("optional.none"));
334
0
    return factory.NewCall(CelOperator::CONDITIONAL, std::move(call_args));
335
0
  }
336
337
  // If the target is complex, use an internal bind expression to avoid
338
  // repeating it and blowing up the AST in the expansion
339
0
  auto tmp = factory.NewIdent(kOptionalMapVar);
340
0
  auto tmp_copy = factory.Copy(tmp);
341
342
0
  auto iter_range = factory.NewList();
343
0
  auto accu_init = factory.NewMemberCall("value", std::move(tmp_copy));
344
0
  auto condition = factory.NewBoolConst(false);
345
0
  auto loop_step = std::move(args[0]);
346
0
  auto fold = factory.NewComprehension(
347
0
      "#unused", std::move(iter_range), std::move(var_name),
348
0
      std::move(accu_init), std::move(condition), std::move(loop_step),
349
0
      std::move(args[1]));
350
0
  std::vector<Expr> call_args;
351
0
  call_args.reserve(3);
352
0
  call_args.push_back(factory.NewMemberCall("hasValue", std::move(tmp)));
353
0
  call_args.push_back(factory.NewCall("optional.of", std::move(fold)));
354
0
  call_args.push_back(factory.NewCall("optional.none"));
355
0
  auto result = factory.NewCall(CelOperator::CONDITIONAL, std::move(call_args));
356
357
0
  iter_range = factory.NewList();
358
0
  accu_init = std::move(target);
359
0
  condition = factory.NewBoolConst(false);
360
0
  loop_step = factory.NewIdent(kOptionalMapVar);
361
0
  return factory.NewComprehension(
362
0
      "#unused", std::move(iter_range), kOptionalMapVar, std::move(accu_init),
363
0
      std::move(condition), loop_step, std::move(result));
364
0
}
365
366
0
Macro MakeOptMapMacro() {
367
0
  auto status_or_macro = Macro::Receiver("optMap", 2, ExpandOptMapMacro);
368
0
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
369
0
  return std::move(*status_or_macro);
370
0
}
371
372
absl::optional<Expr> ExpandOptFlatMapMacro(MacroExprFactory& factory,
373
                                           Expr& target,
374
0
                                           absl::Span<Expr> args) {
375
0
  if (args.size() != 2) {
376
0
    return factory.ReportError("optFlatMap() requires 2 arguments");
377
0
  }
378
0
  if (!IsSimpleIdentifier(args[0])) {
379
0
    return factory.ReportErrorAt(
380
0
        args[0], "optFlatMap() variable name must be a simple identifier");
381
0
  }
382
0
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
383
0
    return factory.ReportErrorAt(
384
0
        args[1], absl::StrCat("optFlatMap() variable name cannot be ",
385
0
                              kDeprecatedAccumulatorVariableName));
386
0
  }
387
0
  auto var_name = args[0].ident_expr().name();
388
389
0
  if (target.has_ident_expr()) {
390
0
    auto target_copy = factory.Copy(target);
391
0
    std::vector<Expr> call_args;
392
0
    call_args.reserve(3);
393
0
    call_args.push_back(factory.NewMemberCall("hasValue", std::move(target)));
394
0
    auto iter_range = factory.NewList();
395
0
    auto accu_init = factory.NewMemberCall("value", std::move(target_copy));
396
0
    auto condition = factory.NewBoolConst(false);
397
0
    call_args.push_back(factory.NewComprehension(
398
0
        "#unused", std::move(iter_range), std::move(var_name),
399
0
        std::move(accu_init), std::move(condition), std::move(args[0]),
400
0
        std::move(args[1])));
401
0
    call_args.push_back(factory.NewCall("optional.none"));
402
0
    return factory.NewCall(CelOperator::CONDITIONAL, std::move(call_args));
403
0
  }
404
405
0
  auto tmp = factory.NewIdent(kOptionalMapVar);
406
0
  auto tmp_copy = factory.Copy(tmp);
407
408
0
  auto iter_range = factory.NewList();
409
0
  auto accu_init = factory.NewMemberCall("value", std::move(tmp_copy));
410
0
  auto condition = factory.NewBoolConst(false);
411
0
  auto loop_step = std::move(args[0]);
412
0
  auto inner = factory.NewComprehension(
413
0
      "#unused", std::move(iter_range), std::move(var_name),
414
0
      std::move(accu_init), std::move(condition), std::move(loop_step),
415
0
      std::move(args[1]));
416
0
  std::vector<Expr> call_args;
417
0
  call_args.reserve(3);
418
0
  call_args.push_back(factory.NewMemberCall("hasValue", std::move(tmp)));
419
0
  call_args.push_back(std::move(inner));
420
0
  call_args.push_back(factory.NewCall("optional.none"));
421
0
  auto result = factory.NewCall(CelOperator::CONDITIONAL, std::move(call_args));
422
423
0
  iter_range = factory.NewList();
424
0
  accu_init = std::move(target);
425
0
  condition = factory.NewBoolConst(false);
426
0
  loop_step = factory.NewIdent(kOptionalMapVar);
427
0
  return factory.NewComprehension(
428
0
      "#unused", std::move(iter_range), kOptionalMapVar, std::move(accu_init),
429
0
      std::move(condition), loop_step, std::move(result));
430
0
}
431
432
0
Macro MakeOptFlatMapMacro() {
433
0
  auto status_or_macro =
434
0
      Macro::Receiver("optFlatMap", 2, ExpandOptFlatMapMacro);
435
0
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
436
0
  return std::move(*status_or_macro);
437
0
}
438
439
}  // namespace
440
441
absl::StatusOr<Macro> Macro::Global(absl::string_view name,
442
                                    size_t argument_count,
443
1
                                    GlobalMacroExpander expander) {
444
1
  if (!expander) {
445
0
    return absl::InvalidArgumentError(
446
0
        absl::StrCat("macro expander for `", name, "` cannot be empty"));
447
0
  }
448
1
  return Make(name, argument_count, ToMacroExpander(std::move(expander)),
449
1
              /*receiver_style=*/false, /*var_arg_style=*/false);
450
1
}
451
452
absl::StatusOr<Macro> Macro::GlobalVarArg(absl::string_view name,
453
0
                                          GlobalMacroExpander expander) {
454
0
  if (!expander) {
455
0
    return absl::InvalidArgumentError(
456
0
        absl::StrCat("macro expander for `", name, "` cannot be empty"));
457
0
  }
458
0
  return Make(name, 0, ToMacroExpander(std::move(expander)),
459
0
              /*receiver_style=*/false,
460
0
              /*var_arg_style=*/true);
461
0
}
462
463
absl::StatusOr<Macro> Macro::Receiver(absl::string_view name,
464
                                      size_t argument_count,
465
6
                                      ReceiverMacroExpander expander) {
466
6
  if (!expander) {
467
0
    return absl::InvalidArgumentError(
468
0
        absl::StrCat("macro expander for `", name, "` cannot be empty"));
469
0
  }
470
6
  return Make(name, argument_count, ToMacroExpander(std::move(expander)),
471
6
              /*receiver_style=*/true, /*var_arg_style=*/false);
472
6
}
473
474
absl::StatusOr<Macro> Macro::ReceiverVarArg(absl::string_view name,
475
0
                                            ReceiverMacroExpander expander) {
476
0
  if (!expander) {
477
0
    return absl::InvalidArgumentError(
478
0
        absl::StrCat("macro expander for `", name, "` cannot be empty"));
479
0
  }
480
0
  return Make(name, 0, ToMacroExpander(std::move(expander)),
481
0
              /*receiver_style=*/true,
482
0
              /*var_arg_style=*/true);
483
0
}
484
485
6.50k
std::vector<Macro> Macro::AllMacros() {
486
6.50k
  return {HasMacro(),  AllMacro(),  ExistsMacro(), ExistsOneMacro(),
487
6.50k
          Map2Macro(), Map3Macro(), FilterMacro()};
488
6.50k
}
489
490
std::string Macro::Key(absl::string_view name, size_t argument_count,
491
7
                       bool receiver_style, bool var_arg_style) {
492
7
  if (var_arg_style) {
493
0
    return absl::StrCat(name, ":*:", receiver_style ? "true" : "false");
494
0
  }
495
7
  return absl::StrCat(name, ":", argument_count, ":",
496
7
                      receiver_style ? "true" : "false");
497
7
}
498
499
absl::StatusOr<Macro> Macro::Make(absl::string_view name, size_t argument_count,
500
                                  MacroExpander expander, bool receiver_style,
501
7
                                  bool var_arg_style) {
502
7
  if (!internal::LexisIsIdentifier(name)) {
503
0
    return absl::InvalidArgumentError(absl::StrCat(
504
0
        "macro function name `", name, "` is not a valid identifier"));
505
0
  }
506
7
  if (!expander) {
507
0
    return absl::InvalidArgumentError(
508
0
        absl::StrCat("macro expander for `", name, "` cannot be empty"));
509
0
  }
510
7
  return Macro(std::make_shared<Rep>(
511
7
      std::string(name),
512
7
      Key(name, argument_count, receiver_style, var_arg_style), argument_count,
513
7
      std::move(expander), receiver_style, var_arg_style));
514
7
}
515
516
6.50k
const Macro& HasMacro() {
517
6.50k
  static const absl::NoDestructor<Macro> macro(MakeHasMacro());
518
6.50k
  return *macro;
519
6.50k
}
520
521
6.50k
const Macro& AllMacro() {
522
6.50k
  static const absl::NoDestructor<Macro> macro(MakeAllMacro());
523
6.50k
  return *macro;
524
6.50k
}
525
526
6.50k
const Macro& ExistsMacro() {
527
6.50k
  static const absl::NoDestructor<Macro> macro(MakeExistsMacro());
528
6.50k
  return *macro;
529
6.50k
}
530
531
6.50k
const Macro& ExistsOneMacro() {
532
6.50k
  static const absl::NoDestructor<Macro> macro(MakeExistsOneMacro());
533
6.50k
  return *macro;
534
6.50k
}
535
536
6.50k
const Macro& Map2Macro() {
537
6.50k
  static const absl::NoDestructor<Macro> macro(MakeMap2Macro());
538
6.50k
  return *macro;
539
6.50k
}
540
541
6.50k
const Macro& Map3Macro() {
542
6.50k
  static const absl::NoDestructor<Macro> macro(MakeMap3Macro());
543
6.50k
  return *macro;
544
6.50k
}
545
546
6.50k
const Macro& FilterMacro() {
547
6.50k
  static const absl::NoDestructor<Macro> macro(MakeFilterMacro());
548
6.50k
  return *macro;
549
6.50k
}
550
551
0
const Macro& OptMapMacro() {
552
0
  static const absl::NoDestructor<Macro> macro(MakeOptMapMacro());
553
0
  return *macro;
554
0
}
555
556
0
const Macro& OptFlatMapMacro() {
557
0
  static const absl::NoDestructor<Macro> macro(MakeOptFlatMapMacro());
558
0
  return *macro;
559
0
}
560
561
}  // namespace cel