Coverage Report

Created: 2026-07-11 06:47

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
using google::api::expr::common::CelOperator;
43
44
37.9k
bool IsSimpleIdentifier(const Expr& expr) {
45
37.9k
  return expr.has_ident_expr() && !expr.ident_expr().name().empty() &&
46
37.0k
         !absl::StartsWith(expr.ident_expr().name(), ".");
47
37.9k
}
48
49
2
inline MacroExpander ToMacroExpander(GlobalMacroExpander expander) {
50
2
  ABSL_DCHECK(expander);
51
2
  return [expander = std::move(expander)](
52
2
             MacroExprFactory& factory,
53
2
             absl::optional<std::reference_wrapper<Expr>> target,
54
14.3k
             absl::Span<Expr> arguments) -> absl::optional<Expr> {
55
14.3k
    ABSL_DCHECK(!target.has_value());
56
14.3k
    return (expander)(factory, arguments);
57
14.3k
  };
58
2
}
59
60
12
inline MacroExpander ToMacroExpander(ReceiverMacroExpander expander) {
61
12
  ABSL_DCHECK(expander);
62
12
  return [expander = std::move(expander)](
63
12
             MacroExprFactory& factory,
64
12
             absl::optional<std::reference_wrapper<Expr>> target,
65
37.9k
             absl::Span<Expr> arguments) -> absl::optional<Expr> {
66
37.9k
    ABSL_DCHECK(target.has_value());
67
37.9k
    return (expander)(factory, *target, arguments);
68
37.9k
  };
69
12
}
70
71
absl::optional<Expr> ExpandHasMacro(MacroExprFactory& factory,
72
14.3k
                                    absl::Span<Expr> args) {
73
14.3k
  if (args.size() != 1) {
74
0
    return factory.ReportError("has() requires 1 arguments");
75
0
  }
76
14.3k
  if (!args[0].has_select_expr() || args[0].select_expr().test_only()) {
77
14.2k
    return factory.ReportErrorAt(args[0],
78
14.2k
                                 "has() argument must be a field selection");
79
14.2k
  }
80
84
  return factory.NewPresenceTest(
81
84
      args[0].mutable_select_expr().release_operand(),
82
84
      args[0].mutable_select_expr().release_field());
83
14.3k
}
84
85
2
Macro MakeHasMacro() {
86
2
  auto macro_or_status = Macro::Global(CelOperator::HAS, 1, ExpandHasMacro);
87
2
  ABSL_CHECK_OK(macro_or_status);  // Crash OK
88
2
  return std::move(*macro_or_status);
89
2
}
90
91
absl::optional<Expr> ExpandAllMacro(MacroExprFactory& factory, Expr& target,
92
838
                                    absl::Span<Expr> args) {
93
838
  if (args.size() != 2) {
94
0
    return factory.ReportError("all() requires 2 arguments");
95
0
  }
96
838
  if (!IsSimpleIdentifier(args[0])) {
97
233
    return factory.ReportErrorAt(
98
233
        args[0], "all() variable name must be a simple identifier");
99
233
  }
100
605
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
101
14
    return factory.ReportErrorAt(
102
14
        args[1], absl::StrCat("all() variable name cannot be ",
103
14
                              kDeprecatedAccumulatorVariableName));
104
14
  }
105
591
  auto init = factory.NewBoolConst(true);
106
591
  auto condition =
107
591
      factory.NewCall(CelOperator::NOT_STRICTLY_FALSE, factory.NewAccuIdent());
108
591
  auto step = factory.NewCall(CelOperator::LOGICAL_AND, factory.NewAccuIdent(),
109
591
                              std::move(args[1]));
110
591
  auto result = factory.NewAccuIdent();
111
591
  return factory.NewComprehension(args[0].ident_expr().name(),
112
591
                                  std::move(target), factory.AccuVarName(),
113
591
                                  std::move(init), std::move(condition),
114
591
                                  std::move(step), std::move(result));
115
605
}
116
117
2
Macro MakeAllMacro() {
118
2
  auto status_or_macro = Macro::Receiver(CelOperator::ALL, 2, ExpandAllMacro);
119
2
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
120
2
  return std::move(*status_or_macro);
121
2
}
122
123
absl::optional<Expr> ExpandExistsMacro(MacroExprFactory& factory, Expr& target,
124
583
                                       absl::Span<Expr> args) {
125
583
  if (args.size() != 2) {
126
0
    return factory.ReportError("exists() requires 2 arguments");
127
0
  }
128
583
  if (!IsSimpleIdentifier(args[0])) {
129
47
    return factory.ReportErrorAt(
130
47
        args[0], "exists() variable name must be a simple identifier");
131
47
  }
132
536
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
133
79
    return factory.ReportErrorAt(
134
79
        args[1], absl::StrCat("exists() variable name cannot be ",
135
79
                              kDeprecatedAccumulatorVariableName));
136
79
  }
137
457
  auto init = factory.NewBoolConst(false);
138
457
  auto condition = factory.NewCall(
139
457
      CelOperator::NOT_STRICTLY_FALSE,
140
457
      factory.NewCall(CelOperator::LOGICAL_NOT, factory.NewAccuIdent()));
141
457
  auto step = factory.NewCall(CelOperator::LOGICAL_OR, factory.NewAccuIdent(),
142
457
                              std::move(args[1]));
143
457
  auto result = factory.NewAccuIdent();
144
457
  return factory.NewComprehension(args[0].ident_expr().name(),
145
457
                                  std::move(target), factory.AccuVarName(),
146
457
                                  std::move(init), std::move(condition),
147
457
                                  std::move(step), std::move(result));
148
536
}
149
150
2
Macro MakeExistsMacro() {
151
2
  auto status_or_macro =
152
2
      Macro::Receiver(CelOperator::EXISTS, 2, ExpandExistsMacro);
153
2
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
154
2
  return std::move(*status_or_macro);
155
2
}
156
157
absl::optional<Expr> ExpandExistsOneMacro(MacroExprFactory& factory,
158
23.8k
                                          Expr& target, absl::Span<Expr> args) {
159
23.8k
  if (args.size() != 2) {
160
0
    return factory.ReportError("exists_one() requires 2 arguments");
161
0
  }
162
23.8k
  if (!IsSimpleIdentifier(args[0])) {
163
276
    return factory.ReportErrorAt(
164
276
        args[0], "exists_one() variable name must be a simple identifier");
165
276
  }
166
23.5k
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
167
61
    return factory.ReportErrorAt(
168
61
        args[1], absl::StrCat("exists_one() variable name cannot be ",
169
61
                              kDeprecatedAccumulatorVariableName));
170
61
  }
171
23.5k
  auto init = factory.NewIntConst(0);
172
23.5k
  auto condition = factory.NewBoolConst(true);
173
23.5k
  auto accu_ident = factory.NewAccuIdent();
174
23.5k
  auto const_1 = factory.NewIntConst(1);
175
23.5k
  auto inc_step = factory.NewCall(CelOperator::ADD, std::move(accu_ident),
176
23.5k
                                  std::move(const_1));
177
178
23.5k
  auto step = factory.NewCall(CelOperator::CONDITIONAL, std::move(args[1]),
179
23.5k
                              std::move(inc_step), factory.NewAccuIdent());
180
23.5k
  accu_ident = factory.NewAccuIdent();
181
23.5k
  auto result = factory.NewCall(CelOperator::EQUALS, std::move(accu_ident),
182
23.5k
                                factory.NewIntConst(1));
183
23.5k
  return factory.NewComprehension(args[0].ident_expr().name(),
184
23.5k
                                  std::move(target), factory.AccuVarName(),
185
23.5k
                                  std::move(init), std::move(condition),
186
23.5k
                                  std::move(step), std::move(result));
187
23.5k
}
188
189
2
Macro MakeExistsOneMacro() {
190
2
  auto status_or_macro =
191
2
      Macro::Receiver(CelOperator::EXISTS_ONE, 2, ExpandExistsOneMacro);
192
2
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
193
2
  return std::move(*status_or_macro);
194
2
}
195
196
absl::optional<Expr> ExpandMap2Macro(MacroExprFactory& factory, Expr& target,
197
6.58k
                                     absl::Span<Expr> args) {
198
6.58k
  if (args.size() != 2) {
199
0
    return factory.ReportError("map() requires 2 arguments");
200
0
  }
201
6.58k
  if (!IsSimpleIdentifier(args[0])) {
202
278
    return factory.ReportErrorAt(
203
278
        args[0], "map() variable name must be a simple identifier");
204
278
  }
205
6.31k
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
206
66
    return factory.ReportErrorAt(
207
66
        args[1], absl::StrCat("map() variable name cannot be ",
208
66
                              kDeprecatedAccumulatorVariableName));
209
66
  }
210
6.24k
  auto init = factory.NewList();
211
6.24k
  auto condition = factory.NewBoolConst(true);
212
6.24k
  auto accu_ref = factory.NewAccuIdent();
213
6.24k
  auto accu_update =
214
6.24k
      factory.NewList(factory.NewListElement(std::move(args[1])));
215
6.24k
  auto step = factory.NewCall(CelOperator::ADD, std::move(accu_ref),
216
6.24k
                              std::move(accu_update));
217
6.24k
  return factory.NewComprehension(args[0].ident_expr().name(),
218
6.24k
                                  std::move(target), factory.AccuVarName(),
219
6.24k
                                  std::move(init), std::move(condition),
220
6.24k
                                  std::move(step), factory.NewAccuIdent());
221
6.31k
}
222
223
2
Macro MakeMap2Macro() {
224
2
  auto status_or_macro = Macro::Receiver(CelOperator::MAP, 2, ExpandMap2Macro);
225
2
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
226
2
  return std::move(*status_or_macro);
227
2
}
228
229
absl::optional<Expr> ExpandMap3Macro(MacroExprFactory& factory, Expr& target,
230
5.60k
                                     absl::Span<Expr> args) {
231
5.60k
  if (args.size() != 3) {
232
0
    return factory.ReportError("map() requires 3 arguments");
233
0
  }
234
5.60k
  if (!IsSimpleIdentifier(args[0])) {
235
81
    return factory.ReportErrorAt(
236
81
        args[0], "map() variable name must be a simple identifier");
237
81
  }
238
5.52k
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
239
90
    return factory.ReportErrorAt(
240
90
        args[1], absl::StrCat("map() variable name cannot be ",
241
90
                              kDeprecatedAccumulatorVariableName));
242
90
  }
243
5.43k
  auto init = factory.NewList();
244
5.43k
  auto condition = factory.NewBoolConst(true);
245
5.43k
  auto accu_ref = factory.NewAccuIdent();
246
5.43k
  auto accu_update =
247
5.43k
      factory.NewList(factory.NewListElement(std::move(args[2])));
248
5.43k
  auto step = factory.NewCall(CelOperator::ADD, std::move(accu_ref),
249
5.43k
                              std::move(accu_update));
250
5.43k
  step = factory.NewCall(CelOperator::CONDITIONAL, std::move(args[1]),
251
5.43k
                         std::move(step), factory.NewAccuIdent());
252
5.43k
  return factory.NewComprehension(args[0].ident_expr().name(),
253
5.43k
                                  std::move(target), factory.AccuVarName(),
254
5.43k
                                  std::move(init), std::move(condition),
255
5.43k
                                  std::move(step), factory.NewAccuIdent());
256
5.52k
}
257
258
2
Macro MakeMap3Macro() {
259
2
  auto status_or_macro = Macro::Receiver(CelOperator::MAP, 3, ExpandMap3Macro);
260
2
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
261
2
  return std::move(*status_or_macro);
262
2
}
263
264
absl::optional<Expr> ExpandFilterMacro(MacroExprFactory& factory, Expr& target,
265
445
                                       absl::Span<Expr> args) {
266
445
  if (args.size() != 2) {
267
0
    return factory.ReportError("filter() requires 2 arguments");
268
0
  }
269
445
  if (!IsSimpleIdentifier(args[0])) {
270
111
    return factory.ReportErrorAt(
271
111
        args[0], "filter() variable name must be a simple identifier");
272
111
  }
273
334
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
274
13
    return factory.ReportErrorAt(
275
13
        args[1], absl::StrCat("filter() variable name cannot be ",
276
13
                              kDeprecatedAccumulatorVariableName));
277
13
  }
278
321
  auto name = args[0].ident_expr().name();
279
280
321
  auto init = factory.NewList();
281
321
  auto condition = factory.NewBoolConst(true);
282
321
  auto accu_ref = factory.NewAccuIdent();
283
321
  auto accu_update =
284
321
      factory.NewList(factory.NewListElement(std::move(args[0])));
285
321
  auto step = factory.NewCall(CelOperator::ADD, std::move(accu_ref),
286
321
                              std::move(accu_update));
287
321
  step = factory.NewCall(CelOperator::CONDITIONAL, std::move(args[1]),
288
321
                         std::move(step), factory.NewAccuIdent());
289
321
  return factory.NewComprehension(std::move(name), std::move(target),
290
321
                                  factory.AccuVarName(), std::move(init),
291
321
                                  std::move(condition), std::move(step),
292
321
                                  factory.NewAccuIdent());
293
334
}
294
295
2
Macro MakeFilterMacro() {
296
2
  auto status_or_macro =
297
2
      Macro::Receiver(CelOperator::FILTER, 2, ExpandFilterMacro);
298
2
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
299
2
  return std::move(*status_or_macro);
300
2
}
301
302
absl::optional<Expr> ExpandOptMapMacro(MacroExprFactory& factory, Expr& target,
303
0
                                       absl::Span<Expr> args) {
304
0
  if (args.size() != 2) {
305
0
    return factory.ReportError("optMap() requires 2 arguments");
306
0
  }
307
0
  if (!IsSimpleIdentifier(args[0])) {
308
0
    return factory.ReportErrorAt(
309
0
        args[0], "optMap() variable name must be a simple identifier");
310
0
  }
311
0
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
312
0
    return factory.ReportErrorAt(
313
0
        args[1], absl::StrCat("optMap() variable name cannot be ",
314
0
                              kDeprecatedAccumulatorVariableName));
315
0
  }
316
0
  auto var_name = args[0].ident_expr().name();
317
318
0
  auto target_copy = factory.Copy(target);
319
0
  std::vector<Expr> call_args;
320
0
  call_args.reserve(3);
321
0
  call_args.push_back(factory.NewMemberCall("hasValue", std::move(target)));
322
0
  auto iter_range = factory.NewList();
323
0
  auto accu_init = factory.NewMemberCall("value", std::move(target_copy));
324
0
  auto condition = factory.NewBoolConst(false);
325
0
  auto fold = factory.NewComprehension(
326
0
      "#unused", std::move(iter_range), std::move(var_name),
327
0
      std::move(accu_init), std::move(condition), std::move(args[0]),
328
0
      std::move(args[1]));
329
0
  call_args.push_back(factory.NewCall("optional.of", std::move(fold)));
330
0
  call_args.push_back(factory.NewCall("optional.none"));
331
0
  return factory.NewCall(CelOperator::CONDITIONAL, std::move(call_args));
332
0
}
333
334
0
Macro MakeOptMapMacro() {
335
0
  auto status_or_macro = Macro::Receiver("optMap", 2, ExpandOptMapMacro);
336
0
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
337
0
  return std::move(*status_or_macro);
338
0
}
339
340
absl::optional<Expr> ExpandOptFlatMapMacro(MacroExprFactory& factory,
341
                                           Expr& target,
342
0
                                           absl::Span<Expr> args) {
343
0
  if (args.size() != 2) {
344
0
    return factory.ReportError("optFlatMap() requires 2 arguments");
345
0
  }
346
0
  if (!IsSimpleIdentifier(args[0])) {
347
0
    return factory.ReportErrorAt(
348
0
        args[0], "optFlatMap() variable name must be a simple identifier");
349
0
  }
350
0
  if (args[0].ident_expr().name() == kDeprecatedAccumulatorVariableName) {
351
0
    return factory.ReportErrorAt(
352
0
        args[1], absl::StrCat("optFlatMap() variable name cannot be ",
353
0
                              kDeprecatedAccumulatorVariableName));
354
0
  }
355
0
  auto var_name = args[0].ident_expr().name();
356
357
0
  auto target_copy = factory.Copy(target);
358
0
  std::vector<Expr> call_args;
359
0
  call_args.reserve(3);
360
0
  call_args.push_back(factory.NewMemberCall("hasValue", std::move(target)));
361
0
  auto iter_range = factory.NewList();
362
0
  auto accu_init = factory.NewMemberCall("value", std::move(target_copy));
363
0
  auto condition = factory.NewBoolConst(false);
364
0
  call_args.push_back(factory.NewComprehension(
365
0
      "#unused", std::move(iter_range), std::move(var_name),
366
0
      std::move(accu_init), std::move(condition), std::move(args[0]),
367
0
      std::move(args[1])));
368
0
  call_args.push_back(factory.NewCall("optional.none"));
369
0
  return factory.NewCall(CelOperator::CONDITIONAL, std::move(call_args));
370
0
}
371
372
0
Macro MakeOptFlatMapMacro() {
373
0
  auto status_or_macro =
374
0
      Macro::Receiver("optFlatMap", 2, ExpandOptFlatMapMacro);
375
0
  ABSL_CHECK_OK(status_or_macro);  // Crash OK
376
0
  return std::move(*status_or_macro);
377
0
}
378
379
}  // namespace
380
381
absl::StatusOr<Macro> Macro::Global(absl::string_view name,
382
                                    size_t argument_count,
383
2
                                    GlobalMacroExpander expander) {
384
2
  if (!expander) {
385
0
    return absl::InvalidArgumentError(
386
0
        absl::StrCat("macro expander for `", name, "` cannot be empty"));
387
0
  }
388
2
  return Make(name, argument_count, ToMacroExpander(std::move(expander)),
389
2
              /*receiver_style=*/false, /*var_arg_style=*/false);
390
2
}
391
392
absl::StatusOr<Macro> Macro::GlobalVarArg(absl::string_view name,
393
0
                                          GlobalMacroExpander expander) {
394
0
  if (!expander) {
395
0
    return absl::InvalidArgumentError(
396
0
        absl::StrCat("macro expander for `", name, "` cannot be empty"));
397
0
  }
398
0
  return Make(name, 0, ToMacroExpander(std::move(expander)),
399
0
              /*receiver_style=*/false,
400
0
              /*var_arg_style=*/true);
401
0
}
402
403
absl::StatusOr<Macro> Macro::Receiver(absl::string_view name,
404
                                      size_t argument_count,
405
12
                                      ReceiverMacroExpander expander) {
406
12
  if (!expander) {
407
0
    return absl::InvalidArgumentError(
408
0
        absl::StrCat("macro expander for `", name, "` cannot be empty"));
409
0
  }
410
12
  return Make(name, argument_count, ToMacroExpander(std::move(expander)),
411
12
              /*receiver_style=*/true, /*var_arg_style=*/false);
412
12
}
413
414
absl::StatusOr<Macro> Macro::ReceiverVarArg(absl::string_view name,
415
0
                                            ReceiverMacroExpander expander) {
416
0
  if (!expander) {
417
0
    return absl::InvalidArgumentError(
418
0
        absl::StrCat("macro expander for `", name, "` cannot be empty"));
419
0
  }
420
0
  return Make(name, 0, ToMacroExpander(std::move(expander)),
421
0
              /*receiver_style=*/true,
422
0
              /*var_arg_style=*/true);
423
0
}
424
425
21.8k
std::vector<Macro> Macro::AllMacros() {
426
21.8k
  return {HasMacro(),  AllMacro(),  ExistsMacro(), ExistsOneMacro(),
427
21.8k
          Map2Macro(), Map3Macro(), FilterMacro()};
428
21.8k
}
429
430
std::string Macro::Key(absl::string_view name, size_t argument_count,
431
14
                       bool receiver_style, bool var_arg_style) {
432
14
  if (var_arg_style) {
433
0
    return absl::StrCat(name, ":*:", receiver_style ? "true" : "false");
434
0
  }
435
14
  return absl::StrCat(name, ":", argument_count, ":",
436
14
                      receiver_style ? "true" : "false");
437
14
}
438
439
absl::StatusOr<Macro> Macro::Make(absl::string_view name, size_t argument_count,
440
                                  MacroExpander expander, bool receiver_style,
441
14
                                  bool var_arg_style) {
442
14
  if (!internal::LexisIsIdentifier(name)) {
443
0
    return absl::InvalidArgumentError(absl::StrCat(
444
0
        "macro function name `", name, "` is not a valid identifier"));
445
0
  }
446
14
  if (!expander) {
447
0
    return absl::InvalidArgumentError(
448
0
        absl::StrCat("macro expander for `", name, "` cannot be empty"));
449
0
  }
450
14
  return Macro(std::make_shared<Rep>(
451
14
      std::string(name),
452
14
      Key(name, argument_count, receiver_style, var_arg_style), argument_count,
453
14
      std::move(expander), receiver_style, var_arg_style));
454
14
}
455
456
21.8k
const Macro& HasMacro() {
457
21.8k
  static const absl::NoDestructor<Macro> macro(MakeHasMacro());
458
21.8k
  return *macro;
459
21.8k
}
460
461
21.8k
const Macro& AllMacro() {
462
21.8k
  static const absl::NoDestructor<Macro> macro(MakeAllMacro());
463
21.8k
  return *macro;
464
21.8k
}
465
466
21.8k
const Macro& ExistsMacro() {
467
21.8k
  static const absl::NoDestructor<Macro> macro(MakeExistsMacro());
468
21.8k
  return *macro;
469
21.8k
}
470
471
21.8k
const Macro& ExistsOneMacro() {
472
21.8k
  static const absl::NoDestructor<Macro> macro(MakeExistsOneMacro());
473
21.8k
  return *macro;
474
21.8k
}
475
476
21.8k
const Macro& Map2Macro() {
477
21.8k
  static const absl::NoDestructor<Macro> macro(MakeMap2Macro());
478
21.8k
  return *macro;
479
21.8k
}
480
481
21.8k
const Macro& Map3Macro() {
482
21.8k
  static const absl::NoDestructor<Macro> macro(MakeMap3Macro());
483
21.8k
  return *macro;
484
21.8k
}
485
486
21.8k
const Macro& FilterMacro() {
487
21.8k
  static const absl::NoDestructor<Macro> macro(MakeFilterMacro());
488
21.8k
  return *macro;
489
21.8k
}
490
491
0
const Macro& OptMapMacro() {
492
0
  static const absl::NoDestructor<Macro> macro(MakeOptMapMacro());
493
0
  return *macro;
494
0
}
495
496
0
const Macro& OptFlatMapMacro() {
497
0
  static const absl::NoDestructor<Macro> macro(MakeOptFlatMapMacro());
498
0
  return *macro;
499
0
}
500
501
}  // namespace cel