Coverage Report

Created: 2026-05-27 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/parser/parser.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/parser.h"
16
17
#include <algorithm>
18
#include <any>
19
#include <array>
20
#include <cstddef>
21
#include <cstdint>
22
#include <exception>
23
#include <functional>
24
#include <iterator>
25
#include <limits>
26
#include <map>
27
#include <memory>
28
#include <string>
29
#include <tuple>
30
#include <utility>
31
#include <vector>
32
33
#include "cel/expr/syntax.pb.h"
34
#include "absl/base/macros.h"
35
#include "absl/base/optimization.h"
36
#include "absl/cleanup/cleanup.h"
37
#include "absl/container/btree_map.h"
38
#include "absl/container/flat_hash_map.h"
39
#include "absl/container/flat_hash_set.h"
40
#include "absl/functional/overload.h"
41
#include "absl/log/absl_check.h"
42
#include "absl/memory/memory.h"
43
#include "absl/status/status.h"
44
#include "absl/status/statusor.h"
45
#include "absl/strings/match.h"
46
#include "absl/strings/numbers.h"
47
#include "absl/strings/str_cat.h"
48
#include "absl/strings/str_format.h"
49
#include "absl/strings/str_join.h"
50
#include "absl/strings/str_replace.h"
51
#include "absl/strings/string_view.h"
52
#include "absl/types/optional.h"
53
#include "absl/types/span.h"
54
#include "absl/types/variant.h"
55
#include "antlr4-runtime.h"
56
#include "common/ast.h"
57
#include "common/ast/expr_proto.h"
58
#include "common/ast/source_info_proto.h"
59
#include "common/constant.h"
60
#include "common/expr_factory.h"
61
#include "common/operators.h"
62
#include "common/source.h"
63
#include "internal/lexis.h"
64
#include "internal/status_macros.h"
65
#include "internal/strings.h"
66
#include "internal/utf8.h"
67
#pragma push_macro("IN")
68
#undef IN
69
#include "parser/internal/CelBaseVisitor.h"
70
#include "parser/internal/CelLexer.h"
71
#include "parser/internal/CelParser.h"
72
#pragma pop_macro("IN")
73
#include "parser/macro.h"
74
#include "parser/macro_expr_factory.h"
75
#include "parser/macro_registry.h"
76
#include "parser/options.h"
77
#include "parser/parser_interface.h"
78
#include "parser/source_factory.h"
79
80
namespace google::api::expr::parser {
81
namespace {
82
class ParserVisitor;
83
}
84
}  // namespace google::api::expr::parser
85
86
namespace cel {
87
88
namespace {
89
90
constexpr const char kHiddenAccumulatorVariableName[] = "@result";
91
92
6.21M
std::any ExprPtrToAny(std::unique_ptr<Expr>&& expr) {
93
6.21M
  return std::make_any<Expr*>(expr.release());
94
6.21M
}
95
96
6.21M
std::any ExprToAny(Expr&& expr) {
97
6.21M
  return ExprPtrToAny(std::make_unique<Expr>(std::move(expr)));
98
6.21M
}
99
100
6.21M
std::unique_ptr<Expr> ExprPtrFromAny(std::any&& any) {
101
6.21M
  return absl::WrapUnique(std::any_cast<Expr*>(std::move(any)));
102
6.21M
}
103
104
6.21M
Expr ExprFromAny(std::any&& any) {
105
6.21M
  auto expr = ExprPtrFromAny(std::move(any));
106
6.21M
  return std::move(*expr);
107
6.21M
}
108
109
struct ParserError {
110
  std::string message;
111
  SourceRange range;
112
};
113
114
std::string DisplayParserError(const cel::Source& source,
115
                               SourceLocation location,
116
192k
                               absl::string_view message) {
117
192k
  return absl::StrCat(absl::StrFormat("ERROR: %s:%zu:%zu: %s",
118
192k
                                      source.description(), location.line,
119
                                      // add one to the 0-based column
120
192k
                                      location.column + 1, message),
121
192k
                      source.DisplayErrorLocation(location));
122
192k
}
123
124
2.06M
int32_t PositiveOrMax(int32_t value) {
125
2.06M
  return value >= 0 ? value : std::numeric_limits<int32_t>::max();
126
2.06M
}
127
128
5.03M
SourceRange SourceRangeFromToken(const antlr4::Token* token) {
129
5.03M
  SourceRange range;
130
5.03M
  if (token != nullptr) {
131
5.03M
    if (auto start = token->getStartIndex(); start != INVALID_INDEX) {
132
5.03M
      range.begin = static_cast<int32_t>(start);
133
5.03M
    }
134
5.03M
    if (auto end = token->getStopIndex(); end != INVALID_INDEX) {
135
5.03M
      range.end = static_cast<int32_t>(end + 1);
136
5.03M
    }
137
5.03M
  }
138
5.03M
  return range;
139
5.03M
}
140
141
SourceRange SourceRangeFromParserRuleContext(
142
1.17M
    const antlr4::ParserRuleContext* context) {
143
1.17M
  SourceRange range;
144
1.17M
  if (context != nullptr) {
145
1.17M
    if (auto start = context->getStart() != nullptr
146
1.17M
                         ? context->getStart()->getStartIndex()
147
1.17M
                         : INVALID_INDEX;
148
1.17M
        start != INVALID_INDEX) {
149
1.17M
      range.begin = static_cast<int32_t>(start);
150
1.17M
    }
151
1.17M
    if (auto end = context->getStop() != nullptr
152
1.17M
                       ? context->getStop()->getStopIndex()
153
1.17M
                       : INVALID_INDEX;
154
1.17M
        end != INVALID_INDEX) {
155
1.17M
      range.end = static_cast<int32_t>(end + 1);
156
1.17M
    }
157
1.17M
  }
158
1.17M
  return range;
159
1.17M
}
160
161
}  // namespace
162
163
class ParserMacroExprFactory final : public MacroExprFactory {
164
 public:
165
  explicit ParserMacroExprFactory(const cel::Source& source)
166
21.4k
      : source_(source) {}
167
168
41.4k
  void BeginMacro(SourceRange macro_position) {
169
41.4k
    macro_position_ = macro_position;
170
41.4k
  }
171
172
41.4k
  void EndMacro() { macro_position_ = SourceRange{}; }
173
174
4.70k
  Expr ReportError(absl::string_view message) override {
175
4.70k
    return ReportError(macro_position_, message);
176
4.70k
  }
177
178
0
  Expr ReportError(int64_t expr_id, absl::string_view message) {
179
0
    return ReportError(GetSourceRange(expr_id), message);
180
0
  }
181
182
8.41M
  Expr ReportError(SourceRange range, absl::string_view message) {
183
8.41M
    ++error_count_;
184
8.41M
    if (errors_.size() <= 100) {
185
191k
      errors_.push_back(ParserError{std::string(message), range});
186
191k
    }
187
8.41M
    return NewUnspecified(NextId(range));
188
8.41M
  }
189
190
14.5k
  Expr ReportErrorAt(const Expr& expr, absl::string_view message) override {
191
14.5k
    return ReportError(GetSourceRange(expr.id()), message);
192
14.5k
  }
193
194
56.0k
  SourceRange GetSourceRange(int64_t id) const {
195
56.0k
    if (auto it = positions_.find(id); it != positions_.end()) {
196
54.9k
      return it->second;
197
54.9k
    }
198
1.13k
    return SourceRange{};
199
56.0k
  }
200
201
14.8M
  int64_t NextId(const SourceRange& range) {
202
14.8M
    auto id = expr_id_++;
203
14.8M
    if (range.begin != -1 || range.end != -1) {
204
14.8M
      positions_.insert(std::pair{id, range});
205
14.8M
    }
206
14.8M
    return id;
207
14.8M
  }
208
209
22.8k
  bool HasErrors() const { return error_count_ != 0; }
210
211
9.29k
  std::vector<cel::ParseIssue> CollectIssues() {
212
    // Errors are collected as they are encountered, not by their location
213
    // within the source. To have a more stable error message as implementation
214
    // details change, we sort the collected errors by their source location
215
    // first.
216
9.29k
    std::stable_sort(
217
9.29k
        errors_.begin(), errors_.end(),
218
516k
        [](const ParserError& lhs, const ParserError& rhs) -> bool {
219
516k
          auto lhs_begin = PositiveOrMax(lhs.range.begin);
220
516k
          auto lhs_end = PositiveOrMax(lhs.range.end);
221
516k
          auto rhs_begin = PositiveOrMax(rhs.range.begin);
222
516k
          auto rhs_end = PositiveOrMax(rhs.range.end);
223
516k
          return lhs_begin < rhs_begin ||
224
474k
                 (lhs_begin == rhs_begin && lhs_end < rhs_end);
225
516k
        });
226
    // Build the summary error message using the sorted errors.
227
9.29k
    bool errors_truncated = error_count_ > 100;
228
9.29k
    std::vector<cel::ParseIssue> issues;
229
9.29k
    issues.reserve(
230
9.29k
        errors_.size() +
231
9.29k
        errors_truncated);  // Reserve space for the transform and an
232
                            // additional element when truncation occurs.
233
9.29k
    std::transform(
234
9.29k
        errors_.begin(), errors_.end(), std::back_inserter(issues),
235
191k
        [this](const ParserError& error) {
236
191k
          auto location =
237
191k
              source_.GetLocation(error.range.begin).value_or(SourceLocation{});
238
191k
          return cel::ParseIssue(location, error.message);
239
191k
        });
240
9.29k
    if (errors_truncated) {
241
786
      issues.push_back(cel::ParseIssue(
242
786
          absl::StrCat(error_count_ - 100, " more errors were truncated.")));
243
786
    }
244
9.29k
    return issues;
245
9.29k
  }
246
247
  void AddMacroCall(int64_t macro_id, absl::string_view function,
248
0
                    absl::optional<Expr> target, std::vector<Expr> arguments) {
249
0
    macro_calls_.insert(
250
0
        {macro_id, target.has_value()
251
0
                       ? NewMemberCall(0, function, std::move(*target),
252
0
                                       std::move(arguments))
253
0
                       : NewCall(0, function, std::move(arguments))});
254
0
  }
255
256
0
  Expr BuildMacroCallArg(const Expr& expr) {
257
0
    if (auto it = macro_calls_.find(expr.id()); it != macro_calls_.end()) {
258
0
      return NewUnspecified(expr.id());
259
0
    }
260
0
    return absl::visit(
261
0
        absl::Overload(
262
0
            [this, &expr](const UnspecifiedExpr&) -> Expr {
263
0
              return NewUnspecified(expr.id());
264
0
            },
265
0
            [this, &expr](const Constant& const_expr) -> Expr {
266
0
              return NewConst(expr.id(), const_expr);
267
0
            },
268
0
            [this, &expr](const IdentExpr& ident_expr) -> Expr {
269
0
              return NewIdent(expr.id(), ident_expr.name());
270
0
            },
271
0
            [this, &expr](const SelectExpr& select_expr) -> Expr {
272
0
              return select_expr.test_only()
273
0
                         ? NewPresenceTest(
274
0
                               expr.id(),
275
0
                               BuildMacroCallArg(select_expr.operand()),
276
0
                               select_expr.field())
277
0
                         : NewSelect(expr.id(),
278
0
                                     BuildMacroCallArg(select_expr.operand()),
279
0
                                     select_expr.field());
280
0
            },
281
0
            [this, &expr](const CallExpr& call_expr) -> Expr {
282
0
              std::vector<Expr> macro_arguments;
283
0
              macro_arguments.reserve(call_expr.args().size());
284
0
              for (const auto& argument : call_expr.args()) {
285
0
                macro_arguments.push_back(BuildMacroCallArg(argument));
286
0
              }
287
0
              absl::optional<Expr> macro_target;
288
0
              if (call_expr.has_target()) {
289
0
                macro_target = BuildMacroCallArg(call_expr.target());
290
0
              }
291
0
              return macro_target.has_value()
292
0
                         ? NewMemberCall(expr.id(), call_expr.function(),
293
0
                                         std::move(*macro_target),
294
0
                                         std::move(macro_arguments))
295
0
                         : NewCall(expr.id(), call_expr.function(),
296
0
                                   std::move(macro_arguments));
297
0
            },
298
0
            [this, &expr](const ListExpr& list_expr) -> Expr {
299
0
              std::vector<ListExprElement> macro_elements;
300
0
              macro_elements.reserve(list_expr.elements().size());
301
0
              for (const auto& element : list_expr.elements()) {
302
0
                auto& cloned_element = macro_elements.emplace_back();
303
0
                if (element.has_expr()) {
304
0
                  cloned_element.set_expr(BuildMacroCallArg(element.expr()));
305
0
                }
306
0
                cloned_element.set_optional(element.optional());
307
0
              }
308
0
              return NewList(expr.id(), std::move(macro_elements));
309
0
            },
310
0
            [this, &expr](const StructExpr& struct_expr) -> Expr {
311
0
              std::vector<StructExprField> macro_fields;
312
0
              macro_fields.reserve(struct_expr.fields().size());
313
0
              for (const auto& field : struct_expr.fields()) {
314
0
                auto& macro_field = macro_fields.emplace_back();
315
0
                macro_field.set_id(field.id());
316
0
                macro_field.set_name(field.name());
317
0
                macro_field.set_value(BuildMacroCallArg(field.value()));
318
0
                macro_field.set_optional(field.optional());
319
0
              }
320
0
              return NewStruct(expr.id(), struct_expr.name(),
321
0
                               std::move(macro_fields));
322
0
            },
323
0
            [this, &expr](const MapExpr& map_expr) -> Expr {
324
0
              std::vector<MapExprEntry> macro_entries;
325
0
              macro_entries.reserve(map_expr.entries().size());
326
0
              for (const auto& entry : map_expr.entries()) {
327
0
                auto& macro_entry = macro_entries.emplace_back();
328
0
                macro_entry.set_id(entry.id());
329
0
                macro_entry.set_key(BuildMacroCallArg(entry.key()));
330
0
                macro_entry.set_value(BuildMacroCallArg(entry.value()));
331
0
                macro_entry.set_optional(entry.optional());
332
0
              }
333
0
              return NewMap(expr.id(), std::move(macro_entries));
334
0
            },
335
0
            [this, &expr](const ComprehensionExpr& comprehension_expr) -> Expr {
336
0
              return NewComprehension(
337
0
                  expr.id(), comprehension_expr.iter_var(),
338
0
                  BuildMacroCallArg(comprehension_expr.iter_range()),
339
0
                  comprehension_expr.accu_var(),
340
0
                  BuildMacroCallArg(comprehension_expr.accu_init()),
341
0
                  BuildMacroCallArg(comprehension_expr.loop_condition()),
342
0
                  BuildMacroCallArg(comprehension_expr.loop_step()),
343
0
                  BuildMacroCallArg(comprehension_expr.result()));
344
0
            }),
345
0
        expr.kind());
346
0
  }
347
348
  using ExprFactory::NewBoolConst;
349
  using ExprFactory::NewBytesConst;
350
  using ExprFactory::NewCall;
351
  using ExprFactory::NewComprehension;
352
  using ExprFactory::NewConst;
353
  using ExprFactory::NewDoubleConst;
354
  using ExprFactory::NewIdent;
355
  using ExprFactory::NewIntConst;
356
  using ExprFactory::NewList;
357
  using ExprFactory::NewListElement;
358
  using ExprFactory::NewMap;
359
  using ExprFactory::NewMapEntry;
360
  using ExprFactory::NewMemberCall;
361
  using ExprFactory::NewNullConst;
362
  using ExprFactory::NewPresenceTest;
363
  using ExprFactory::NewSelect;
364
  using ExprFactory::NewStringConst;
365
  using ExprFactory::NewStruct;
366
  using ExprFactory::NewStructField;
367
  using ExprFactory::NewUintConst;
368
  using ExprFactory::NewUnspecified;
369
370
24.3k
  const absl::btree_map<int64_t, SourceRange>& positions() const {
371
24.3k
    return positions_;
372
24.3k
  }
373
374
0
  const absl::flat_hash_map<int64_t, Expr>& macro_calls() const {
375
0
    return macro_calls_;
376
0
  }
377
378
12.1k
  absl::flat_hash_map<int64_t, Expr> release_macro_calls() {
379
12.1k
    using std::swap;
380
12.1k
    absl::flat_hash_map<int64_t, Expr> result;
381
12.1k
    swap(result, macro_calls_);
382
12.1k
    return result;
383
12.1k
  }
384
385
41.4k
  void EraseId(ExprId id) {
386
41.4k
    positions_.erase(id);
387
41.4k
    if (expr_id_ == id + 1) {
388
0
      --expr_id_;
389
0
    }
390
41.4k
  }
391
392
 protected:
393
272k
  int64_t NextId() override { return NextId(macro_position_); }
394
395
0
  int64_t CopyId(int64_t id) override {
396
0
    if (id == 0) {
397
0
      return 0;
398
0
    }
399
0
    return NextId(GetSourceRange(id));
400
0
  }
401
402
 private:
403
  int64_t expr_id_ = 1;
404
  absl::btree_map<int64_t, SourceRange> positions_;
405
  absl::flat_hash_map<int64_t, Expr> macro_calls_;
406
  std::vector<ParserError> errors_;
407
  size_t error_count_ = 0;
408
  const Source& source_;
409
  SourceRange macro_position_;
410
};
411
412
}  // namespace cel
413
414
namespace google::api::expr::parser {
415
416
namespace {
417
418
using ::antlr4::CharStream;
419
using ::antlr4::CommonTokenStream;
420
using ::antlr4::DefaultErrorStrategy;
421
using ::antlr4::ParseCancellationException;
422
using ::antlr4::Parser;
423
using ::antlr4::ParserRuleContext;
424
using ::antlr4::Token;
425
using ::antlr4::misc::IntervalSet;
426
using ::antlr4::tree::ErrorNode;
427
using ::antlr4::tree::ParseTreeListener;
428
using ::antlr4::tree::TerminalNode;
429
using ::cel::Expr;
430
using ::cel::ExprFromAny;
431
using ::cel::ExprKind;
432
using ::cel::ExprToAny;
433
using ::cel::IdentExpr;
434
using ::cel::ListExprElement;
435
using ::cel::MapExprEntry;
436
using ::cel::SelectExpr;
437
using ::cel::SourceRangeFromParserRuleContext;
438
using ::cel::SourceRangeFromToken;
439
using ::cel::StructExprField;
440
using ::cel_parser_internal::CelBaseVisitor;
441
using ::cel_parser_internal::CelLexer;
442
using ::cel_parser_internal::CelParser;
443
using common::CelOperator;
444
using common::ReverseLookupOperator;
445
using ::cel::expr::ParsedExpr;
446
447
class CodePointStream final : public CharStream {
448
 public:
449
  CodePointStream(cel::SourceContentView buffer, absl::string_view source_name)
450
21.4k
      : buffer_(buffer),
451
21.4k
        source_name_(source_name),
452
21.4k
        size_(buffer_.size()),
453
21.4k
        index_(0) {}
454
455
199M
  void consume() override {
456
199M
    if (ABSL_PREDICT_FALSE(index_ >= size_)) {
457
0
      ABSL_ASSERT(LA(1) == IntStream::EOF);
458
0
      throw antlr4::IllegalStateException("cannot consume EOF");
459
0
    }
460
199M
    index_++;
461
199M
  }
462
463
434M
  size_t LA(ptrdiff_t i) override {
464
434M
    if (ABSL_PREDICT_FALSE(i == 0)) {
465
0
      return 0;
466
0
    }
467
434M
    auto p = static_cast<ptrdiff_t>(index_);
468
434M
    if (i < 0) {
469
0
      i++;
470
0
      if (p + i - 1 < 0) {
471
0
        return IntStream::EOF;
472
0
      }
473
0
    }
474
434M
    if (p + i - 1 >= static_cast<ptrdiff_t>(size_)) {
475
43.9k
      return IntStream::EOF;
476
43.9k
    }
477
434M
    return buffer_.at(static_cast<size_t>(p + i - 1));
478
434M
  }
479
480
27.1M
  ptrdiff_t mark() override { return -1; }
481
482
27.1M
  void release(ptrdiff_t marker) override {}
483
484
180M
  size_t index() override { return index_; }
485
486
9.40M
  void seek(size_t index) override { index_ = std::min(index, size_); }
487
488
8.40M
  size_t size() override { return size_; }
489
490
0
  std::string getSourceName() const override {
491
0
    return source_name_.empty() ? IntStream::UNKNOWN_SOURCE_NAME
492
0
                                : std::string(source_name_);
493
0
  }
494
495
16.7M
  std::string getText(const antlr4::misc::Interval& interval) override {
496
16.7M
    if (ABSL_PREDICT_FALSE(interval.a < 0 || interval.b < 0)) {
497
0
      return std::string();
498
0
    }
499
16.7M
    size_t start = static_cast<size_t>(interval.a);
500
16.7M
    if (ABSL_PREDICT_FALSE(start >= size_)) {
501
0
      return std::string();
502
0
    }
503
16.7M
    size_t stop = static_cast<size_t>(interval.b);
504
16.7M
    if (ABSL_PREDICT_FALSE(stop >= size_)) {
505
875
      stop = size_ - 1;
506
875
    }
507
16.7M
    return buffer_.ToString(static_cast<cel::SourcePosition>(start),
508
16.7M
                            static_cast<cel::SourcePosition>(stop) + 1);
509
16.7M
  }
510
511
0
  std::string toString() const override { return buffer_.ToString(); }
512
513
 private:
514
  cel::SourceContentView const buffer_;
515
  const absl::string_view source_name_;
516
  const size_t size_;
517
  size_t index_;
518
};
519
520
// Scoped helper for incrementing the parse recursion count.
521
// Increments on creation, decrements on destruction (stack unwind).
522
class ScopedIncrement final {
523
 public:
524
  explicit ScopedIncrement(int& recursion_depth)
525
5.69M
      : recursion_depth_(recursion_depth) {
526
5.69M
    ++recursion_depth_;
527
5.69M
  }
528
529
5.69M
  ~ScopedIncrement() { --recursion_depth_; }
530
531
 private:
532
  int& recursion_depth_;
533
};
534
535
// balancer performs tree balancing on operators whose arguments are of equal
536
// precedence.
537
//
538
// The purpose of the balancer is to ensure a compact serialization format for
539
// the logical &&, || operators which have a tendency to create long DAGs which
540
// are skewed in one direction. Since the operators are commutative re-ordering
541
// the terms *must not* affect the evaluation result.
542
//
543
// Based on code from //third_party/cel/go/parser/helper.go
544
class ExpressionBalancer final {
545
 public:
546
  ExpressionBalancer(cel::ParserMacroExprFactory& factory, std::string function,
547
                     Expr expr);
548
549
  // addTerm adds an operation identifier and term to the set of terms to be
550
  // balanced.
551
  void AddTerm(int64_t op, Expr term);
552
553
  // balance creates a balanced tree from the sub-terms and returns the final
554
  // Expr value.
555
  Expr Balance();
556
557
 private:
558
  // balancedTree recursively balances the terms provided to a commutative
559
  // operator.
560
  Expr BalancedTree(int lo, int hi);
561
562
 private:
563
  cel::ParserMacroExprFactory& factory_;
564
  std::string function_;
565
  std::vector<Expr> terms_;
566
  std::vector<int64_t> ops_;
567
};
568
569
ExpressionBalancer::ExpressionBalancer(cel::ParserMacroExprFactory& factory,
570
                                       std::string function, Expr expr)
571
4.58k
    : factory_(factory), function_(std::move(function)) {
572
4.58k
  terms_.push_back(std::move(expr));
573
4.58k
}
574
575
235k
void ExpressionBalancer::AddTerm(int64_t op, Expr term) {
576
235k
  terms_.push_back(std::move(term));
577
235k
  ops_.push_back(op);
578
235k
}
579
580
4.58k
Expr ExpressionBalancer::Balance() {
581
4.58k
  if (terms_.size() == 1) {
582
0
    return std::move(terms_[0]);
583
0
  }
584
4.58k
  return BalancedTree(0, ops_.size() - 1);
585
4.58k
}
586
587
235k
Expr ExpressionBalancer::BalancedTree(int lo, int hi) {
588
235k
  int mid = (lo + hi + 1) / 2;
589
590
235k
  std::vector<Expr> arguments;
591
235k
  arguments.reserve(2);
592
593
235k
  if (mid == lo) {
594
99.5k
    arguments.push_back(std::move(terms_[mid]));
595
135k
  } else {
596
135k
    arguments.push_back(BalancedTree(lo, mid - 1));
597
135k
  }
598
599
235k
  if (mid == hi) {
600
139k
    arguments.push_back(std::move(terms_[mid + 1]));
601
139k
  } else {
602
95.0k
    arguments.push_back(BalancedTree(mid + 1, hi));
603
95.0k
  }
604
235k
  return factory_.NewCall(ops_[mid], function_, std::move(arguments));
605
235k
}
606
607
std::string FormatIssues(const cel::Source& source,
608
9.29k
                         absl::Span<const cel::ParseIssue> issues) {
609
9.29k
  return absl::StrJoin(
610
192k
      issues, "\n", [&source](std::string* out, const cel::ParseIssue& issue) {
611
192k
        absl::StrAppend(out, cel::DisplayParserError(source, issue.location(),
612
192k
                                                     issue.message()));
613
192k
      });
614
9.29k
}
615
616
class ParserVisitor final : public CelBaseVisitor,
617
                            public antlr4::BaseErrorListener {
618
 public:
619
  ParserVisitor(const cel::Source& source, int max_recursion_depth,
620
                const cel::MacroRegistry& macro_registry,
621
                bool add_macro_calls = false,
622
                bool enable_optional_syntax = false,
623
                bool enable_quoted_identifiers = false)
624
21.4k
      : source_(source),
625
21.4k
        factory_(source_),
626
21.4k
        macro_registry_(macro_registry),
627
21.4k
        recursion_depth_(0),
628
21.4k
        max_recursion_depth_(max_recursion_depth),
629
21.4k
        add_macro_calls_(add_macro_calls),
630
21.4k
        enable_optional_syntax_(enable_optional_syntax),
631
21.4k
        enable_quoted_identifiers_(enable_quoted_identifiers) {}
632
633
21.4k
  ~ParserVisitor() override = default;
634
635
  std::any visit(antlr4::tree::ParseTree* tree) override;
636
637
  std::any visitStart(CelParser::StartContext* ctx) override;
638
  std::any visitExpr(CelParser::ExprContext* ctx) override;
639
  std::any visitConditionalOr(CelParser::ConditionalOrContext* ctx) override;
640
  std::any visitConditionalAnd(CelParser::ConditionalAndContext* ctx) override;
641
  std::any visitRelation(CelParser::RelationContext* ctx) override;
642
  std::any visitCalc(CelParser::CalcContext* ctx) override;
643
  std::any visitUnary(CelParser::UnaryContext* ctx);
644
  std::any visitLogicalNot(CelParser::LogicalNotContext* ctx) override;
645
  std::any visitNegate(CelParser::NegateContext* ctx) override;
646
  std::any visitSelect(CelParser::SelectContext* ctx) override;
647
  std::any visitMemberCall(CelParser::MemberCallContext* ctx) override;
648
  std::any visitIndex(CelParser::IndexContext* ctx) override;
649
  std::any visitCreateMessage(CelParser::CreateMessageContext* ctx) override;
650
  std::any visitFieldInitializerList(
651
      CelParser::FieldInitializerListContext* ctx) override;
652
  std::vector<StructExprField> visitFields(
653
      CelParser::FieldInitializerListContext* ctx);
654
  std::any visitGlobalCall(CelParser::GlobalCallContext* ctx) override;
655
  std::any visitIdent(CelParser::IdentContext* ctx) override;
656
  std::any visitNested(CelParser::NestedContext* ctx) override;
657
  std::any visitCreateList(CelParser::CreateListContext* ctx) override;
658
  std::vector<ListExprElement> visitList(CelParser::ListInitContext* ctx);
659
  std::vector<Expr> visitList(CelParser::ExprListContext* ctx);
660
  std::any visitCreateMap(CelParser::CreateMapContext* ctx) override;
661
  std::any visitConstantLiteral(
662
      CelParser::ConstantLiteralContext* ctx) override;
663
  std::any visitPrimaryExpr(CelParser::PrimaryExprContext* ctx) override;
664
  std::any visitMemberExpr(CelParser::MemberExprContext* ctx) override;
665
666
  std::any visitMapInitializerList(
667
      CelParser::MapInitializerListContext* ctx) override;
668
  std::vector<MapExprEntry> visitEntries(
669
      CelParser::MapInitializerListContext* ctx);
670
  std::any visitInt(CelParser::IntContext* ctx) override;
671
  std::any visitUint(CelParser::UintContext* ctx) override;
672
  std::any visitDouble(CelParser::DoubleContext* ctx) override;
673
  std::any visitString(CelParser::StringContext* ctx) override;
674
  std::any visitBytes(CelParser::BytesContext* ctx) override;
675
  std::any visitBoolTrue(CelParser::BoolTrueContext* ctx) override;
676
  std::any visitBoolFalse(CelParser::BoolFalseContext* ctx) override;
677
  std::any visitNull(CelParser::NullContext* ctx) override;
678
  // Note: this is destructive and intended to be called after the parse is
679
  // finished.
680
  cel::SourceInfo GetSourceInfo();
681
  EnrichedSourceInfo enriched_source_info() const;
682
  void syntaxError(antlr4::Recognizer* recognizer,
683
                   antlr4::Token* offending_symbol, size_t line, size_t col,
684
                   const std::string& msg, std::exception_ptr e) override;
685
  bool HasErrored() const;
686
687
  std::vector<cel::ParseIssue> CollectIssues();
688
689
 private:
690
  template <typename... Args>
691
  Expr GlobalCallOrMacro(int64_t expr_id, absl::string_view function,
692
2.23M
                         Args&&... args) {
693
2.23M
    std::vector<Expr> arguments;
694
2.23M
    arguments.reserve(sizeof...(Args));
695
2.23M
    (arguments.push_back(std::forward<Args>(args)), ...);
696
2.23M
    return GlobalCallOrMacroImpl(expr_id, function, std::move(arguments));
697
2.23M
  }
parser.cc:cel::Expr google::api::expr::parser::(anonymous namespace)::ParserVisitor::GlobalCallOrMacro<cel::Expr, cel::Expr>(long, std::__1::basic_string_view<char, std::__1::char_traits<char> >, cel::Expr&&, cel::Expr&&)
Line
Count
Source
692
1.98M
                         Args&&... args) {
693
1.98M
    std::vector<Expr> arguments;
694
1.98M
    arguments.reserve(sizeof...(Args));
695
1.98M
    (arguments.push_back(std::forward<Args>(args)), ...);
696
1.98M
    return GlobalCallOrMacroImpl(expr_id, function, std::move(arguments));
697
1.98M
  }
parser.cc:cel::Expr google::api::expr::parser::(anonymous namespace)::ParserVisitor::GlobalCallOrMacro<cel::Expr>(long, std::__1::basic_string_view<char, std::__1::char_traits<char> >, cel::Expr&&)
Line
Count
Source
692
252k
                         Args&&... args) {
693
252k
    std::vector<Expr> arguments;
694
252k
    arguments.reserve(sizeof...(Args));
695
252k
    (arguments.push_back(std::forward<Args>(args)), ...);
696
252k
    return GlobalCallOrMacroImpl(expr_id, function, std::move(arguments));
697
252k
  }
698
699
  Expr GlobalCallOrMacroImpl(int64_t expr_id, absl::string_view function,
700
                             std::vector<Expr> args);
701
  Expr ReceiverCallOrMacroImpl(int64_t expr_id, absl::string_view function,
702
                               Expr target, std::vector<Expr> args);
703
  std::string ExtractQualifiedName(antlr4::ParserRuleContext* ctx,
704
                                   const Expr& e);
705
706
  std::string NormalizeIdentifier(CelParser::EscapeIdentContext* ctx);
707
  // Attempt to unnest parse context.
708
  //
709
  // Walk the parse tree to the first complex term to reduce recursive depth in
710
  // the visit* calls.
711
  antlr4::tree::ParseTree* UnnestContext(antlr4::tree::ParseTree* tree);
712
713
 private:
714
  const cel::Source& source_;
715
  cel::ParserMacroExprFactory factory_;
716
  const cel::MacroRegistry& macro_registry_;
717
  int recursion_depth_;
718
  const int max_recursion_depth_;
719
  const bool add_macro_calls_;
720
  const bool enable_optional_syntax_;
721
  const bool enable_quoted_identifiers_;
722
};
723
724
template <typename T, typename = std::enable_if_t<
725
                          std::is_base_of<antlr4::tree::ParseTree, T>::value>>
726
105M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
105M
  return dynamic_cast<T*>(tree);
728
105M
}
parser.cc:cel_parser_internal::CelParser::PrimaryExprContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::PrimaryExprContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
7.74M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
7.74M
  return dynamic_cast<T*>(tree);
728
7.74M
}
parser.cc:cel_parser_internal::CelParser::SelectContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::SelectContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
374k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
374k
  return dynamic_cast<T*>(tree);
728
374k
}
parser.cc:cel_parser_internal::CelParser::MemberCallContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::MemberCallContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
327k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
327k
  return dynamic_cast<T*>(tree);
728
327k
}
parser.cc:cel_parser_internal::CelParser::IndexContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::IndexContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
18.2k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
18.2k
  return dynamic_cast<T*>(tree);
728
18.2k
}
parser.cc:cel_parser_internal::CelParser::SimpleIdentifierContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::SimpleIdentifierContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
54.6k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
54.6k
  return dynamic_cast<T*>(tree);
728
54.6k
}
parser.cc:cel_parser_internal::CelParser::EscapedIdentifierContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::EscapedIdentifierContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
2.48k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
2.48k
  return dynamic_cast<T*>(tree);
728
2.48k
}
parser.cc:cel_parser_internal::CelParser::NestedContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::NestedContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
6.67M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
6.67M
  return dynamic_cast<T*>(tree);
728
6.67M
}
parser.cc:cel_parser_internal::CelParser::IdentContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::IdentContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
3.33M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
3.33M
  return dynamic_cast<T*>(tree);
728
3.33M
}
parser.cc:cel_parser_internal::CelParser::GlobalCallContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::GlobalCallContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
1.24M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
1.24M
  return dynamic_cast<T*>(tree);
728
1.24M
}
parser.cc:cel_parser_internal::CelParser::CreateListContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::CreateListContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
1.20M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
1.20M
  return dynamic_cast<T*>(tree);
728
1.20M
}
parser.cc:cel_parser_internal::CelParser::CreateMapContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::CreateMapContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
1.18M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
1.18M
  return dynamic_cast<T*>(tree);
728
1.18M
}
parser.cc:cel_parser_internal::CelParser::CreateMessageContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::CreateMessageContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
1.16M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
1.16M
  return dynamic_cast<T*>(tree);
728
1.16M
}
parser.cc:cel_parser_internal::CelParser::ConstantLiteralContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::ConstantLiteralContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
1.15M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
1.15M
  return dynamic_cast<T*>(tree);
728
1.15M
}
parser.cc:cel_parser_internal::CelParser::IntContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::IntContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
1.15M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
1.15M
  return dynamic_cast<T*>(tree);
728
1.15M
}
parser.cc:cel_parser_internal::CelParser::UintContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::UintContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
408k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
408k
  return dynamic_cast<T*>(tree);
728
408k
}
parser.cc:cel_parser_internal::CelParser::DoubleContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::DoubleContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
383k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
383k
  return dynamic_cast<T*>(tree);
728
383k
}
parser.cc:cel_parser_internal::CelParser::StringContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::StringContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
303k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
303k
  return dynamic_cast<T*>(tree);
728
303k
}
parser.cc:cel_parser_internal::CelParser::BytesContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::BytesContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
15.3k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
15.3k
  return dynamic_cast<T*>(tree);
728
15.3k
}
parser.cc:cel_parser_internal::CelParser::BoolFalseContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::BoolFalseContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
4.83k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
4.83k
  return dynamic_cast<T*>(tree);
728
4.83k
}
parser.cc:cel_parser_internal::CelParser::BoolTrueContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::BoolTrueContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
3.75k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
3.75k
  return dynamic_cast<T*>(tree);
728
3.75k
}
parser.cc:cel_parser_internal::CelParser::NullContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::NullContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
2.69k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
2.69k
  return dynamic_cast<T*>(tree);
728
2.69k
}
parser.cc:cel_parser_internal::CelParser::StartContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::StartContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
11.7M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
11.7M
  return dynamic_cast<T*>(tree);
728
11.7M
}
parser.cc:cel_parser_internal::CelParser::ExprContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::ExprContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
11.7M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
11.7M
  return dynamic_cast<T*>(tree);
728
11.7M
}
parser.cc:cel_parser_internal::CelParser::ConditionalAndContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::ConditionalAndContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
11.7M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
11.7M
  return dynamic_cast<T*>(tree);
728
11.7M
}
parser.cc:cel_parser_internal::CelParser::ConditionalOrContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::ConditionalOrContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
11.7M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
11.7M
  return dynamic_cast<T*>(tree);
728
11.7M
}
parser.cc:cel_parser_internal::CelParser::RelationContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::RelationContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
11.6M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
11.6M
  return dynamic_cast<T*>(tree);
728
11.6M
}
parser.cc:cel_parser_internal::CelParser::CalcContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::CalcContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
11.5M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
11.5M
  return dynamic_cast<T*>(tree);
728
11.5M
}
parser.cc:cel_parser_internal::CelParser::LogicalNotContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::LogicalNotContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
3.71M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
3.71M
  return dynamic_cast<T*>(tree);
728
3.71M
}
parser.cc:cel_parser_internal::CelParser::MemberExprContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::MemberExprContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
4.40M
T* tree_as(antlr4::tree::ParseTree* tree) {
727
4.40M
  return dynamic_cast<T*>(tree);
728
4.40M
}
parser.cc:cel_parser_internal::CelParser::MapInitializerListContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::MapInitializerListContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
275k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
275k
  return dynamic_cast<T*>(tree);
728
275k
}
parser.cc:cel_parser_internal::CelParser::NegateContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::NegateContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
275k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
275k
  return dynamic_cast<T*>(tree);
728
275k
}
parser.cc:cel_parser_internal::CelParser::UnaryContext* google::api::expr::parser::(anonymous namespace)::tree_as<cel_parser_internal::CelParser::UnaryContext, void>(antlr4::tree::ParseTree*)
Line
Count
Source
726
6.91k
T* tree_as(antlr4::tree::ParseTree* tree) {
727
6.91k
  return dynamic_cast<T*>(tree);
728
6.91k
}
Unexecuted instantiation: parser.cc:antlr4::ParserRuleContext* google::api::expr::parser::(anonymous namespace)::tree_as<antlr4::ParserRuleContext, void>(antlr4::tree::ParseTree*)
729
730
5.69M
std::any ParserVisitor::visit(antlr4::tree::ParseTree* tree) {
731
5.69M
  ScopedIncrement inc(recursion_depth_);
732
5.69M
  if (recursion_depth_ > max_recursion_depth_) {
733
3.28k
    return ExprToAny(factory_.ReportError(
734
3.28k
        absl::StrFormat("Exceeded max recursion depth of %d when parsing.",
735
3.28k
                        max_recursion_depth_)));
736
3.28k
  }
737
5.69M
  tree = UnnestContext(tree);
738
5.69M
  if (auto* ctx = tree_as<CelParser::StartContext>(tree)) {
739
0
    return visitStart(ctx);
740
5.69M
  } else if (auto* ctx = tree_as<CelParser::ExprContext>(tree)) {
741
2.47k
    return visitExpr(ctx);
742
5.69M
  } else if (auto* ctx = tree_as<CelParser::ConditionalAndContext>(tree)) {
743
2.02k
    return visitConditionalAnd(ctx);
744
5.69M
  } else if (auto* ctx = tree_as<CelParser::ConditionalOrContext>(tree)) {
745
2.56k
    return visitConditionalOr(ctx);
746
5.68M
  } else if (auto* ctx = tree_as<CelParser::RelationContext>(tree)) {
747
56.8k
    return visitRelation(ctx);
748
5.63M
  } else if (auto* ctx = tree_as<CelParser::CalcContext>(tree)) {
749
1.91M
    return visitCalc(ctx);
750
3.71M
  } else if (auto* ctx = tree_as<CelParser::LogicalNotContext>(tree)) {
751
4.49k
    return visitLogicalNot(ctx);
752
3.70M
  } else if (auto* ctx = tree_as<CelParser::PrimaryExprContext>(tree)) {
753
3.33M
    return visitPrimaryExpr(ctx);
754
3.33M
  } else if (auto* ctx = tree_as<CelParser::MemberExprContext>(tree)) {
755
0
    return visitMemberExpr(ctx);
756
374k
  } else if (auto* ctx = tree_as<CelParser::SelectContext>(tree)) {
757
46.7k
    return visitSelect(ctx);
758
327k
  } else if (auto* ctx = tree_as<CelParser::MemberCallContext>(tree)) {
759
52.4k
    return visitMemberCall(ctx);
760
275k
  } else if (auto* ctx = tree_as<CelParser::MapInitializerListContext>(tree)) {
761
0
    return visitMapInitializerList(ctx);
762
275k
  } else if (auto* ctx = tree_as<CelParser::NegateContext>(tree)) {
763
257k
    return visitNegate(ctx);
764
257k
  } else if (auto* ctx = tree_as<CelParser::IndexContext>(tree)) {
765
11.3k
    return visitIndex(ctx);
766
11.3k
  } else if (auto* ctx = tree_as<CelParser::UnaryContext>(tree)) {
767
5.49k
    return visitUnary(ctx);
768
5.49k
  } else if (auto* ctx = tree_as<CelParser::CreateListContext>(tree)) {
769
0
    return visitCreateList(ctx);
770
1.42k
  } else if (auto* ctx = tree_as<CelParser::CreateMessageContext>(tree)) {
771
0
    return visitCreateMessage(ctx);
772
1.42k
  } else if (auto* ctx = tree_as<CelParser::CreateMapContext>(tree)) {
773
0
    return visitCreateMap(ctx);
774
0
  }
775
776
1.42k
  if (tree) {
777
0
    return ExprToAny(
778
0
        factory_.ReportError(SourceRangeFromParserRuleContext(
779
0
                                 tree_as<antlr4::ParserRuleContext>(tree)),
780
0
                             "unknown parsetree type"));
781
0
  }
782
1.42k
  return ExprToAny(factory_.ReportError("<<nil>> parsetree"));
783
1.42k
}
784
785
3.33M
std::any ParserVisitor::visitPrimaryExpr(CelParser::PrimaryExprContext* pctx) {
786
3.33M
  CelParser::PrimaryContext* primary = pctx->primary();
787
3.33M
  if (auto* ctx = tree_as<CelParser::NestedContext>(primary)) {
788
0
    return visitNested(ctx);
789
3.33M
  } else if (auto* ctx = tree_as<CelParser::IdentContext>(primary)) {
790
2.09M
    return visitIdent(ctx);
791
2.09M
  } else if (auto* ctx = tree_as<CelParser::GlobalCallContext>(primary)) {
792
40.9k
    return visitGlobalCall(ctx);
793
1.20M
  } else if (auto* ctx = tree_as<CelParser::CreateListContext>(primary)) {
794
21.7k
    return visitCreateList(ctx);
795
1.18M
  } else if (auto* ctx = tree_as<CelParser::CreateMapContext>(primary)) {
796
15.1k
    return visitCreateMap(ctx);
797
1.16M
  } else if (auto* ctx = tree_as<CelParser::CreateMessageContext>(primary)) {
798
7.64k
    return visitCreateMessage(ctx);
799
1.15M
  } else if (auto* ctx = tree_as<CelParser::ConstantLiteralContext>(primary)) {
800
1.15M
    return visitConstantLiteral(ctx);
801
1.15M
  }
802
1.43k
  if (factory_.HasErrors()) {
803
    // ANTLR creates PrimaryContext rather than a derived class during certain
804
    // error conditions. This is odd, but we ignore it as we already have errors
805
    // that occurred.
806
1.43k
    return ExprToAny(factory_.NewUnspecified(factory_.NextId({})));
807
1.43k
  }
808
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(pctx),
809
0
                                        "invalid primary expression"));
810
1.43k
}
811
812
0
std::any ParserVisitor::visitMemberExpr(CelParser::MemberExprContext* mctx) {
813
0
  CelParser::MemberContext* member = mctx->member();
814
0
  if (auto* ctx = tree_as<CelParser::PrimaryExprContext>(member)) {
815
0
    return visitPrimaryExpr(ctx);
816
0
  } else if (auto* ctx = tree_as<CelParser::SelectContext>(member)) {
817
0
    return visitSelect(ctx);
818
0
  } else if (auto* ctx = tree_as<CelParser::MemberCallContext>(member)) {
819
0
    return visitMemberCall(ctx);
820
0
  } else if (auto* ctx = tree_as<CelParser::IndexContext>(member)) {
821
0
    return visitIndex(ctx);
822
0
  }
823
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(mctx),
824
0
                                        "unsupported simple expression"));
825
0
}
826
827
0
std::any ParserVisitor::visitStart(CelParser::StartContext* ctx) {
828
0
  return visit(ctx->expr());
829
0
}
830
831
antlr4::tree::ParseTree* ParserVisitor::UnnestContext(
832
5.69M
    antlr4::tree::ParseTree* tree) {
833
5.69M
  antlr4::tree::ParseTree* last = nullptr;
834
6.39M
  while (tree != last) {
835
6.01M
    last = tree;
836
837
6.01M
    if (auto* ctx = tree_as<CelParser::StartContext>(tree)) {
838
20.3k
      tree = ctx->expr();
839
20.3k
    }
840
841
6.01M
    if (auto* ctx = tree_as<CelParser::ExprContext>(tree)) {
842
607k
      if (ctx->op != nullptr) {
843
2.47k
        return ctx;
844
2.47k
      }
845
604k
      tree = ctx->e;
846
604k
    }
847
848
6.01M
    if (auto* ctx = tree_as<CelParser::ConditionalOrContext>(tree)) {
849
1.13M
      if (!ctx->ops.empty()) {
850
2.56k
        return ctx;
851
2.56k
      }
852
1.13M
      tree = ctx->e;
853
1.13M
    }
854
855
6.00M
    if (auto* ctx = tree_as<CelParser::ConditionalAndContext>(tree)) {
856
1.19M
      if (!ctx->ops.empty()) {
857
2.02k
        return ctx;
858
2.02k
      }
859
1.19M
      tree = ctx->e;
860
1.19M
    }
861
862
6.00M
    if (auto* ctx = tree_as<CelParser::RelationContext>(tree)) {
863
1.48M
      if (ctx->calc() == nullptr) {
864
56.8k
        return ctx;
865
56.8k
      }
866
1.42M
      tree = ctx->calc();
867
1.42M
    }
868
869
5.95M
    if (auto* ctx = tree_as<CelParser::CalcContext>(tree)) {
870
5.26M
      if (ctx->unary() == nullptr) {
871
1.91M
        return ctx;
872
1.91M
      }
873
3.34M
      tree = ctx->unary();
874
3.34M
    }
875
876
4.03M
    if (auto* ctx = tree_as<CelParser::MemberExprContext>(tree)) {
877
3.07M
      tree = ctx->member();
878
3.07M
    }
879
880
4.03M
    if (auto* ctx = tree_as<CelParser::PrimaryExprContext>(tree)) {
881
3.33M
      if (auto* nested = tree_as<CelParser::NestedContext>(ctx->primary())) {
882
2.50k
        tree = nested->e;
883
3.33M
      } else {
884
3.33M
        return ctx;
885
3.33M
      }
886
3.33M
    }
887
4.03M
  }
888
889
379k
  return tree;
890
5.69M
}
891
892
527k
std::any ParserVisitor::visitExpr(CelParser::ExprContext* ctx) {
893
527k
  auto result = ExprFromAny(visit(ctx->e));
894
527k
  if (!ctx->op) {
895
524k
    return ExprToAny(std::move(result));
896
524k
  }
897
3.06k
  std::vector<Expr> arguments;
898
3.06k
  arguments.reserve(3);
899
3.06k
  arguments.push_back(std::move(result));
900
3.06k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
901
3.06k
  arguments.push_back(ExprFromAny(visit(ctx->e1)));
902
3.06k
  arguments.push_back(ExprFromAny(visit(ctx->e2)));
903
904
3.06k
  return ExprToAny(
905
3.06k
      factory_.NewCall(op_id, CelOperator::CONDITIONAL, std::move(arguments)));
906
527k
}
907
908
std::any ParserVisitor::visitConditionalOr(
909
2.56k
    CelParser::ConditionalOrContext* ctx) {
910
2.56k
  auto result = ExprFromAny(visit(ctx->e));
911
2.56k
  if (ctx->ops.empty()) {
912
0
    return ExprToAny(std::move(result));
913
0
  }
914
2.56k
  ExpressionBalancer b(factory_, CelOperator::LOGICAL_OR, std::move(result));
915
60.5k
  for (size_t i = 0; i < ctx->ops.size(); ++i) {
916
57.9k
    auto op = ctx->ops[i];
917
57.9k
    if (i >= ctx->e1.size()) {
918
0
      return ExprToAny(
919
0
          factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
920
0
                               "unexpected character, wanted '||'"));
921
0
    }
922
57.9k
    auto next = ExprFromAny(visit(ctx->e1[i]));
923
57.9k
    int64_t op_id = factory_.NextId(SourceRangeFromToken(op));
924
57.9k
    b.AddTerm(op_id, std::move(next));
925
57.9k
  }
926
2.56k
  return ExprToAny(b.Balance());
927
2.56k
}
928
929
std::any ParserVisitor::visitConditionalAnd(
930
2.02k
    CelParser::ConditionalAndContext* ctx) {
931
2.02k
  auto result = ExprFromAny(visit(ctx->e));
932
2.02k
  if (ctx->ops.empty()) {
933
0
    return ExprToAny(std::move(result));
934
0
  }
935
2.02k
  ExpressionBalancer b(factory_, CelOperator::LOGICAL_AND, std::move(result));
936
179k
  for (size_t i = 0; i < ctx->ops.size(); ++i) {
937
177k
    auto op = ctx->ops[i];
938
177k
    if (i >= ctx->e1.size()) {
939
0
      return ExprToAny(
940
0
          factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
941
0
                               "unexpected character, wanted '&&'"));
942
0
    }
943
177k
    auto next = ExprFromAny(visit(ctx->e1[i]));
944
177k
    int64_t op_id = factory_.NextId(SourceRangeFromToken(op));
945
177k
    b.AddTerm(op_id, std::move(next));
946
177k
  }
947
2.02k
  return ExprToAny(b.Balance());
948
2.02k
}
949
950
56.8k
std::any ParserVisitor::visitRelation(CelParser::RelationContext* ctx) {
951
56.8k
  if (ctx->calc()) {
952
0
    return visit(ctx->calc());
953
0
  }
954
56.8k
  std::string op_text;
955
56.8k
  if (ctx->op) {
956
56.8k
    op_text = ctx->op->getText();
957
56.8k
  }
958
56.8k
  auto op = ReverseLookupOperator(op_text);
959
56.8k
  if (op) {
960
56.8k
    auto lhs = ExprFromAny(visit(ctx->relation(0)));
961
56.8k
    int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
962
56.8k
    auto rhs = ExprFromAny(visit(ctx->relation(1)));
963
56.8k
    return ExprToAny(
964
56.8k
        GlobalCallOrMacro(op_id, *op, std::move(lhs), std::move(rhs)));
965
56.8k
  }
966
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
967
0
                                        "operator not found"));
968
56.8k
}
969
970
1.91M
std::any ParserVisitor::visitCalc(CelParser::CalcContext* ctx) {
971
1.91M
  if (ctx->unary()) {
972
0
    return visit(ctx->unary());
973
0
  }
974
1.91M
  std::string op_text;
975
1.91M
  if (ctx->op) {
976
1.91M
    op_text = ctx->op->getText();
977
1.91M
  }
978
1.91M
  auto op = ReverseLookupOperator(op_text);
979
1.91M
  if (op) {
980
1.91M
    auto lhs = ExprFromAny(visit(ctx->calc(0)));
981
1.91M
    int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
982
1.91M
    auto rhs = ExprFromAny(visit(ctx->calc(1)));
983
1.91M
    return ExprToAny(
984
1.91M
        GlobalCallOrMacro(op_id, *op, std::move(lhs), std::move(rhs)));
985
1.91M
  }
986
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
987
0
                                        "operator not found"));
988
1.91M
}
989
990
5.49k
std::any ParserVisitor::visitUnary(CelParser::UnaryContext* ctx) {
991
5.49k
  return ExprToAny(factory_.NewStringConst(
992
5.49k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)), "<<error>>"));
993
5.49k
}
994
995
4.49k
std::any ParserVisitor::visitLogicalNot(CelParser::LogicalNotContext* ctx) {
996
4.49k
  if (ctx->ops.size() % 2 == 0) {
997
893
    return visit(ctx->member());
998
893
  }
999
3.60k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->ops[0]));
1000
3.60k
  auto target = ExprFromAny(visit(ctx->member()));
1001
3.60k
  return ExprToAny(
1002
3.60k
      GlobalCallOrMacro(op_id, CelOperator::LOGICAL_NOT, std::move(target)));
1003
4.49k
}
1004
1005
257k
std::any ParserVisitor::visitNegate(CelParser::NegateContext* ctx) {
1006
257k
  if (ctx->ops.size() % 2 == 0) {
1007
8.13k
    return visit(ctx->member());
1008
8.13k
  }
1009
249k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->ops[0]));
1010
249k
  auto target = ExprFromAny(visit(ctx->member()));
1011
249k
  return ExprToAny(
1012
249k
      GlobalCallOrMacro(op_id, CelOperator::NEGATE, std::move(target)));
1013
257k
}
1014
1015
std::string ParserVisitor::NormalizeIdentifier(
1016
54.6k
    CelParser::EscapeIdentContext* ctx) {
1017
54.6k
  if (auto* raw_id = tree_as<CelParser::SimpleIdentifierContext>(ctx); raw_id) {
1018
52.1k
    return raw_id->id->getText();
1019
52.1k
  }
1020
2.48k
  if (auto* escaped_id = tree_as<CelParser::EscapedIdentifierContext>(ctx);
1021
2.48k
      escaped_id) {
1022
1.72k
    if (!enable_quoted_identifiers_) {
1023
0
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1024
0
                           "unsupported syntax '`'");
1025
0
    }
1026
1.72k
    auto escaped_id_text = escaped_id->id->getText();
1027
1.72k
    return escaped_id_text.substr(1, escaped_id_text.size() - 2);
1028
1.72k
  }
1029
1030
  // Fallthrough might occur if the parser is in an error state.
1031
762
  return "";
1032
2.48k
}
1033
1034
46.7k
std::any ParserVisitor::visitSelect(CelParser::SelectContext* ctx) {
1035
46.7k
  auto operand = ExprFromAny(visit(ctx->member()));
1036
  // Handle the error case where no valid identifier is specified.
1037
46.7k
  if (!ctx->id || !ctx->op) {
1038
0
    return ExprToAny(factory_.NewUnspecified(
1039
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1040
0
  }
1041
46.7k
  auto id = NormalizeIdentifier(ctx->id);
1042
46.7k
  if (ctx->opt != nullptr) {
1043
5.90k
    if (!enable_optional_syntax_) {
1044
5.90k
      return ExprToAny(factory_.ReportError(
1045
5.90k
          SourceRangeFromParserRuleContext(ctx), "unsupported syntax '.?'"));
1046
5.90k
    }
1047
0
    auto op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1048
0
    std::vector<Expr> arguments;
1049
0
    arguments.reserve(2);
1050
0
    arguments.push_back(std::move(operand));
1051
0
    arguments.push_back(factory_.NewStringConst(
1052
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx)), std::move(id)));
1053
0
    return ExprToAny(factory_.NewCall(op_id, "_?._", std::move(arguments)));
1054
5.90k
  }
1055
40.8k
  return ExprToAny(
1056
40.8k
      factory_.NewSelect(factory_.NextId(SourceRangeFromToken(ctx->op)),
1057
40.8k
                         std::move(operand), std::move(id)));
1058
46.7k
}
1059
1060
52.4k
std::any ParserVisitor::visitMemberCall(CelParser::MemberCallContext* ctx) {
1061
52.4k
  auto operand = ExprFromAny(visit(ctx->member()));
1062
  // Handle the error case where no valid identifier is specified.
1063
52.4k
  if (!ctx->id) {
1064
0
    return ExprToAny(factory_.NewUnspecified(
1065
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1066
0
  }
1067
52.4k
  auto id = ctx->id->getText();
1068
52.4k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->open));
1069
52.4k
  auto args = visitList(ctx->args);
1070
52.4k
  return ExprToAny(
1071
52.4k
      ReceiverCallOrMacroImpl(op_id, id, std::move(operand), std::move(args)));
1072
52.4k
}
1073
1074
11.3k
std::any ParserVisitor::visitIndex(CelParser::IndexContext* ctx) {
1075
11.3k
  auto target = ExprFromAny(visit(ctx->member()));
1076
11.3k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1077
11.3k
  auto index = ExprFromAny(visit(ctx->index));
1078
11.3k
  if (!enable_optional_syntax_ && ctx->opt != nullptr) {
1079
1.73k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1080
1.73k
                                          "unsupported syntax '.?'"));
1081
1.73k
  }
1082
9.63k
  return ExprToAny(GlobalCallOrMacro(
1083
9.63k
      op_id, ctx->opt != nullptr ? "_[?_]" : CelOperator::INDEX,
1084
9.63k
      std::move(target), std::move(index)));
1085
11.3k
}
1086
1087
std::any ParserVisitor::visitCreateMessage(
1088
7.64k
    CelParser::CreateMessageContext* ctx) {
1089
7.64k
  std::vector<std::string> parts;
1090
7.64k
  parts.reserve(ctx->ids.size());
1091
37.5k
  for (const auto* id : ctx->ids) {
1092
37.5k
    parts.push_back(id->getText());
1093
37.5k
  }
1094
7.64k
  std::string name;
1095
7.64k
  if (ctx->leadingDot) {
1096
1.96k
    name.push_back('.');
1097
1.96k
    name.append(absl::StrJoin(parts, "."));
1098
5.67k
  } else {
1099
5.67k
    name = absl::StrJoin(parts, ".");
1100
5.67k
  }
1101
7.64k
  int64_t obj_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1102
7.64k
  std::vector<StructExprField> fields;
1103
7.64k
  if (ctx->entries) {
1104
1.33k
    fields = visitFields(ctx->entries);
1105
1.33k
  }
1106
7.64k
  return ExprToAny(
1107
7.64k
      factory_.NewStruct(obj_id, std::move(name), std::move(fields)));
1108
7.64k
}
1109
1110
std::any ParserVisitor::visitFieldInitializerList(
1111
0
    CelParser::FieldInitializerListContext* ctx) {
1112
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1113
0
                                        "<<unreachable>>"));
1114
0
}
1115
1116
std::vector<StructExprField> ParserVisitor::visitFields(
1117
1.33k
    CelParser::FieldInitializerListContext* ctx) {
1118
1.33k
  std::vector<StructExprField> res;
1119
1.33k
  if (!ctx || ctx->fields.empty()) {
1120
0
    return res;
1121
0
  }
1122
1123
1.33k
  res.reserve(ctx->fields.size());
1124
9.25k
  for (size_t i = 0; i < ctx->fields.size(); ++i) {
1125
8.04k
    if (i >= ctx->cols.size() || i >= ctx->values.size()) {
1126
      // This is the result of a syntax error detected elsewhere.
1127
120
      return res;
1128
120
    }
1129
7.92k
    auto* f = ctx->fields[i];
1130
7.92k
    if (!f->escapeIdent()) {
1131
0
      ABSL_DCHECK(HasErrored());
1132
      // This is the result of a syntax error detected elsewhere.
1133
0
      return res;
1134
0
    }
1135
1136
7.92k
    std::string id = NormalizeIdentifier(f->escapeIdent());
1137
1138
7.92k
    int64_t init_id = factory_.NextId(SourceRangeFromToken(ctx->cols[i]));
1139
7.92k
    if (!enable_optional_syntax_ && f->opt) {
1140
365
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1141
365
                           "unsupported syntax '?'");
1142
365
      continue;
1143
365
    }
1144
7.56k
    auto value = ExprFromAny(visit(ctx->values[i]));
1145
7.56k
    res.push_back(factory_.NewStructField(init_id, std::move(id),
1146
7.56k
                                          std::move(value), f->opt != nullptr));
1147
7.56k
  }
1148
1149
1.21k
  return res;
1150
1.33k
}
1151
1152
2.09M
std::any ParserVisitor::visitIdent(CelParser::IdentContext* ctx) {
1153
2.09M
  std::string ident_name;
1154
2.09M
  if (ctx->leadingDot) {
1155
9.51k
    ident_name = ".";
1156
9.51k
  }
1157
2.09M
  if (!ctx->id) {
1158
0
    return ExprToAny(factory_.NewUnspecified(
1159
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1160
0
  }
1161
  // check if ID is in reserved identifiers
1162
2.09M
  if (cel::internal::LexisIsReserved(ctx->id->getText())) {
1163
1.01k
    return ExprToAny(factory_.ReportError(
1164
1.01k
        SourceRangeFromParserRuleContext(ctx),
1165
1.01k
        absl::StrFormat("reserved identifier: %s", ctx->id->getText())));
1166
1.01k
  }
1167
1168
2.09M
  ident_name += ctx->id->getText();
1169
1170
2.09M
  return ExprToAny(factory_.NewIdent(
1171
2.09M
      factory_.NextId(SourceRangeFromToken(ctx->id)), std::move(ident_name)));
1172
2.09M
}
1173
1174
40.9k
std::any ParserVisitor::visitGlobalCall(CelParser::GlobalCallContext* ctx) {
1175
40.9k
  std::string ident_name;
1176
40.9k
  if (ctx->leadingDot) {
1177
1.61k
    ident_name = ".";
1178
1.61k
  }
1179
40.9k
  if (!ctx->id || !ctx->op) {
1180
0
    return ExprToAny(factory_.NewUnspecified(
1181
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1182
0
  }
1183
  // check if ID is in reserved identifiers
1184
40.9k
  if (cel::internal::LexisIsReserved(ctx->id->getText())) {
1185
114
    return ExprToAny(factory_.ReportError(
1186
114
        SourceRangeFromParserRuleContext(ctx),
1187
114
        absl::StrFormat("reserved identifier: %s", ctx->id->getText())));
1188
114
  }
1189
1190
40.8k
  ident_name += ctx->id->getText();
1191
1192
40.8k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1193
40.8k
  auto args = visitList(ctx->args);
1194
40.8k
  return ExprToAny(
1195
40.8k
      GlobalCallOrMacroImpl(op_id, std::move(ident_name), std::move(args)));
1196
40.9k
}
1197
1198
0
std::any ParserVisitor::visitNested(CelParser::NestedContext* ctx) {
1199
0
  return visit(ctx->e);
1200
0
}
1201
1202
21.7k
std::any ParserVisitor::visitCreateList(CelParser::CreateListContext* ctx) {
1203
21.7k
  int64_t list_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1204
21.7k
  auto elems = visitList(ctx->elems);
1205
21.7k
  return ExprToAny(factory_.NewList(list_id, std::move(elems)));
1206
21.7k
}
1207
1208
std::vector<ListExprElement> ParserVisitor::visitList(
1209
21.7k
    CelParser::ListInitContext* ctx) {
1210
21.7k
  std::vector<ListExprElement> rv;
1211
21.7k
  if (!ctx) return rv;
1212
18.6k
  rv.reserve(ctx->elems.size());
1213
391k
  for (size_t i = 0; i < ctx->elems.size(); ++i) {
1214
372k
    auto* expr_ctx = ctx->elems[i];
1215
372k
    if (expr_ctx == nullptr) {
1216
0
      return rv;
1217
0
    }
1218
372k
    if (!enable_optional_syntax_ && expr_ctx->opt != nullptr) {
1219
646
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1220
646
                           "unsupported syntax '?'");
1221
646
      rv.push_back(factory_.NewListElement(factory_.NewUnspecified(0), false));
1222
646
      continue;
1223
646
    }
1224
372k
    rv.push_back(factory_.NewListElement(ExprFromAny(visitExpr(expr_ctx->e)),
1225
372k
                                         expr_ctx->opt != nullptr));
1226
372k
  }
1227
18.6k
  return rv;
1228
18.6k
}
1229
1230
93.2k
std::vector<Expr> ParserVisitor::visitList(CelParser::ExprListContext* ctx) {
1231
93.2k
  std::vector<Expr> rv;
1232
93.2k
  if (!ctx) return rv;
1233
72.0k
  std::transform(ctx->e.begin(), ctx->e.end(), std::back_inserter(rv),
1234
152k
                 [this](CelParser::ExprContext* expr_ctx) {
1235
152k
                   return ExprFromAny(visitExpr(expr_ctx));
1236
152k
                 });
1237
72.0k
  return rv;
1238
93.2k
}
1239
1240
15.1k
std::any ParserVisitor::visitCreateMap(CelParser::CreateMapContext* ctx) {
1241
15.1k
  int64_t struct_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1242
15.1k
  std::vector<MapExprEntry> entries;
1243
15.1k
  if (ctx->entries) {
1244
6.72k
    entries = visitEntries(ctx->entries);
1245
6.72k
  }
1246
15.1k
  return ExprToAny(factory_.NewMap(struct_id, std::move(entries)));
1247
15.1k
}
1248
1249
std::any ParserVisitor::visitConstantLiteral(
1250
1.15M
    CelParser::ConstantLiteralContext* clctx) {
1251
1.15M
  CelParser::LiteralContext* literal = clctx->literal();
1252
1.15M
  if (auto* ctx = tree_as<CelParser::IntContext>(literal)) {
1253
747k
    return visitInt(ctx);
1254
747k
  } else if (auto* ctx = tree_as<CelParser::UintContext>(literal)) {
1255
25.5k
    return visitUint(ctx);
1256
383k
  } else if (auto* ctx = tree_as<CelParser::DoubleContext>(literal)) {
1257
79.5k
    return visitDouble(ctx);
1258
303k
  } else if (auto* ctx = tree_as<CelParser::StringContext>(literal)) {
1259
288k
    return visitString(ctx);
1260
288k
  } else if (auto* ctx = tree_as<CelParser::BytesContext>(literal)) {
1261
10.5k
    return visitBytes(ctx);
1262
10.5k
  } else if (auto* ctx = tree_as<CelParser::BoolFalseContext>(literal)) {
1263
1.07k
    return visitBoolFalse(ctx);
1264
3.75k
  } else if (auto* ctx = tree_as<CelParser::BoolTrueContext>(literal)) {
1265
1.06k
    return visitBoolTrue(ctx);
1266
2.69k
  } else if (auto* ctx = tree_as<CelParser::NullContext>(literal)) {
1267
2.10k
    return visitNull(ctx);
1268
2.10k
  }
1269
597
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(clctx),
1270
597
                                        "invalid constant literal expression"));
1271
1.15M
}
1272
1273
std::any ParserVisitor::visitMapInitializerList(
1274
0
    CelParser::MapInitializerListContext* ctx) {
1275
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1276
0
                                        "<<unreachable>>"));
1277
0
}
1278
1279
std::vector<MapExprEntry> ParserVisitor::visitEntries(
1280
6.72k
    CelParser::MapInitializerListContext* ctx) {
1281
6.72k
  std::vector<MapExprEntry> res;
1282
6.72k
  if (!ctx || ctx->keys.empty()) {
1283
0
    return res;
1284
0
  }
1285
1286
6.72k
  res.reserve(ctx->cols.size());
1287
288k
  for (size_t i = 0; i < ctx->cols.size(); ++i) {
1288
282k
    auto id = factory_.NextId(SourceRangeFromToken(ctx->cols[i]));
1289
282k
    if (!enable_optional_syntax_ && ctx->keys[i]->opt) {
1290
126
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1291
126
                           "unsupported syntax '?'");
1292
126
      res.push_back(factory_.NewMapEntry(0, factory_.NewUnspecified(0),
1293
126
                                         factory_.NewUnspecified(0), false));
1294
126
      continue;
1295
126
    }
1296
282k
    auto key = ExprFromAny(visit(ctx->keys[i]->e));
1297
282k
    auto value = ExprFromAny(visit(ctx->values[i]));
1298
282k
    res.push_back(factory_.NewMapEntry(id, std::move(key), std::move(value),
1299
282k
                                       ctx->keys[i]->opt != nullptr));
1300
282k
  }
1301
6.72k
  return res;
1302
6.72k
}
1303
1304
747k
std::any ParserVisitor::visitInt(CelParser::IntContext* ctx) {
1305
747k
  std::string value;
1306
747k
  if (ctx->sign) {
1307
19.1k
    value = ctx->sign->getText();
1308
19.1k
  }
1309
747k
  value += ctx->tok->getText();
1310
747k
  int64_t int_value;
1311
747k
  if (absl::StartsWith(ctx->tok->getText(), "0x")) {
1312
2.74k
    if (absl::SimpleHexAtoi(value, &int_value)) {
1313
1.43k
      return ExprToAny(factory_.NewIntConst(
1314
1.43k
          factory_.NextId(SourceRangeFromParserRuleContext(ctx)), int_value));
1315
1.43k
    } else {
1316
1.31k
      return ExprToAny(factory_.ReportError(
1317
1.31k
          SourceRangeFromParserRuleContext(ctx), "invalid hex int literal"));
1318
1.31k
    }
1319
2.74k
  }
1320
745k
  if (absl::SimpleAtoi(value, &int_value)) {
1321
741k
    return ExprToAny(factory_.NewIntConst(
1322
741k
        factory_.NextId(SourceRangeFromParserRuleContext(ctx)), int_value));
1323
741k
  } else {
1324
4.14k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1325
4.14k
                                          "invalid int literal"));
1326
4.14k
  }
1327
745k
}
1328
1329
25.5k
std::any ParserVisitor::visitUint(CelParser::UintContext* ctx) {
1330
25.5k
  std::string value = ctx->tok->getText();
1331
  // trim the 'u' designator included in the uint literal.
1332
25.5k
  if (!value.empty()) {
1333
25.5k
    value.resize(value.size() - 1);
1334
25.5k
  }
1335
25.5k
  uint64_t uint_value;
1336
25.5k
  if (absl::StartsWith(ctx->tok->getText(), "0x")) {
1337
3.61k
    if (absl::SimpleHexAtoi(value, &uint_value)) {
1338
1.24k
      return ExprToAny(factory_.NewUintConst(
1339
1.24k
          factory_.NextId(SourceRangeFromParserRuleContext(ctx)), uint_value));
1340
2.36k
    } else {
1341
2.36k
      return ExprToAny(factory_.ReportError(
1342
2.36k
          SourceRangeFromParserRuleContext(ctx), "invalid hex uint literal"));
1343
2.36k
    }
1344
3.61k
  }
1345
21.9k
  if (absl::SimpleAtoi(value, &uint_value)) {
1346
19.9k
    return ExprToAny(factory_.NewUintConst(
1347
19.9k
        factory_.NextId(SourceRangeFromParserRuleContext(ctx)), uint_value));
1348
19.9k
  } else {
1349
1.95k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1350
1.95k
                                          "invalid uint literal"));
1351
1.95k
  }
1352
21.9k
}
1353
1354
79.5k
std::any ParserVisitor::visitDouble(CelParser::DoubleContext* ctx) {
1355
79.5k
  std::string value;
1356
79.5k
  if (ctx->sign) {
1357
5.20k
    value = ctx->sign->getText();
1358
5.20k
  }
1359
79.5k
  value += ctx->tok->getText();
1360
79.5k
  double double_value;
1361
79.5k
  if (absl::SimpleAtod(value, &double_value)) {
1362
79.5k
    return ExprToAny(factory_.NewDoubleConst(
1363
79.5k
        factory_.NextId(SourceRangeFromParserRuleContext(ctx)), double_value));
1364
79.5k
  } else {
1365
0
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1366
0
                                          "invalid double literal"));
1367
0
  }
1368
79.5k
}
1369
1370
288k
std::any ParserVisitor::visitString(CelParser::StringContext* ctx) {
1371
288k
  auto status_or_value = cel::internal::ParseStringLiteral(ctx->tok->getText());
1372
288k
  if (!status_or_value.ok()) {
1373
2.89k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1374
2.89k
                                          status_or_value.status().message()));
1375
2.89k
  }
1376
285k
  return ExprToAny(factory_.NewStringConst(
1377
285k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)),
1378
285k
      std::move(status_or_value).value()));
1379
288k
}
1380
1381
10.5k
std::any ParserVisitor::visitBytes(CelParser::BytesContext* ctx) {
1382
10.5k
  auto status_or_value = cel::internal::ParseBytesLiteral(ctx->tok->getText());
1383
10.5k
  if (!status_or_value.ok()) {
1384
2.38k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1385
2.38k
                                          status_or_value.status().message()));
1386
2.38k
  }
1387
8.18k
  return ExprToAny(factory_.NewBytesConst(
1388
8.18k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)),
1389
8.18k
      std::move(status_or_value).value()));
1390
10.5k
}
1391
1392
1.06k
std::any ParserVisitor::visitBoolTrue(CelParser::BoolTrueContext* ctx) {
1393
1.06k
  return ExprToAny(factory_.NewBoolConst(
1394
1.06k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)), true));
1395
1.06k
}
1396
1397
1.07k
std::any ParserVisitor::visitBoolFalse(CelParser::BoolFalseContext* ctx) {
1398
1.07k
  return ExprToAny(factory_.NewBoolConst(
1399
1.07k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)), false));
1400
1.07k
}
1401
1402
2.10k
std::any ParserVisitor::visitNull(CelParser::NullContext* ctx) {
1403
2.10k
  return ExprToAny(factory_.NewNullConst(
1404
2.10k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1405
2.10k
}
1406
1407
12.1k
cel::SourceInfo ParserVisitor::GetSourceInfo() {
1408
12.1k
  cel::SourceInfo source_info;
1409
12.1k
  source_info.set_location(std::string(source_.description()));
1410
2.78M
  for (const auto& positions : factory_.positions()) {
1411
2.78M
    source_info.mutable_positions().insert(
1412
2.78M
        std::pair{positions.first, positions.second.begin});
1413
2.78M
  }
1414
12.1k
  source_info.mutable_line_offsets().reserve(source_.line_offsets().size());
1415
6.05M
  for (const auto& line_offset : source_.line_offsets()) {
1416
6.05M
    source_info.mutable_line_offsets().push_back(line_offset);
1417
6.05M
  }
1418
1419
12.1k
  source_info.mutable_macro_calls() = factory_.release_macro_calls();
1420
12.1k
  return source_info;
1421
12.1k
}
1422
1423
12.1k
EnrichedSourceInfo ParserVisitor::enriched_source_info() const {
1424
12.1k
  std::map<int64_t, std::pair<int32_t, int32_t>> offsets;
1425
2.78M
  for (const auto& positions : factory_.positions()) {
1426
2.78M
    offsets.insert(
1427
2.78M
        std::pair{positions.first,
1428
2.78M
                  std::pair{positions.second.begin, positions.second.end - 1}});
1429
2.78M
  }
1430
12.1k
  return EnrichedSourceInfo(std::move(offsets));
1431
12.1k
}
1432
1433
void ParserVisitor::syntaxError(antlr4::Recognizer* recognizer,
1434
                                antlr4::Token* offending_symbol, size_t line,
1435
                                size_t col, const std::string& msg,
1436
8.36M
                                std::exception_ptr e) {
1437
8.36M
  cel::SourceRange range;
1438
8.36M
  if (auto position = source_.GetPosition(cel::SourceLocation{
1439
8.36M
          static_cast<int32_t>(line), static_cast<int32_t>(col)});
1440
8.36M
      position) {
1441
8.36M
    range.begin = *position;
1442
8.36M
  }
1443
8.36M
  factory_.ReportError(range, absl::StrCat("Syntax error: ", msg));
1444
8.36M
}
1445
1446
21.4k
bool ParserVisitor::HasErrored() const { return factory_.HasErrors(); }
1447
1448
9.29k
std::vector<cel::ParseIssue> ParserVisitor::CollectIssues() {
1449
9.29k
  return factory_.CollectIssues();
1450
9.29k
}
1451
1452
Expr ParserVisitor::GlobalCallOrMacroImpl(int64_t expr_id,
1453
                                          absl::string_view function,
1454
2.27M
                                          std::vector<Expr> args) {
1455
2.27M
  if (auto macro = macro_registry_.FindMacro(function, args.size(), false);
1456
2.27M
      macro) {
1457
13.5k
    std::vector<Expr> macro_args;
1458
13.5k
    if (add_macro_calls_) {
1459
0
      macro_args.reserve(args.size());
1460
0
      for (const auto& arg : args) {
1461
0
        macro_args.push_back(factory_.BuildMacroCallArg(arg));
1462
0
      }
1463
0
    }
1464
13.5k
    factory_.BeginMacro(factory_.GetSourceRange(expr_id));
1465
13.5k
    auto expr = macro->Expand(factory_, absl::nullopt, absl::MakeSpan(args));
1466
13.5k
    factory_.EndMacro();
1467
13.5k
    if (expr) {
1468
13.5k
      if (add_macro_calls_) {
1469
0
        factory_.AddMacroCall(expr->id(), function, absl::nullopt,
1470
0
                              std::move(macro_args));
1471
0
      }
1472
      // We did not end up using `expr_id`. Delete metadata.
1473
13.5k
      factory_.EraseId(expr_id);
1474
13.5k
      return std::move(*expr);
1475
13.5k
    }
1476
13.5k
  }
1477
1478
2.26M
  return factory_.NewCall(expr_id, function, std::move(args));
1479
2.27M
}
1480
1481
Expr ParserVisitor::ReceiverCallOrMacroImpl(int64_t expr_id,
1482
                                            absl::string_view function,
1483
                                            Expr target,
1484
52.4k
                                            std::vector<Expr> args) {
1485
52.4k
  if (auto macro = macro_registry_.FindMacro(function, args.size(), true);
1486
52.4k
      macro) {
1487
27.9k
    Expr macro_target;
1488
27.9k
    std::vector<Expr> macro_args;
1489
27.9k
    if (add_macro_calls_) {
1490
0
      macro_args.reserve(args.size());
1491
0
      macro_target = factory_.BuildMacroCallArg(target);
1492
0
      for (const auto& arg : args) {
1493
0
        macro_args.push_back(factory_.BuildMacroCallArg(arg));
1494
0
      }
1495
0
    }
1496
27.9k
    factory_.BeginMacro(factory_.GetSourceRange(expr_id));
1497
27.9k
    auto expr = macro->Expand(factory_, std::ref(target), absl::MakeSpan(args));
1498
27.9k
    factory_.EndMacro();
1499
27.9k
    if (expr) {
1500
27.9k
      if (add_macro_calls_) {
1501
0
        factory_.AddMacroCall(expr->id(), function, std::move(macro_target),
1502
0
                              std::move(macro_args));
1503
0
      }
1504
      // We did not end up using `expr_id`. Delete metadata.
1505
27.9k
      factory_.EraseId(expr_id);
1506
27.9k
      return std::move(*expr);
1507
27.9k
    }
1508
27.9k
  }
1509
24.4k
  return factory_.NewMemberCall(expr_id, function, std::move(target),
1510
24.4k
                                std::move(args));
1511
52.4k
}
1512
1513
std::string ParserVisitor::ExtractQualifiedName(antlr4::ParserRuleContext* ctx,
1514
0
                                                const Expr& e) {
1515
0
  if (e == Expr{}) {
1516
0
    return "";
1517
0
  }
1518
0
1519
0
  if (const auto* ident_expr = absl::get_if<IdentExpr>(&e.kind()); ident_expr) {
1520
0
    return ident_expr->name();
1521
0
  }
1522
0
  if (const auto* select_expr = absl::get_if<SelectExpr>(&e.kind());
1523
0
      select_expr) {
1524
0
    std::string prefix = ExtractQualifiedName(ctx, select_expr->operand());
1525
0
    if (!prefix.empty()) {
1526
0
      return absl::StrCat(prefix, ".", select_expr->field());
1527
0
    }
1528
0
  }
1529
0
  factory_.ReportError(factory_.GetSourceRange(e.id()),
1530
0
                       "expected a qualified name");
1531
0
  return "";
1532
0
}
1533
1534
// Replacements for absl::StrReplaceAll for escaping standard whitespace
1535
// characters.
1536
static constexpr auto kStandardReplacements =
1537
    std::array<std::pair<absl::string_view, absl::string_view>, 3>{
1538
        std::make_pair("\n", "\\n"),
1539
        std::make_pair("\r", "\\r"),
1540
        std::make_pair("\t", "\\t"),
1541
    };
1542
1543
static constexpr absl::string_view kSingleQuote = "'";
1544
1545
// ExprRecursionListener extends the standard ANTLR CelParser to ensure that
1546
// recursive entries into the 'expr' rule are limited to a configurable depth so
1547
// as to prevent stack overflows.
1548
class ExprRecursionListener final : public ParseTreeListener {
1549
 public:
1550
  explicit ExprRecursionListener(
1551
      const int max_recursion_depth = kDefaultMaxRecursionDepth)
1552
21.4k
      : max_recursion_depth_(max_recursion_depth), recursion_depth_(0) {}
1553
0
  ~ExprRecursionListener() override {}
1554
1555
9.28M
  void visitTerminal(TerminalNode* node) override {};
1556
117k
  void visitErrorNode(ErrorNode* error) override {};
1557
  void enterEveryRule(ParserRuleContext* ctx) override;
1558
  void exitEveryRule(ParserRuleContext* ctx) override;
1559
1560
 private:
1561
  const int max_recursion_depth_;
1562
  int recursion_depth_;
1563
};
1564
1565
24.2M
void ExprRecursionListener::enterEveryRule(ParserRuleContext* ctx) {
1566
  // Throw a ParseCancellationException since the parsing would otherwise
1567
  // continue if this were treated as a syntax error and the problem would
1568
  // continue to manifest.
1569
24.2M
  if (ctx->getRuleIndex() == CelParser::RuleExpr) {
1570
1.20M
    if (recursion_depth_ > max_recursion_depth_) {
1571
35
      throw ParseCancellationException(
1572
35
          absl::StrFormat("Expression recursion limit exceeded. limit: %d",
1573
35
                          max_recursion_depth_));
1574
35
    }
1575
1.20M
    recursion_depth_++;
1576
1.20M
  }
1577
24.2M
}
1578
1579
24.2M
void ExprRecursionListener::exitEveryRule(ParserRuleContext* ctx) {
1580
24.2M
  if (ctx->getRuleIndex() == CelParser::RuleExpr) {
1581
1.20M
    recursion_depth_--;
1582
1.20M
  }
1583
24.2M
}
1584
1585
class RecoveryLimitErrorStrategy final : public DefaultErrorStrategy {
1586
 public:
1587
  explicit RecoveryLimitErrorStrategy(
1588
      int recovery_limit = kDefaultErrorRecoveryLimit,
1589
      int recovery_token_lookahead_limit =
1590
          kDefaultErrorRecoveryTokenLookaheadLimit)
1591
21.4k
      : recovery_limit_(recovery_limit),
1592
21.4k
        recovery_attempts_(0),
1593
21.4k
        recovery_token_lookahead_limit_(recovery_token_lookahead_limit) {}
1594
1595
27.9k
  void recover(Parser* recognizer, std::exception_ptr e) override {
1596
27.9k
    checkRecoveryLimit(recognizer);
1597
27.9k
    DefaultErrorStrategy::recover(recognizer, e);
1598
27.9k
  }
1599
1600
19.5k
  Token* recoverInline(Parser* recognizer) override {
1601
19.5k
    checkRecoveryLimit(recognizer);
1602
19.5k
    return DefaultErrorStrategy::recoverInline(recognizer);
1603
19.5k
  }
1604
1605
  // Override the ANTLR implementation to introduce a token lookahead limit as
1606
  // this prevents pathologically constructed, yet small (< 16kb) inputs from
1607
  // consuming inordinate amounts of compute.
1608
  //
1609
  // This method is only called on error recovery paths.
1610
31.1k
  void consumeUntil(Parser* recognizer, const IntervalSet& set) override {
1611
31.1k
    size_t ttype = recognizer->getInputStream()->LA(1);
1612
31.1k
    int recovery_search_depth = 0;
1613
127k
    while (ttype != Token::EOF && !set.contains(ttype) &&
1614
96.6k
           recovery_search_depth++ < recovery_token_lookahead_limit_) {
1615
96.6k
      recognizer->consume();
1616
96.6k
      ttype = recognizer->getInputStream()->LA(1);
1617
96.6k
    }
1618
    // Halt all parsing if the lookahead limit is reached during error recovery.
1619
31.1k
    if (recovery_search_depth == recovery_token_lookahead_limit_) {
1620
4
      throw ParseCancellationException("Unable to find a recovery token");
1621
4
    }
1622
31.1k
  }
1623
1624
 protected:
1625
44.0k
  std::string escapeWSAndQuote(const std::string& s) const override {
1626
44.0k
    std::string result;
1627
44.0k
    result.reserve(s.size() + 2);
1628
44.0k
    absl::StrAppend(&result, kSingleQuote, s, kSingleQuote);
1629
44.0k
    absl::StrReplaceAll(kStandardReplacements, &result);
1630
44.0k
    return result;
1631
44.0k
  }
1632
1633
 private:
1634
47.5k
  void checkRecoveryLimit(Parser* recognizer) {
1635
47.5k
    if (recovery_attempts_++ >= recovery_limit_) {
1636
1.11k
      std::string too_many_errors =
1637
1.11k
          absl::StrFormat("More than %d parse errors.", recovery_limit_);
1638
1.11k
      recognizer->notifyErrorListeners(too_many_errors);
1639
1.11k
      throw ParseCancellationException(too_many_errors);
1640
1.11k
    }
1641
47.5k
  }
1642
1643
  int recovery_limit_;
1644
  int recovery_attempts_;
1645
  int recovery_token_lookahead_limit_;
1646
};
1647
1648
struct ParseResult {
1649
  cel::Expr expr;
1650
  cel::SourceInfo source_info;
1651
  EnrichedSourceInfo enriched_source_info;
1652
};
1653
1654
absl::StatusOr<ParseResult> ParseImpl(
1655
    const cel::Source& source, const cel::MacroRegistry& registry,
1656
    const ParserOptions& options,
1657
21.4k
    std::vector<cel::ParseIssue>* parse_issues = nullptr) {
1658
21.4k
  try {
1659
21.4k
    CodePointStream input(source.content(), source.description());
1660
21.4k
    if (input.size() > options.expression_size_codepoint_limit) {
1661
0
      return absl::InvalidArgumentError(absl::StrCat(
1662
0
          "expression size exceeds codepoint limit.", " input size: ",
1663
0
          input.size(), ", limit: ", options.expression_size_codepoint_limit));
1664
0
    }
1665
21.4k
    CelLexer lexer(&input);
1666
21.4k
    CommonTokenStream tokens(&lexer);
1667
21.4k
    CelParser parser(&tokens);
1668
21.4k
    ExprRecursionListener listener(options.max_recursion_depth);
1669
21.4k
    ParserVisitor visitor(
1670
21.4k
        source, options.max_recursion_depth, registry, options.add_macro_calls,
1671
21.4k
        options.enable_optional_syntax, options.enable_quoted_identifiers);
1672
1673
21.4k
    lexer.removeErrorListeners();
1674
21.4k
    parser.removeErrorListeners();
1675
21.4k
    lexer.addErrorListener(&visitor);
1676
21.4k
    parser.addErrorListener(&visitor);
1677
21.4k
    parser.addParseListener(&listener);
1678
1679
    // Limit the number of error recovery attempts to prevent bad expressions
1680
    // from consuming lots of cpu / memory.
1681
21.4k
    parser.setErrorHandler(std::make_shared<RecoveryLimitErrorStrategy>(
1682
21.4k
        options.error_recovery_limit,
1683
21.4k
        options.error_recovery_token_lookahead_limit));
1684
1685
21.4k
    Expr expr;
1686
21.4k
    try {
1687
21.4k
      expr = ExprFromAny(visitor.visit(parser.start()));
1688
21.4k
    } catch (const ParseCancellationException& e) {
1689
1.15k
      if (visitor.HasErrored()) {
1690
1.14k
        auto issues = visitor.CollectIssues();
1691
1.14k
        std::string error_message = FormatIssues(source, issues);
1692
1.14k
        if (parse_issues != nullptr) {
1693
0
          *parse_issues = std::move(issues);
1694
0
        }
1695
1.14k
        return absl::InvalidArgumentError(error_message);
1696
1.14k
      }
1697
9
      return absl::CancelledError(e.what());
1698
1.15k
    }
1699
1700
20.3k
    if (visitor.HasErrored()) {
1701
8.15k
      auto issues = visitor.CollectIssues();
1702
8.15k
      std::string error_message = FormatIssues(source, issues);
1703
8.15k
      if (parse_issues != nullptr) {
1704
0
        *parse_issues = std::move(issues);
1705
0
      }
1706
8.15k
      return absl::InvalidArgumentError(error_message);
1707
8.15k
    }
1708
1709
12.1k
    return {
1710
12.1k
        ParseResult{.expr = std::move(expr),
1711
12.1k
                    .source_info = visitor.GetSourceInfo(),
1712
12.1k
                    .enriched_source_info = visitor.enriched_source_info()}};
1713
20.3k
  } catch (const std::exception& e) {
1714
0
    return absl::AbortedError(e.what());
1715
0
  } catch (const char* what) {
1716
    // ANTLRv4 has historically thrown C string literals.
1717
0
    return absl::AbortedError(what);
1718
0
  } catch (...) {
1719
    // We guarantee to never throw and always return a status.
1720
0
    return absl::UnknownError("An unknown exception occurred");
1721
0
  }
1722
21.4k
}
1723
1724
class ParserImpl : public cel::Parser {
1725
 public:
1726
  explicit ParserImpl(const ParserOptions& options,
1727
                      cel::MacroRegistry macro_registry,
1728
                      absl::flat_hash_set<std::string> library_ids)
1729
0
      : options_(options),
1730
0
        macro_registry_(std::move(macro_registry)),
1731
0
        library_ids_(std::move(library_ids)) {}
1732
1733
  absl::StatusOr<std::unique_ptr<cel::Ast>> ParseImpl(
1734
      const cel::Source& source,
1735
0
      std::vector<cel::ParseIssue>* parse_issues) const override {
1736
0
    CEL_ASSIGN_OR_RETURN(auto parse_result,
1737
0
                         ::google::api::expr::parser::ParseImpl(
1738
0
                             source, macro_registry_, options_, parse_issues));
1739
0
    return std::make_unique<cel::Ast>(std::move(parse_result.expr),
1740
0
                                      std::move(parse_result.source_info));
1741
0
  }
1742
1743
  std::unique_ptr<cel::ParserBuilder> ToBuilder() const override;
1744
1745
 private:
1746
  const ParserOptions options_;
1747
  const cel::MacroRegistry macro_registry_;
1748
  absl::flat_hash_set<std::string> library_ids_;
1749
};
1750
1751
class ParserBuilderImpl : public cel::ParserBuilder {
1752
 public:
1753
  explicit ParserBuilderImpl(const ParserOptions& options)
1754
0
      : options_(options) {}
1755
1756
0
  ParserOptions& GetOptions() override { return options_; }
1757
1758
0
  absl::Status AddMacro(const cel::Macro& macro) override {
1759
0
    for (const auto& existing_macro : macros_) {
1760
0
      if (existing_macro.key() == macro.key()) {
1761
0
        return absl::AlreadyExistsError(
1762
0
            absl::StrCat("macro already exists: ", macro.key()));
1763
0
      }
1764
0
    }
1765
0
    macros_.push_back(macro);
1766
0
    return absl::OkStatus();
1767
0
  }
1768
1769
0
  absl::Status AddLibrary(cel::ParserLibrary library) override {
1770
0
    if (!library.id.empty()) {
1771
0
      auto [it, inserted] = library_ids_.insert(library.id);
1772
0
      if (!inserted) {
1773
0
        return absl::AlreadyExistsError(
1774
0
            absl::StrCat("parser library already exists: ", library.id));
1775
0
      }
1776
0
    }
1777
0
    libraries_.push_back(std::move(library));
1778
0
    return absl::OkStatus();
1779
0
  }
1780
1781
0
  absl::Status AddLibrarySubset(cel::ParserLibrarySubset subset) override {
1782
0
    if (subset.library_id.empty()) {
1783
0
      return absl::InvalidArgumentError("subset must have a library id");
1784
0
    }
1785
0
    std::string library_id = subset.library_id;
1786
0
    auto [it, inserted] =
1787
0
        library_subsets_.insert({library_id, std::move(subset)});
1788
0
    if (!inserted) {
1789
0
      return absl::AlreadyExistsError(
1790
0
          absl::StrCat("parser library subset already exists: ", library_id));
1791
0
    }
1792
0
    return absl::OkStatus();
1793
0
  }
1794
1795
0
  absl::StatusOr<std::unique_ptr<cel::Parser>> Build() override {
1796
0
    using std::swap;
1797
    // Save the old configured macros so they aren't affected by applying the
1798
    // libraries and can be restored if an error occurs.
1799
0
    std::vector<cel::Macro> individual_macros;
1800
0
    swap(individual_macros, macros_);
1801
0
    absl::Cleanup cleanup([&] { swap(macros_, individual_macros); });
1802
1803
0
    cel::MacroRegistry macro_registry;
1804
1805
0
    for (const auto& library : libraries_) {
1806
0
      CEL_RETURN_IF_ERROR(library.configure(*this));
1807
0
      if (!library.id.empty()) {
1808
0
        auto it = library_subsets_.find(library.id);
1809
0
        if (it != library_subsets_.end()) {
1810
0
          const cel::ParserLibrarySubset& subset = it->second;
1811
0
          for (const auto& macro : macros_) {
1812
0
            if (subset.should_include_macro(macro)) {
1813
0
              CEL_RETURN_IF_ERROR(macro_registry.RegisterMacro(macro));
1814
0
            }
1815
0
          }
1816
0
          macros_.clear();
1817
0
          continue;
1818
0
        }
1819
0
      }
1820
1821
0
      CEL_RETURN_IF_ERROR(macro_registry.RegisterMacros(macros_));
1822
0
      macros_.clear();
1823
0
    }
1824
1825
0
    absl::flat_hash_set<std::string> library_ids(library_ids_);
1826
1827
    // Hack to support adding the standard library macros either by option or
1828
    // with a library configurer.
1829
0
    if (!options_.disable_standard_macros && !library_ids_.contains("stdlib")) {
1830
0
      CEL_RETURN_IF_ERROR(macro_registry.RegisterMacros(Macro::AllMacros()));
1831
0
      library_ids.insert("stdlib");
1832
0
    }
1833
1834
0
    if (options_.enable_optional_syntax && !library_ids_.contains("optional")) {
1835
0
      CEL_RETURN_IF_ERROR(macro_registry.RegisterMacro(cel::OptMapMacro()));
1836
0
      CEL_RETURN_IF_ERROR(macro_registry.RegisterMacro(cel::OptFlatMapMacro()));
1837
0
      library_ids.insert("optional");
1838
0
    }
1839
0
    CEL_RETURN_IF_ERROR(macro_registry.RegisterMacros(individual_macros));
1840
0
    return std::make_unique<ParserImpl>(options_, std::move(macro_registry),
1841
0
                                        std::move(library_ids));
1842
0
  }
1843
1844
 private:
1845
  friend class ParserImpl;
1846
1847
  ParserOptions options_;
1848
  std::vector<cel::Macro> macros_;
1849
  absl::flat_hash_set<std::string> library_ids_;
1850
  std::vector<cel::ParserLibrary> libraries_;
1851
  absl::flat_hash_map<std::string, cel::ParserLibrarySubset> library_subsets_;
1852
};
1853
1854
0
std::unique_ptr<cel::ParserBuilder> ParserImpl::ToBuilder() const {
1855
0
  auto ins = std::make_unique<ParserBuilderImpl>(options_);
1856
0
  ins->library_ids_ = library_ids_;
1857
0
  ins->macros_ = macro_registry_.ListMacros();
1858
0
  return ins;
1859
0
}
1860
1861
}  // namespace
1862
1863
absl::StatusOr<ParsedExpr> Parse(absl::string_view expression,
1864
                                 absl::string_view description,
1865
21.5k
                                 const ParserOptions& options) {
1866
21.5k
  std::vector<Macro> macros;
1867
21.5k
  if (!options.disable_standard_macros) {
1868
21.5k
    macros = Macro::AllMacros();
1869
21.5k
  }
1870
21.5k
  if (options.enable_optional_syntax) {
1871
0
    macros.push_back(cel::OptMapMacro());
1872
0
    macros.push_back(cel::OptFlatMapMacro());
1873
0
  }
1874
21.5k
  return ParseWithMacros(expression, macros, description, options);
1875
21.5k
}
1876
1877
absl::StatusOr<ParsedExpr> ParseWithMacros(absl::string_view expression,
1878
                                           const std::vector<Macro>& macros,
1879
                                           absl::string_view description,
1880
21.5k
                                           const ParserOptions& options) {
1881
21.5k
  CEL_ASSIGN_OR_RETURN(auto verbose_parsed_expr,
1882
12.1k
                       EnrichedParse(expression, macros, description, options));
1883
12.1k
  return verbose_parsed_expr.parsed_expr();
1884
21.5k
}
1885
1886
absl::StatusOr<VerboseParsedExpr> EnrichedParse(
1887
    absl::string_view expression, const std::vector<Macro>& macros,
1888
21.5k
    absl::string_view description, const ParserOptions& options) {
1889
21.5k
  CEL_ASSIGN_OR_RETURN(auto source,
1890
21.4k
                       cel::NewSource(expression, std::string(description)));
1891
21.4k
  cel::MacroRegistry macro_registry;
1892
21.4k
  CEL_RETURN_IF_ERROR(macro_registry.RegisterMacros(macros));
1893
21.4k
  return EnrichedParse(*source, macro_registry, options);
1894
21.4k
}
1895
1896
absl::StatusOr<VerboseParsedExpr> EnrichedParse(
1897
    const cel::Source& source, const cel::MacroRegistry& registry,
1898
21.4k
    const ParserOptions& options) {
1899
21.4k
  CEL_ASSIGN_OR_RETURN(ParseResult parse_result,
1900
12.1k
                       ParseImpl(source, registry, options));
1901
12.1k
  ParsedExpr parsed_expr;
1902
12.1k
  CEL_RETURN_IF_ERROR(cel::ast_internal::ExprToProto(
1903
12.1k
      parse_result.expr, parsed_expr.mutable_expr()));
1904
1905
12.1k
  CEL_RETURN_IF_ERROR(cel::ast_internal::SourceInfoToProto(
1906
12.1k
      parse_result.source_info, parsed_expr.mutable_source_info()));
1907
12.1k
  return VerboseParsedExpr(std::move(parsed_expr),
1908
12.1k
                           std::move(parse_result.enriched_source_info));
1909
12.1k
}
1910
1911
absl::StatusOr<cel::expr::ParsedExpr> Parse(
1912
    const cel::Source& source, const cel::MacroRegistry& registry,
1913
0
    const ParserOptions& options) {
1914
0
  CEL_ASSIGN_OR_RETURN(auto verbose_expr,
1915
0
                       EnrichedParse(source, registry, options));
1916
0
  return verbose_expr.parsed_expr();
1917
0
}
1918
1919
}  // namespace google::api::expr::parser
1920
1921
namespace cel {
1922
1923
// Creates a new parser builder.
1924
//
1925
// Intended for use with the Compiler class, most users should prefer the free
1926
// functions above for independent parsing of expressions.
1927
0
std::unique_ptr<ParserBuilder> NewParserBuilder(const ParserOptions& options) {
1928
0
  return std::make_unique<google::api::expr::parser::ParserBuilderImpl>(
1929
0
      options);
1930
0
}
1931
1932
}  // namespace cel