Coverage Report

Created: 2026-07-11 06:47

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.82M
std::any ExprPtrToAny(std::unique_ptr<Expr>&& expr) {
93
6.82M
  return std::make_any<Expr*>(expr.release());
94
6.82M
}
95
96
6.82M
std::any ExprToAny(Expr&& expr) {
97
6.82M
  return ExprPtrToAny(std::make_unique<Expr>(std::move(expr)));
98
6.82M
}
99
100
6.82M
std::unique_ptr<Expr> ExprPtrFromAny(std::any&& any) {
101
6.82M
  return absl::WrapUnique(std::any_cast<Expr*>(std::move(any)));
102
6.82M
}
103
104
6.82M
Expr ExprFromAny(std::any&& any) {
105
6.82M
  auto expr = ExprPtrFromAny(std::move(any));
106
6.82M
  return std::move(*expr);
107
6.82M
}
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
135k
                               absl::string_view message) {
117
135k
  return absl::StrCat(absl::StrFormat("ERROR: %s:%zu:%zu: %s",
118
135k
                                      source.description(), location.line,
119
                                      // add one to the 0-based column
120
135k
                                      location.column + 1, message),
121
135k
                      source.DisplayErrorLocation(location));
122
135k
}
123
124
1.49M
int32_t PositiveOrMax(int32_t value) {
125
1.49M
  return value >= 0 ? value : std::numeric_limits<int32_t>::max();
126
1.49M
}
127
128
6.09M
SourceRange SourceRangeFromToken(const antlr4::Token* token) {
129
6.09M
  SourceRange range;
130
6.09M
  if (token != nullptr) {
131
6.09M
    if (auto start = token->getStartIndex(); start != INVALID_INDEX) {
132
6.09M
      range.begin = static_cast<int32_t>(start);
133
6.09M
    }
134
6.09M
    if (auto end = token->getStopIndex(); end != INVALID_INDEX) {
135
6.09M
      range.end = static_cast<int32_t>(end + 1);
136
6.09M
    }
137
6.09M
  }
138
6.09M
  return range;
139
6.09M
}
140
141
SourceRange SourceRangeFromParserRuleContext(
142
1.05M
    const antlr4::ParserRuleContext* context) {
143
1.05M
  SourceRange range;
144
1.05M
  if (context != nullptr) {
145
1.05M
    if (auto start = context->getStart() != nullptr
146
1.05M
                         ? context->getStart()->getStartIndex()
147
1.05M
                         : INVALID_INDEX;
148
1.05M
        start != INVALID_INDEX) {
149
1.05M
      range.begin = static_cast<int32_t>(start);
150
1.05M
    }
151
1.05M
    if (auto end = context->getStop() != nullptr
152
1.05M
                       ? context->getStop()->getStopIndex()
153
1.05M
                       : INVALID_INDEX;
154
1.05M
        end != INVALID_INDEX) {
155
1.05M
      range.end = static_cast<int32_t>(end + 1);
156
1.05M
    }
157
1.05M
  }
158
1.05M
  return range;
159
1.05M
}
160
161
}  // namespace
162
163
class ParserMacroExprFactory final : public MacroExprFactory {
164
 public:
165
  explicit ParserMacroExprFactory(const cel::Source& source)
166
7.15k
      : source_(source) {}
167
168
43.7k
  void BeginMacro(SourceRange macro_position) {
169
43.7k
    macro_position_ = macro_position;
170
43.7k
  }
171
172
43.7k
  void EndMacro() { macro_position_ = SourceRange{}; }
173
174
3.30k
  Expr ReportError(absl::string_view message) override {
175
3.30k
    return ReportError(macro_position_, message);
176
3.30k
  }
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.17M
  Expr ReportError(SourceRange range, absl::string_view message) {
183
8.17M
    ++error_count_;
184
8.17M
    if (errors_.size() <= 100) {
185
134k
      errors_.push_back(ParserError{std::string(message), range});
186
134k
    }
187
8.17M
    return NewUnspecified(NextId(range));
188
8.17M
  }
189
190
12.4k
  Expr ReportErrorAt(const Expr& expr, absl::string_view message) override {
191
12.4k
    return ReportError(GetSourceRange(expr.id()), message);
192
12.4k
  }
193
194
56.1k
  SourceRange GetSourceRange(int64_t id) const {
195
56.1k
    if (auto it = positions_.find(id); it != positions_.end()) {
196
55.3k
      return it->second;
197
55.3k
    }
198
758
    return SourceRange{};
199
56.1k
  }
200
201
15.6M
  int64_t NextId(const SourceRange& range) {
202
15.6M
    auto id = expr_id_++;
203
15.6M
    if (range.begin != -1 || range.end != -1) {
204
15.6M
      positions_.insert(std::pair{id, range});
205
15.6M
    }
206
15.6M
    return id;
207
15.6M
  }
208
209
8.04k
  bool HasErrors() const { return error_count_ != 0; }
210
211
5.46k
  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
5.46k
    std::stable_sort(
217
5.46k
        errors_.begin(), errors_.end(),
218
373k
        [](const ParserError& lhs, const ParserError& rhs) -> bool {
219
373k
          auto lhs_begin = PositiveOrMax(lhs.range.begin);
220
373k
          auto lhs_end = PositiveOrMax(lhs.range.end);
221
373k
          auto rhs_begin = PositiveOrMax(rhs.range.begin);
222
373k
          auto rhs_end = PositiveOrMax(rhs.range.end);
223
373k
          return lhs_begin < rhs_begin ||
224
343k
                 (lhs_begin == rhs_begin && lhs_end < rhs_end);
225
373k
        });
226
    // Build the summary error message using the sorted errors.
227
5.46k
    bool errors_truncated = error_count_ > 100;
228
5.46k
    std::vector<cel::ParseIssue> issues;
229
5.46k
    issues.reserve(
230
5.46k
        errors_.size() +
231
5.46k
        errors_truncated);  // Reserve space for the transform and an
232
                            // additional element when truncation occurs.
233
5.46k
    std::transform(
234
5.46k
        errors_.begin(), errors_.end(), std::back_inserter(issues),
235
134k
        [this](const ParserError& error) {
236
134k
          auto location =
237
134k
              source_.GetLocation(error.range.begin).value_or(SourceLocation{});
238
134k
          return cel::ParseIssue(location, error.message);
239
134k
        });
240
5.46k
    if (errors_truncated) {
241
605
      issues.push_back(cel::ParseIssue(
242
605
          absl::StrCat(error_count_ - 100, " more errors were truncated.")));
243
605
    }
244
5.46k
    return issues;
245
5.46k
  }
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
3.35k
  const absl::btree_map<int64_t, SourceRange>& positions() const {
371
3.35k
    return positions_;
372
3.35k
  }
373
374
0
  const absl::flat_hash_map<int64_t, Expr>& macro_calls() const {
375
0
    return macro_calls_;
376
0
  }
377
378
1.67k
  absl::flat_hash_map<int64_t, Expr> release_macro_calls() {
379
1.67k
    using std::swap;
380
1.67k
    absl::flat_hash_map<int64_t, Expr> result;
381
1.67k
    swap(result, macro_calls_);
382
1.67k
    return result;
383
1.67k
  }
384
385
43.7k
  void EraseId(ExprId id) {
386
43.7k
    positions_.erase(id);
387
43.7k
    if (expr_id_ == id + 1) {
388
0
      --expr_id_;
389
0
    }
390
43.7k
  }
391
392
 protected:
393
324k
  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
7.15k
      : buffer_(buffer),
451
7.15k
        source_name_(source_name),
452
7.15k
        size_(buffer_.size()),
453
7.15k
        index_(0) {}
454
455
194M
  void consume() override {
456
194M
    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
194M
    index_++;
461
194M
  }
462
463
424M
  size_t LA(ptrdiff_t i) override {
464
424M
    if (ABSL_PREDICT_FALSE(i == 0)) {
465
0
      return 0;
466
0
    }
467
424M
    auto p = static_cast<ptrdiff_t>(index_);
468
424M
    if (i < 0) {
469
0
      i++;
470
0
      if (p + i - 1 < 0) {
471
0
        return IntStream::EOF;
472
0
      }
473
0
    }
474
424M
    if (p + i - 1 >= static_cast<ptrdiff_t>(size_)) {
475
15.3k
      return IntStream::EOF;
476
15.3k
    }
477
424M
    return buffer_.at(static_cast<size_t>(p + i - 1));
478
424M
  }
479
480
27.5M
  ptrdiff_t mark() override { return -1; }
481
482
27.5M
  void release(ptrdiff_t marker) override {}
483
484
178M
  size_t index() override { return index_; }
485
486
9.74M
  void seek(size_t index) override { index_ = std::min(index, size_); }
487
488
9.59M
  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
17.6M
  std::string getText(const antlr4::misc::Interval& interval) override {
496
17.6M
    if (ABSL_PREDICT_FALSE(interval.a < 0 || interval.b < 0)) {
497
0
      return std::string();
498
0
    }
499
17.6M
    size_t start = static_cast<size_t>(interval.a);
500
17.6M
    if (ABSL_PREDICT_FALSE(start >= size_)) {
501
0
      return std::string();
502
0
    }
503
17.6M
    size_t stop = static_cast<size_t>(interval.b);
504
17.6M
    if (ABSL_PREDICT_FALSE(stop >= size_)) {
505
556
      stop = size_ - 1;
506
556
    }
507
17.6M
    return buffer_.ToString(static_cast<cel::SourcePosition>(start),
508
17.6M
                            static_cast<cel::SourcePosition>(stop) + 1);
509
17.6M
  }
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
6.43M
      : recursion_depth_(recursion_depth) {
526
6.43M
    ++recursion_depth_;
527
6.43M
  }
528
529
6.43M
  ~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(bool enable_variadic = false);
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
2.94k
    : factory_(factory), function_(std::move(function)) {
572
2.94k
  terms_.push_back(std::move(expr));
573
2.94k
}
574
575
406k
void ExpressionBalancer::AddTerm(int64_t op, Expr term) {
576
406k
  terms_.push_back(std::move(term));
577
406k
  ops_.push_back(op);
578
406k
}
579
580
2.94k
Expr ExpressionBalancer::Balance(bool enable_variadic) {
581
2.94k
  if (terms_.size() == 1) {
582
0
    return std::move(terms_[0]);
583
0
  }
584
2.94k
  if (enable_variadic) {
585
0
    return factory_.NewCall(ops_[0], function_, std::move(terms_));
586
0
  }
587
2.94k
  return BalancedTree(0, ops_.size() - 1);
588
2.94k
}
589
590
406k
Expr ExpressionBalancer::BalancedTree(int lo, int hi) {
591
406k
  int mid = (lo + hi + 1) / 2;
592
593
406k
  std::vector<Expr> arguments;
594
406k
  arguments.reserve(2);
595
596
406k
  if (mid == lo) {
597
168k
    arguments.push_back(std::move(terms_[mid]));
598
238k
  } else {
599
238k
    arguments.push_back(BalancedTree(lo, mid - 1));
600
238k
  }
601
602
406k
  if (mid == hi) {
603
240k
    arguments.push_back(std::move(terms_[mid + 1]));
604
240k
  } else {
605
165k
    arguments.push_back(BalancedTree(mid + 1, hi));
606
165k
  }
607
406k
  return factory_.NewCall(ops_[mid], function_, std::move(arguments));
608
406k
}
609
610
std::string FormatIssues(const cel::Source& source,
611
5.46k
                         absl::Span<const cel::ParseIssue> issues) {
612
5.46k
  return absl::StrJoin(
613
135k
      issues, "\n", [&source](std::string* out, const cel::ParseIssue& issue) {
614
135k
        absl::StrAppend(out, cel::DisplayParserError(source, issue.location(),
615
135k
                                                     issue.message()));
616
135k
      });
617
5.46k
}
618
619
class ParserVisitor final : public CelBaseVisitor,
620
                            public antlr4::BaseErrorListener {
621
 public:
622
  ParserVisitor(const cel::Source& source, int max_recursion_depth,
623
                const cel::MacroRegistry& macro_registry,
624
                bool add_macro_calls = false,
625
                bool enable_optional_syntax = false,
626
                bool enable_quoted_identifiers = false,
627
                bool enable_variadic_logical_operators = false)
628
7.15k
      : source_(source),
629
7.15k
        factory_(source_),
630
7.15k
        macro_registry_(macro_registry),
631
7.15k
        recursion_depth_(0),
632
7.15k
        max_recursion_depth_(max_recursion_depth),
633
7.15k
        add_macro_calls_(add_macro_calls),
634
7.15k
        enable_optional_syntax_(enable_optional_syntax),
635
7.15k
        enable_quoted_identifiers_(enable_quoted_identifiers),
636
7.15k
        enable_variadic_logical_operators_(enable_variadic_logical_operators) {}
637
638
7.15k
  ~ParserVisitor() override = default;
639
640
  std::any visit(antlr4::tree::ParseTree* tree) override;
641
642
  std::any visitStart(CelParser::StartContext* ctx) override;
643
  std::any visitExpr(CelParser::ExprContext* ctx) override;
644
  std::any visitConditionalOr(CelParser::ConditionalOrContext* ctx) override;
645
  std::any visitConditionalAnd(CelParser::ConditionalAndContext* ctx) override;
646
  std::any visitRelation(CelParser::RelationContext* ctx) override;
647
  std::any visitCalc(CelParser::CalcContext* ctx) override;
648
  std::any visitUnary(CelParser::UnaryContext* ctx);
649
  std::any visitLogicalNot(CelParser::LogicalNotContext* ctx) override;
650
  std::any visitNegate(CelParser::NegateContext* ctx) override;
651
  std::any visitSelect(CelParser::SelectContext* ctx) override;
652
  std::any visitMemberCall(CelParser::MemberCallContext* ctx) override;
653
  std::any visitIndex(CelParser::IndexContext* ctx) override;
654
  std::any visitCreateMessage(CelParser::CreateMessageContext* ctx) override;
655
  std::any visitFieldInitializerList(
656
      CelParser::FieldInitializerListContext* ctx) override;
657
  std::vector<StructExprField> visitFields(
658
      CelParser::FieldInitializerListContext* ctx);
659
  std::any visitGlobalCall(CelParser::GlobalCallContext* ctx) override;
660
  std::any visitIdent(CelParser::IdentContext* ctx) override;
661
  std::any visitNested(CelParser::NestedContext* ctx) override;
662
  std::any visitCreateList(CelParser::CreateListContext* ctx) override;
663
  std::vector<ListExprElement> visitList(CelParser::ListInitContext* ctx);
664
  std::vector<Expr> visitList(CelParser::ExprListContext* ctx);
665
  std::any visitCreateMap(CelParser::CreateMapContext* ctx) override;
666
  std::any visitConstantLiteral(
667
      CelParser::ConstantLiteralContext* ctx) override;
668
  std::any visitPrimaryExpr(CelParser::PrimaryExprContext* ctx) override;
669
  std::any visitMemberExpr(CelParser::MemberExprContext* ctx) override;
670
671
  std::any visitMapInitializerList(
672
      CelParser::MapInitializerListContext* ctx) override;
673
  std::vector<MapExprEntry> visitEntries(
674
      CelParser::MapInitializerListContext* ctx);
675
  std::any visitInt(CelParser::IntContext* ctx) override;
676
  std::any visitUint(CelParser::UintContext* ctx) override;
677
  std::any visitDouble(CelParser::DoubleContext* ctx) override;
678
  std::any visitString(CelParser::StringContext* ctx) override;
679
  std::any visitBytes(CelParser::BytesContext* ctx) override;
680
  std::any visitBoolTrue(CelParser::BoolTrueContext* ctx) override;
681
  std::any visitBoolFalse(CelParser::BoolFalseContext* ctx) override;
682
  std::any visitNull(CelParser::NullContext* ctx) override;
683
  // Note: this is destructive and intended to be called after the parse is
684
  // finished.
685
  cel::SourceInfo GetSourceInfo();
686
  EnrichedSourceInfo enriched_source_info() const;
687
  void syntaxError(antlr4::Recognizer* recognizer,
688
                   antlr4::Token* offending_symbol, size_t line, size_t col,
689
                   const std::string& msg, std::exception_ptr e) override;
690
  bool HasErrored() const;
691
692
  std::vector<cel::ParseIssue> CollectIssues();
693
694
 private:
695
  template <typename... Args>
696
  Expr GlobalCallOrMacro(int64_t expr_id, absl::string_view function,
697
2.57M
                         Args&&... args) {
698
2.57M
    std::vector<Expr> arguments;
699
2.57M
    arguments.reserve(sizeof...(Args));
700
2.57M
    (arguments.push_back(std::forward<Args>(args)), ...);
701
2.57M
    return GlobalCallOrMacroImpl(expr_id, function, std::move(arguments));
702
2.57M
  }
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
697
2.31M
                         Args&&... args) {
698
2.31M
    std::vector<Expr> arguments;
699
2.31M
    arguments.reserve(sizeof...(Args));
700
2.31M
    (arguments.push_back(std::forward<Args>(args)), ...);
701
2.31M
    return GlobalCallOrMacroImpl(expr_id, function, std::move(arguments));
702
2.31M
  }
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
697
261k
                         Args&&... args) {
698
261k
    std::vector<Expr> arguments;
699
261k
    arguments.reserve(sizeof...(Args));
700
261k
    (arguments.push_back(std::forward<Args>(args)), ...);
701
261k
    return GlobalCallOrMacroImpl(expr_id, function, std::move(arguments));
702
261k
  }
703
704
  Expr GlobalCallOrMacroImpl(int64_t expr_id, absl::string_view function,
705
                             std::vector<Expr> args);
706
  Expr ReceiverCallOrMacroImpl(int64_t expr_id, absl::string_view function,
707
                               Expr target, std::vector<Expr> args);
708
  std::string ExtractQualifiedName(antlr4::ParserRuleContext* ctx,
709
                                   const Expr& e);
710
711
  std::string NormalizeIdentifier(CelParser::EscapeIdentContext* ctx);
712
  // Attempt to unnest parse context.
713
  //
714
  // Walk the parse tree to the first complex term to reduce recursive depth in
715
  // the visit* calls.
716
  antlr4::tree::ParseTree* UnnestContext(antlr4::tree::ParseTree* tree);
717
718
 private:
719
  const cel::Source& source_;
720
  cel::ParserMacroExprFactory factory_;
721
  const cel::MacroRegistry& macro_registry_;
722
  int recursion_depth_;
723
  const int max_recursion_depth_;
724
  const bool add_macro_calls_;
725
  const bool enable_optional_syntax_;
726
  const bool enable_quoted_identifiers_;
727
  const bool enable_variadic_logical_operators_;
728
};
729
730
template <typename T, typename = std::enable_if_t<
731
                          std::is_base_of<antlr4::tree::ParseTree, T>::value>>
732
116M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
116M
  return dynamic_cast<T*>(tree);
734
116M
}
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
732
8.53M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
8.53M
  return dynamic_cast<T*>(tree);
734
8.53M
}
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
732
349k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
349k
  return dynamic_cast<T*>(tree);
734
349k
}
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
732
319k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
319k
  return dynamic_cast<T*>(tree);
734
319k
}
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
732
7.27k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
7.27k
  return dynamic_cast<T*>(tree);
734
7.27k
}
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
732
39.7k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
39.7k
  return dynamic_cast<T*>(tree);
734
39.7k
}
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
732
1.21k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
1.21k
  return dynamic_cast<T*>(tree);
734
1.21k
}
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
732
7.52M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
7.52M
  return dynamic_cast<T*>(tree);
734
7.52M
}
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
732
3.76M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
3.76M
  return dynamic_cast<T*>(tree);
734
3.76M
}
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
732
1.08M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
1.08M
  return dynamic_cast<T*>(tree);
734
1.08M
}
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
732
1.04M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
1.04M
  return dynamic_cast<T*>(tree);
734
1.04M
}
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
732
1.03M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
1.03M
  return dynamic_cast<T*>(tree);
734
1.03M
}
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
732
1.02M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
1.02M
  return dynamic_cast<T*>(tree);
734
1.02M
}
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
732
1.02M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
1.02M
  return dynamic_cast<T*>(tree);
734
1.02M
}
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
732
1.02M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
1.02M
  return dynamic_cast<T*>(tree);
734
1.02M
}
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
732
414k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
414k
  return dynamic_cast<T*>(tree);
734
414k
}
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
732
405k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
405k
  return dynamic_cast<T*>(tree);
734
405k
}
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
732
329k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
329k
  return dynamic_cast<T*>(tree);
734
329k
}
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
732
11.4k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
11.4k
  return dynamic_cast<T*>(tree);
734
11.4k
}
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
732
5.56k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
5.56k
  return dynamic_cast<T*>(tree);
734
5.56k
}
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
732
4.77k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
4.77k
  return dynamic_cast<T*>(tree);
734
4.77k
}
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
732
4.13k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
4.13k
  return dynamic_cast<T*>(tree);
734
4.13k
}
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
732
13.1M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
13.1M
  return dynamic_cast<T*>(tree);
734
13.1M
}
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
732
13.1M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
13.1M
  return dynamic_cast<T*>(tree);
734
13.1M
}
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
732
13.1M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
13.1M
  return dynamic_cast<T*>(tree);
734
13.1M
}
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
732
13.1M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
13.1M
  return dynamic_cast<T*>(tree);
734
13.1M
}
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
732
13.1M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
13.1M
  return dynamic_cast<T*>(tree);
734
13.1M
}
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
732
13.1M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
13.1M
  return dynamic_cast<T*>(tree);
734
13.1M
}
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
732
4.11M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
4.11M
  return dynamic_cast<T*>(tree);
734
4.11M
}
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
732
4.77M
T* tree_as(antlr4::tree::ParseTree* tree) {
733
4.77M
  return dynamic_cast<T*>(tree);
734
4.77M
}
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
732
270k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
270k
  return dynamic_cast<T*>(tree);
734
270k
}
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
732
270k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
270k
  return dynamic_cast<T*>(tree);
734
270k
}
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
732
3.71k
T* tree_as(antlr4::tree::ParseTree* tree) {
733
3.71k
  return dynamic_cast<T*>(tree);
734
3.71k
}
Unexecuted instantiation: parser.cc:antlr4::ParserRuleContext* google::api::expr::parser::(anonymous namespace)::tree_as<antlr4::ParserRuleContext, void>(antlr4::tree::ParseTree*)
735
736
6.43M
std::any ParserVisitor::visit(antlr4::tree::ParseTree* tree) {
737
6.43M
  ScopedIncrement inc(recursion_depth_);
738
6.43M
  if (recursion_depth_ > max_recursion_depth_) {
739
2.50k
    return ExprToAny(factory_.ReportError(
740
2.50k
        absl::StrFormat("Exceeded max recursion depth of %d when parsing.",
741
2.50k
                        max_recursion_depth_)));
742
2.50k
  }
743
6.42M
  tree = UnnestContext(tree);
744
6.42M
  if (auto* ctx = tree_as<CelParser::StartContext>(tree)) {
745
0
    return visitStart(ctx);
746
6.42M
  } else if (auto* ctx = tree_as<CelParser::ExprContext>(tree)) {
747
1.35k
    return visitExpr(ctx);
748
6.42M
  } else if (auto* ctx = tree_as<CelParser::ConditionalAndContext>(tree)) {
749
863
    return visitConditionalAnd(ctx);
750
6.42M
  } else if (auto* ctx = tree_as<CelParser::ConditionalOrContext>(tree)) {
751
2.07k
    return visitConditionalOr(ctx);
752
6.42M
  } else if (auto* ctx = tree_as<CelParser::RelationContext>(tree)) {
753
6.12k
    return visitRelation(ctx);
754
6.41M
  } else if (auto* ctx = tree_as<CelParser::CalcContext>(tree)) {
755
2.30M
    return visitCalc(ctx);
756
4.11M
  } else if (auto* ctx = tree_as<CelParser::LogicalNotContext>(tree)) {
757
3.14k
    return visitLogicalNot(ctx);
758
4.11M
  } else if (auto* ctx = tree_as<CelParser::PrimaryExprContext>(tree)) {
759
3.76M
    return visitPrimaryExpr(ctx);
760
3.76M
  } else if (auto* ctx = tree_as<CelParser::MemberExprContext>(tree)) {
761
0
    return visitMemberExpr(ctx);
762
349k
  } else if (auto* ctx = tree_as<CelParser::SelectContext>(tree)) {
763
29.6k
    return visitSelect(ctx);
764
319k
  } else if (auto* ctx = tree_as<CelParser::MemberCallContext>(tree)) {
765
49.1k
    return visitMemberCall(ctx);
766
270k
  } else if (auto* ctx = tree_as<CelParser::MapInitializerListContext>(tree)) {
767
0
    return visitMapInitializerList(ctx);
768
270k
  } else if (auto* ctx = tree_as<CelParser::NegateContext>(tree)) {
769
263k
    return visitNegate(ctx);
770
263k
  } else if (auto* ctx = tree_as<CelParser::IndexContext>(tree)) {
771
3.55k
    return visitIndex(ctx);
772
3.71k
  } else if (auto* ctx = tree_as<CelParser::UnaryContext>(tree)) {
773
2.91k
    return visitUnary(ctx);
774
2.91k
  } else if (auto* ctx = tree_as<CelParser::CreateListContext>(tree)) {
775
0
    return visitCreateList(ctx);
776
803
  } else if (auto* ctx = tree_as<CelParser::CreateMessageContext>(tree)) {
777
0
    return visitCreateMessage(ctx);
778
803
  } else if (auto* ctx = tree_as<CelParser::CreateMapContext>(tree)) {
779
0
    return visitCreateMap(ctx);
780
0
  }
781
782
803
  if (tree) {
783
0
    return ExprToAny(
784
0
        factory_.ReportError(SourceRangeFromParserRuleContext(
785
0
                                 tree_as<antlr4::ParserRuleContext>(tree)),
786
0
                             "unknown parsetree type"));
787
0
  }
788
803
  return ExprToAny(factory_.ReportError("<<nil>> parsetree"));
789
803
}
790
791
3.76M
std::any ParserVisitor::visitPrimaryExpr(CelParser::PrimaryExprContext* pctx) {
792
3.76M
  CelParser::PrimaryContext* primary = pctx->primary();
793
3.76M
  if (auto* ctx = tree_as<CelParser::NestedContext>(primary)) {
794
0
    return visitNested(ctx);
795
3.76M
  } else if (auto* ctx = tree_as<CelParser::IdentContext>(primary)) {
796
2.67M
    return visitIdent(ctx);
797
2.67M
  } else if (auto* ctx = tree_as<CelParser::GlobalCallContext>(primary)) {
798
36.6k
    return visitGlobalCall(ctx);
799
1.04M
  } else if (auto* ctx = tree_as<CelParser::CreateListContext>(primary)) {
800
13.6k
    return visitCreateList(ctx);
801
1.03M
  } else if (auto* ctx = tree_as<CelParser::CreateMapContext>(primary)) {
802
6.22k
    return visitCreateMap(ctx);
803
1.02M
  } else if (auto* ctx = tree_as<CelParser::CreateMessageContext>(primary)) {
804
5.12k
    return visitCreateMessage(ctx);
805
1.02M
  } else if (auto* ctx = tree_as<CelParser::ConstantLiteralContext>(primary)) {
806
1.02M
    return visitConstantLiteral(ctx);
807
1.02M
  }
808
893
  if (factory_.HasErrors()) {
809
    // ANTLR creates PrimaryContext rather than a derived class during certain
810
    // error conditions. This is odd, but we ignore it as we already have errors
811
    // that occurred.
812
893
    return ExprToAny(factory_.NewUnspecified(factory_.NextId({})));
813
893
  }
814
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(pctx),
815
0
                                        "invalid primary expression"));
816
893
}
817
818
0
std::any ParserVisitor::visitMemberExpr(CelParser::MemberExprContext* mctx) {
819
0
  CelParser::MemberContext* member = mctx->member();
820
0
  if (auto* ctx = tree_as<CelParser::PrimaryExprContext>(member)) {
821
0
    return visitPrimaryExpr(ctx);
822
0
  } else if (auto* ctx = tree_as<CelParser::SelectContext>(member)) {
823
0
    return visitSelect(ctx);
824
0
  } else if (auto* ctx = tree_as<CelParser::MemberCallContext>(member)) {
825
0
    return visitMemberCall(ctx);
826
0
  } else if (auto* ctx = tree_as<CelParser::IndexContext>(member)) {
827
0
    return visitIndex(ctx);
828
0
  }
829
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(mctx),
830
0
                                        "unsupported simple expression"));
831
0
}
832
833
0
std::any ParserVisitor::visitStart(CelParser::StartContext* ctx) {
834
0
  return visit(ctx->expr());
835
0
}
836
837
antlr4::tree::ParseTree* ParserVisitor::UnnestContext(
838
6.42M
    antlr4::tree::ParseTree* tree) {
839
6.42M
  antlr4::tree::ParseTree* last = nullptr;
840
7.09M
  while (tree != last) {
841
6.73M
    last = tree;
842
843
6.73M
    if (auto* ctx = tree_as<CelParser::StartContext>(tree)) {
844
6.53k
      tree = ctx->expr();
845
6.53k
    }
846
847
6.73M
    if (auto* ctx = tree_as<CelParser::ExprContext>(tree)) {
848
653k
      if (ctx->op != nullptr) {
849
1.35k
        return ctx;
850
1.35k
      }
851
651k
      tree = ctx->e;
852
651k
    }
853
854
6.73M
    if (auto* ctx = tree_as<CelParser::ConditionalOrContext>(tree)) {
855
1.04M
      if (!ctx->ops.empty()) {
856
2.07k
        return ctx;
857
2.07k
      }
858
1.04M
      tree = ctx->e;
859
1.04M
    }
860
861
6.73M
    if (auto* ctx = tree_as<CelParser::ConditionalAndContext>(tree)) {
862
1.11M
      if (!ctx->ops.empty()) {
863
863
        return ctx;
864
863
      }
865
1.11M
      tree = ctx->e;
866
1.11M
    }
867
868
6.73M
    if (auto* ctx = tree_as<CelParser::RelationContext>(tree)) {
869
1.46M
      if (ctx->calc() == nullptr) {
870
6.12k
        return ctx;
871
6.12k
      }
872
1.46M
      tree = ctx->calc();
873
1.46M
    }
874
875
6.72M
    if (auto* ctx = tree_as<CelParser::CalcContext>(tree)) {
876
6.07M
      if (ctx->unary() == nullptr) {
877
2.30M
        return ctx;
878
2.30M
      }
879
3.76M
      tree = ctx->unary();
880
3.76M
    }
881
882
4.42M
    if (auto* ctx = tree_as<CelParser::MemberExprContext>(tree)) {
883
3.49M
      tree = ctx->member();
884
3.49M
    }
885
886
4.42M
    if (auto* ctx = tree_as<CelParser::PrimaryExprContext>(tree)) {
887
3.76M
      if (auto* nested = tree_as<CelParser::NestedContext>(ctx->primary())) {
888
1.29k
        tree = nested->e;
889
3.76M
      } else {
890
3.76M
        return ctx;
891
3.76M
      }
892
3.76M
    }
893
4.42M
  }
894
895
352k
  return tree;
896
6.42M
}
897
898
396k
std::any ParserVisitor::visitExpr(CelParser::ExprContext* ctx) {
899
396k
  auto result = ExprFromAny(visit(ctx->e));
900
396k
  if (!ctx->op) {
901
395k
    return ExprToAny(std::move(result));
902
395k
  }
903
1.52k
  std::vector<Expr> arguments;
904
1.52k
  arguments.reserve(3);
905
1.52k
  arguments.push_back(std::move(result));
906
1.52k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
907
1.52k
  arguments.push_back(ExprFromAny(visit(ctx->e1)));
908
1.52k
  arguments.push_back(ExprFromAny(visit(ctx->e2)));
909
910
1.52k
  return ExprToAny(
911
1.52k
      factory_.NewCall(op_id, CelOperator::CONDITIONAL, std::move(arguments)));
912
396k
}
913
914
std::any ParserVisitor::visitConditionalOr(
915
2.07k
    CelParser::ConditionalOrContext* ctx) {
916
2.07k
  auto result = ExprFromAny(visit(ctx->e));
917
2.07k
  if (ctx->ops.empty()) {
918
0
    return ExprToAny(std::move(result));
919
0
  }
920
2.07k
  ExpressionBalancer b(factory_, CelOperator::LOGICAL_OR, std::move(result));
921
69.4k
  for (size_t i = 0; i < ctx->ops.size(); ++i) {
922
67.3k
    auto op = ctx->ops[i];
923
67.3k
    if (i >= ctx->e1.size()) {
924
0
      return ExprToAny(
925
0
          factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
926
0
                               "unexpected character, wanted '||'"));
927
0
    }
928
67.3k
    auto next = ExprFromAny(visit(ctx->e1[i]));
929
67.3k
    int64_t op_id = factory_.NextId(SourceRangeFromToken(op));
930
67.3k
    b.AddTerm(op_id, std::move(next));
931
67.3k
  }
932
2.07k
  return ExprToAny(b.Balance(enable_variadic_logical_operators_));
933
2.07k
}
934
935
std::any ParserVisitor::visitConditionalAnd(
936
863
    CelParser::ConditionalAndContext* ctx) {
937
863
  auto result = ExprFromAny(visit(ctx->e));
938
863
  if (ctx->ops.empty()) {
939
0
    return ExprToAny(std::move(result));
940
0
  }
941
863
  ExpressionBalancer b(factory_, CelOperator::LOGICAL_AND, std::move(result));
942
340k
  for (size_t i = 0; i < ctx->ops.size(); ++i) {
943
339k
    auto op = ctx->ops[i];
944
339k
    if (i >= ctx->e1.size()) {
945
0
      return ExprToAny(
946
0
          factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
947
0
                               "unexpected character, wanted '&&'"));
948
0
    }
949
339k
    auto next = ExprFromAny(visit(ctx->e1[i]));
950
339k
    int64_t op_id = factory_.NextId(SourceRangeFromToken(op));
951
339k
    b.AddTerm(op_id, std::move(next));
952
339k
  }
953
863
  return ExprToAny(b.Balance(enable_variadic_logical_operators_));
954
863
}
955
956
6.12k
std::any ParserVisitor::visitRelation(CelParser::RelationContext* ctx) {
957
6.12k
  if (ctx->calc()) {
958
0
    return visit(ctx->calc());
959
0
  }
960
6.12k
  std::string op_text;
961
6.12k
  if (ctx->op) {
962
6.12k
    op_text = ctx->op->getText();
963
6.12k
  }
964
6.12k
  auto op = ReverseLookupOperator(op_text);
965
6.12k
  if (op) {
966
6.12k
    auto lhs = ExprFromAny(visit(ctx->relation(0)));
967
6.12k
    int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
968
6.12k
    auto rhs = ExprFromAny(visit(ctx->relation(1)));
969
6.12k
    return ExprToAny(
970
6.12k
        GlobalCallOrMacro(op_id, *op, std::move(lhs), std::move(rhs)));
971
6.12k
  }
972
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
973
0
                                        "operator not found"));
974
6.12k
}
975
976
2.30M
std::any ParserVisitor::visitCalc(CelParser::CalcContext* ctx) {
977
2.30M
  if (ctx->unary()) {
978
0
    return visit(ctx->unary());
979
0
  }
980
2.30M
  std::string op_text;
981
2.30M
  if (ctx->op) {
982
2.30M
    op_text = ctx->op->getText();
983
2.30M
  }
984
2.30M
  auto op = ReverseLookupOperator(op_text);
985
2.30M
  if (op) {
986
2.30M
    auto lhs = ExprFromAny(visit(ctx->calc(0)));
987
2.30M
    int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
988
2.30M
    auto rhs = ExprFromAny(visit(ctx->calc(1)));
989
2.30M
    return ExprToAny(
990
2.30M
        GlobalCallOrMacro(op_id, *op, std::move(lhs), std::move(rhs)));
991
2.30M
  }
992
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
993
0
                                        "operator not found"));
994
2.30M
}
995
996
2.91k
std::any ParserVisitor::visitUnary(CelParser::UnaryContext* ctx) {
997
2.91k
  return ExprToAny(factory_.NewStringConst(
998
2.91k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)), "<<error>>"));
999
2.91k
}
1000
1001
3.14k
std::any ParserVisitor::visitLogicalNot(CelParser::LogicalNotContext* ctx) {
1002
3.14k
  if (ctx->ops.size() % 2 == 0) {
1003
792
    return visit(ctx->member());
1004
792
  }
1005
2.34k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->ops[0]));
1006
2.34k
  auto target = ExprFromAny(visit(ctx->member()));
1007
2.34k
  return ExprToAny(
1008
2.34k
      GlobalCallOrMacro(op_id, CelOperator::LOGICAL_NOT, std::move(target)));
1009
3.14k
}
1010
1011
263k
std::any ParserVisitor::visitNegate(CelParser::NegateContext* ctx) {
1012
263k
  if (ctx->ops.size() % 2 == 0) {
1013
4.68k
    return visit(ctx->member());
1014
4.68k
  }
1015
258k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->ops[0]));
1016
258k
  auto target = ExprFromAny(visit(ctx->member()));
1017
258k
  return ExprToAny(
1018
258k
      GlobalCallOrMacro(op_id, CelOperator::NEGATE, std::move(target)));
1019
263k
}
1020
1021
std::string ParserVisitor::NormalizeIdentifier(
1022
39.7k
    CelParser::EscapeIdentContext* ctx) {
1023
39.7k
  if (auto* raw_id = tree_as<CelParser::SimpleIdentifierContext>(ctx); raw_id) {
1024
38.5k
    return raw_id->id->getText();
1025
38.5k
  }
1026
1.21k
  if (auto* escaped_id = tree_as<CelParser::EscapedIdentifierContext>(ctx);
1027
1.21k
      escaped_id) {
1028
870
    if (!enable_quoted_identifiers_) {
1029
0
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1030
0
                           "unsupported syntax '`'");
1031
0
    }
1032
870
    auto escaped_id_text = escaped_id->id->getText();
1033
870
    return escaped_id_text.substr(1, escaped_id_text.size() - 2);
1034
870
  }
1035
1036
  // Fallthrough might occur if the parser is in an error state.
1037
340
  return "";
1038
1.21k
}
1039
1040
29.6k
std::any ParserVisitor::visitSelect(CelParser::SelectContext* ctx) {
1041
29.6k
  auto operand = ExprFromAny(visit(ctx->member()));
1042
  // Handle the error case where no valid identifier is specified.
1043
29.6k
  if (!ctx->id || !ctx->op) {
1044
0
    return ExprToAny(factory_.NewUnspecified(
1045
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1046
0
  }
1047
29.6k
  auto id = NormalizeIdentifier(ctx->id);
1048
29.6k
  if (ctx->opt != nullptr) {
1049
3.56k
    if (!enable_optional_syntax_) {
1050
3.56k
      return ExprToAny(factory_.ReportError(
1051
3.56k
          SourceRangeFromParserRuleContext(ctx), "unsupported syntax '.?'"));
1052
3.56k
    }
1053
0
    auto op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1054
0
    std::vector<Expr> arguments;
1055
0
    arguments.reserve(2);
1056
0
    arguments.push_back(std::move(operand));
1057
0
    arguments.push_back(factory_.NewStringConst(
1058
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx)), std::move(id)));
1059
0
    return ExprToAny(factory_.NewCall(op_id, "_?._", std::move(arguments)));
1060
3.56k
  }
1061
26.1k
  return ExprToAny(
1062
26.1k
      factory_.NewSelect(factory_.NextId(SourceRangeFromToken(ctx->op)),
1063
26.1k
                         std::move(operand), std::move(id)));
1064
29.6k
}
1065
1066
49.1k
std::any ParserVisitor::visitMemberCall(CelParser::MemberCallContext* ctx) {
1067
49.1k
  auto operand = ExprFromAny(visit(ctx->member()));
1068
  // Handle the error case where no valid identifier is specified.
1069
49.1k
  if (!ctx->id) {
1070
0
    return ExprToAny(factory_.NewUnspecified(
1071
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1072
0
  }
1073
49.1k
  auto id = ctx->id->getText();
1074
49.1k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->open));
1075
49.1k
  auto args = visitList(ctx->args);
1076
49.1k
  return ExprToAny(
1077
49.1k
      ReceiverCallOrMacroImpl(op_id, id, std::move(operand), std::move(args)));
1078
49.1k
}
1079
1080
3.55k
std::any ParserVisitor::visitIndex(CelParser::IndexContext* ctx) {
1081
3.55k
  auto target = ExprFromAny(visit(ctx->member()));
1082
3.55k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1083
3.55k
  auto index = ExprFromAny(visit(ctx->index));
1084
3.55k
  if (!enable_optional_syntax_ && ctx->opt != nullptr) {
1085
1.10k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1086
1.10k
                                          "unsupported syntax '.?'"));
1087
1.10k
  }
1088
2.45k
  return ExprToAny(GlobalCallOrMacro(
1089
2.45k
      op_id, ctx->opt != nullptr ? "_[?_]" : CelOperator::INDEX,
1090
2.45k
      std::move(target), std::move(index)));
1091
3.55k
}
1092
1093
std::any ParserVisitor::visitCreateMessage(
1094
5.12k
    CelParser::CreateMessageContext* ctx) {
1095
5.12k
  std::vector<std::string> parts;
1096
5.12k
  parts.reserve(ctx->ids.size());
1097
78.7k
  for (const auto* id : ctx->ids) {
1098
78.7k
    parts.push_back(id->getText());
1099
78.7k
  }
1100
5.12k
  std::string name;
1101
5.12k
  if (ctx->leadingDot) {
1102
1.54k
    name.push_back('.');
1103
1.54k
    name.append(absl::StrJoin(parts, "."));
1104
3.57k
  } else {
1105
3.57k
    name = absl::StrJoin(parts, ".");
1106
3.57k
  }
1107
5.12k
  int64_t obj_id = factory_.NextId(SourceRangeFromParserRuleContext(ctx));
1108
5.12k
  std::vector<StructExprField> fields;
1109
5.12k
  if (ctx->entries) {
1110
717
    fields = visitFields(ctx->entries);
1111
717
  }
1112
5.12k
  return ExprToAny(
1113
5.12k
      factory_.NewStruct(obj_id, std::move(name), std::move(fields)));
1114
5.12k
}
1115
1116
std::any ParserVisitor::visitFieldInitializerList(
1117
0
    CelParser::FieldInitializerListContext* ctx) {
1118
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1119
0
                                        "<<unreachable>>"));
1120
0
}
1121
1122
std::vector<StructExprField> ParserVisitor::visitFields(
1123
717
    CelParser::FieldInitializerListContext* ctx) {
1124
717
  std::vector<StructExprField> res;
1125
717
  if (!ctx || ctx->fields.empty()) {
1126
0
    return res;
1127
0
  }
1128
1129
717
  res.reserve(ctx->fields.size());
1130
10.8k
  for (size_t i = 0; i < ctx->fields.size(); ++i) {
1131
10.1k
    if (i >= ctx->cols.size() || i >= ctx->values.size()) {
1132
      // This is the result of a syntax error detected elsewhere.
1133
87
      return res;
1134
87
    }
1135
10.0k
    auto* f = ctx->fields[i];
1136
10.0k
    if (!f->escapeIdent()) {
1137
0
      ABSL_DCHECK(HasErrored());
1138
      // This is the result of a syntax error detected elsewhere.
1139
0
      return res;
1140
0
    }
1141
1142
10.0k
    std::string id = NormalizeIdentifier(f->escapeIdent());
1143
1144
10.0k
    int64_t init_id = factory_.NextId(SourceRangeFromToken(ctx->cols[i]));
1145
10.0k
    if (!enable_optional_syntax_ && f->opt) {
1146
486
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1147
486
                           "unsupported syntax '?'");
1148
486
      continue;
1149
486
    }
1150
9.59k
    auto value = ExprFromAny(visit(ctx->values[i]));
1151
9.59k
    res.push_back(factory_.NewStructField(init_id, std::move(id),
1152
9.59k
                                          std::move(value), f->opt != nullptr));
1153
9.59k
  }
1154
1155
630
  return res;
1156
717
}
1157
1158
2.67M
std::any ParserVisitor::visitIdent(CelParser::IdentContext* ctx) {
1159
2.67M
  std::string ident_name;
1160
2.67M
  if (ctx->leadingDot) {
1161
7.65k
    ident_name = ".";
1162
7.65k
  }
1163
2.67M
  if (!ctx->id) {
1164
0
    return ExprToAny(factory_.NewUnspecified(
1165
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1166
0
  }
1167
  // check if ID is in reserved identifiers
1168
2.67M
  if (cel::internal::LexisIsReserved(ctx->id->getText())) {
1169
639
    return ExprToAny(factory_.ReportError(
1170
639
        SourceRangeFromParserRuleContext(ctx),
1171
639
        absl::StrFormat("reserved identifier: %s", ctx->id->getText())));
1172
639
  }
1173
1174
2.67M
  ident_name += ctx->id->getText();
1175
1176
2.67M
  return ExprToAny(factory_.NewIdent(
1177
2.67M
      factory_.NextId(SourceRangeFromToken(ctx->id)), std::move(ident_name)));
1178
2.67M
}
1179
1180
36.6k
std::any ParserVisitor::visitGlobalCall(CelParser::GlobalCallContext* ctx) {
1181
36.6k
  std::string ident_name;
1182
36.6k
  if (ctx->leadingDot) {
1183
1.45k
    ident_name = ".";
1184
1.45k
  }
1185
36.6k
  if (!ctx->id || !ctx->op) {
1186
0
    return ExprToAny(factory_.NewUnspecified(
1187
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1188
0
  }
1189
  // check if ID is in reserved identifiers
1190
36.6k
  if (cel::internal::LexisIsReserved(ctx->id->getText())) {
1191
82
    return ExprToAny(factory_.ReportError(
1192
82
        SourceRangeFromParserRuleContext(ctx),
1193
82
        absl::StrFormat("reserved identifier: %s", ctx->id->getText())));
1194
82
  }
1195
1196
36.6k
  ident_name += ctx->id->getText();
1197
1198
36.6k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1199
36.6k
  auto args = visitList(ctx->args);
1200
36.6k
  return ExprToAny(
1201
36.6k
      GlobalCallOrMacroImpl(op_id, std::move(ident_name), std::move(args)));
1202
36.6k
}
1203
1204
0
std::any ParserVisitor::visitNested(CelParser::NestedContext* ctx) {
1205
0
  return visit(ctx->e);
1206
0
}
1207
1208
13.6k
std::any ParserVisitor::visitCreateList(CelParser::CreateListContext* ctx) {
1209
13.6k
  int64_t list_id = factory_.NextId(SourceRangeFromParserRuleContext(ctx));
1210
13.6k
  auto elems = visitList(ctx->elems);
1211
13.6k
  return ExprToAny(factory_.NewList(list_id, std::move(elems)));
1212
13.6k
}
1213
1214
std::vector<ListExprElement> ParserVisitor::visitList(
1215
13.6k
    CelParser::ListInitContext* ctx) {
1216
13.6k
  std::vector<ListExprElement> rv;
1217
13.6k
  if (!ctx) return rv;
1218
12.7k
  rv.reserve(ctx->elems.size());
1219
262k
  for (size_t i = 0; i < ctx->elems.size(); ++i) {
1220
249k
    auto* expr_ctx = ctx->elems[i];
1221
249k
    if (expr_ctx == nullptr) {
1222
0
      return rv;
1223
0
    }
1224
249k
    if (!enable_optional_syntax_ && expr_ctx->opt != nullptr) {
1225
340
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1226
340
                           "unsupported syntax '?'");
1227
340
      rv.push_back(factory_.NewListElement(factory_.NewUnspecified(0), false));
1228
340
      continue;
1229
340
    }
1230
249k
    rv.push_back(factory_.NewListElement(ExprFromAny(visitExpr(expr_ctx->e)),
1231
249k
                                         expr_ctx->opt != nullptr));
1232
249k
  }
1233
12.7k
  return rv;
1234
12.7k
}
1235
1236
85.7k
std::vector<Expr> ParserVisitor::visitList(CelParser::ExprListContext* ctx) {
1237
85.7k
  std::vector<Expr> rv;
1238
85.7k
  if (!ctx) return rv;
1239
71.8k
  std::transform(ctx->e.begin(), ctx->e.end(), std::back_inserter(rv),
1240
145k
                 [this](CelParser::ExprContext* expr_ctx) {
1241
145k
                   return ExprFromAny(visitExpr(expr_ctx));
1242
145k
                 });
1243
71.8k
  return rv;
1244
85.7k
}
1245
1246
6.22k
std::any ParserVisitor::visitCreateMap(CelParser::CreateMapContext* ctx) {
1247
6.22k
  int64_t struct_id = factory_.NextId(SourceRangeFromParserRuleContext(ctx));
1248
6.22k
  std::vector<MapExprEntry> entries;
1249
6.22k
  if (ctx->entries) {
1250
5.30k
    entries = visitEntries(ctx->entries);
1251
5.30k
  }
1252
6.22k
  return ExprToAny(factory_.NewMap(struct_id, std::move(entries)));
1253
6.22k
}
1254
1255
std::any ParserVisitor::visitConstantLiteral(
1256
1.02M
    CelParser::ConstantLiteralContext* clctx) {
1257
1.02M
  CelParser::LiteralContext* literal = clctx->literal();
1258
1.02M
  if (auto* ctx = tree_as<CelParser::IntContext>(literal)) {
1259
605k
    return visitInt(ctx);
1260
605k
  } else if (auto* ctx = tree_as<CelParser::UintContext>(literal)) {
1261
9.05k
    return visitUint(ctx);
1262
405k
  } else if (auto* ctx = tree_as<CelParser::DoubleContext>(literal)) {
1263
75.9k
    return visitDouble(ctx);
1264
329k
  } else if (auto* ctx = tree_as<CelParser::StringContext>(literal)) {
1265
317k
    return visitString(ctx);
1266
317k
  } else if (auto* ctx = tree_as<CelParser::BytesContext>(literal)) {
1267
5.90k
    return visitBytes(ctx);
1268
5.90k
  } else if (auto* ctx = tree_as<CelParser::BoolFalseContext>(literal)) {
1269
788
    return visitBoolFalse(ctx);
1270
4.77k
  } else if (auto* ctx = tree_as<CelParser::BoolTrueContext>(literal)) {
1271
636
    return visitBoolTrue(ctx);
1272
4.13k
  } else if (auto* ctx = tree_as<CelParser::NullContext>(literal)) {
1273
3.76k
    return visitNull(ctx);
1274
3.76k
  }
1275
370
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(clctx),
1276
370
                                        "invalid constant literal expression"));
1277
1.02M
}
1278
1279
std::any ParserVisitor::visitMapInitializerList(
1280
0
    CelParser::MapInitializerListContext* ctx) {
1281
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1282
0
                                        "<<unreachable>>"));
1283
0
}
1284
1285
std::vector<MapExprEntry> ParserVisitor::visitEntries(
1286
5.30k
    CelParser::MapInitializerListContext* ctx) {
1287
5.30k
  std::vector<MapExprEntry> res;
1288
5.30k
  if (!ctx || ctx->keys.empty()) {
1289
0
    return res;
1290
0
  }
1291
1292
5.30k
  res.reserve(ctx->cols.size());
1293
321k
  for (size_t i = 0; i < ctx->cols.size(); ++i) {
1294
315k
    auto id = factory_.NextId(SourceRangeFromToken(ctx->cols[i]));
1295
315k
    if (!enable_optional_syntax_ && ctx->keys[i]->opt) {
1296
97
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1297
97
                           "unsupported syntax '?'");
1298
97
      res.push_back(factory_.NewMapEntry(0, factory_.NewUnspecified(0),
1299
97
                                         factory_.NewUnspecified(0), false));
1300
97
      continue;
1301
97
    }
1302
315k
    auto key = ExprFromAny(visit(ctx->keys[i]->e));
1303
315k
    auto value = ExprFromAny(visit(ctx->values[i]));
1304
315k
    res.push_back(factory_.NewMapEntry(id, std::move(key), std::move(value),
1305
315k
                                       ctx->keys[i]->opt != nullptr));
1306
315k
  }
1307
5.30k
  return res;
1308
5.30k
}
1309
1310
605k
std::any ParserVisitor::visitInt(CelParser::IntContext* ctx) {
1311
605k
  std::string value;
1312
605k
  if (ctx->sign) {
1313
12.4k
    value = ctx->sign->getText();
1314
12.4k
  }
1315
605k
  value += ctx->tok->getText();
1316
605k
  int64_t int_value;
1317
605k
  if (absl::StartsWith(ctx->tok->getText(), "0x")) {
1318
2.76k
    if (absl::SimpleHexAtoi(value, &int_value)) {
1319
1.18k
      return ExprToAny(factory_.NewIntConst(
1320
1.18k
          factory_.NextId(SourceRangeFromParserRuleContext(ctx)), int_value));
1321
1.57k
    } else {
1322
1.57k
      return ExprToAny(factory_.ReportError(
1323
1.57k
          SourceRangeFromParserRuleContext(ctx), "invalid hex int literal"));
1324
1.57k
    }
1325
2.76k
  }
1326
603k
  if (absl::SimpleAtoi(value, &int_value)) {
1327
599k
    return ExprToAny(factory_.NewIntConst(
1328
599k
        factory_.NextId(SourceRangeFromParserRuleContext(ctx)), int_value));
1329
599k
  } else {
1330
3.65k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1331
3.65k
                                          "invalid int literal"));
1332
3.65k
  }
1333
603k
}
1334
1335
9.05k
std::any ParserVisitor::visitUint(CelParser::UintContext* ctx) {
1336
9.05k
  std::string value = ctx->tok->getText();
1337
  // trim the 'u' designator included in the uint literal.
1338
9.05k
  if (!value.empty()) {
1339
9.05k
    value.resize(value.size() - 1);
1340
9.05k
  }
1341
9.05k
  uint64_t uint_value;
1342
9.05k
  if (absl::StartsWith(ctx->tok->getText(), "0x")) {
1343
4.33k
    if (absl::SimpleHexAtoi(value, &uint_value)) {
1344
1.84k
      return ExprToAny(factory_.NewUintConst(
1345
1.84k
          factory_.NextId(SourceRangeFromParserRuleContext(ctx)), uint_value));
1346
2.49k
    } else {
1347
2.49k
      return ExprToAny(factory_.ReportError(
1348
2.49k
          SourceRangeFromParserRuleContext(ctx), "invalid hex uint literal"));
1349
2.49k
    }
1350
4.33k
  }
1351
4.72k
  if (absl::SimpleAtoi(value, &uint_value)) {
1352
2.45k
    return ExprToAny(factory_.NewUintConst(
1353
2.45k
        factory_.NextId(SourceRangeFromParserRuleContext(ctx)), uint_value));
1354
2.45k
  } else {
1355
2.26k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1356
2.26k
                                          "invalid uint literal"));
1357
2.26k
  }
1358
4.72k
}
1359
1360
75.9k
std::any ParserVisitor::visitDouble(CelParser::DoubleContext* ctx) {
1361
75.9k
  std::string value;
1362
75.9k
  if (ctx->sign) {
1363
3.85k
    value = ctx->sign->getText();
1364
3.85k
  }
1365
75.9k
  value += ctx->tok->getText();
1366
75.9k
  double double_value;
1367
75.9k
  if (absl::SimpleAtod(value, &double_value)) {
1368
75.9k
    return ExprToAny(factory_.NewDoubleConst(
1369
75.9k
        factory_.NextId(SourceRangeFromParserRuleContext(ctx)), double_value));
1370
75.9k
  } else {
1371
0
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1372
0
                                          "invalid double literal"));
1373
0
  }
1374
75.9k
}
1375
1376
317k
std::any ParserVisitor::visitString(CelParser::StringContext* ctx) {
1377
317k
  auto status_or_value = cel::internal::ParseStringLiteral(ctx->tok->getText());
1378
317k
  if (!status_or_value.ok()) {
1379
3.18k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1380
3.18k
                                          status_or_value.status().message()));
1381
3.18k
  }
1382
314k
  return ExprToAny(factory_.NewStringConst(
1383
314k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)),
1384
314k
      std::move(status_or_value).value()));
1385
317k
}
1386
1387
5.90k
std::any ParserVisitor::visitBytes(CelParser::BytesContext* ctx) {
1388
5.90k
  auto status_or_value = cel::internal::ParseBytesLiteral(ctx->tok->getText());
1389
5.90k
  if (!status_or_value.ok()) {
1390
2.18k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1391
2.18k
                                          status_or_value.status().message()));
1392
2.18k
  }
1393
3.71k
  return ExprToAny(factory_.NewBytesConst(
1394
3.71k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)),
1395
3.71k
      std::move(status_or_value).value()));
1396
5.90k
}
1397
1398
636
std::any ParserVisitor::visitBoolTrue(CelParser::BoolTrueContext* ctx) {
1399
636
  return ExprToAny(factory_.NewBoolConst(
1400
636
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)), true));
1401
636
}
1402
1403
788
std::any ParserVisitor::visitBoolFalse(CelParser::BoolFalseContext* ctx) {
1404
788
  return ExprToAny(factory_.NewBoolConst(
1405
788
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)), false));
1406
788
}
1407
1408
3.76k
std::any ParserVisitor::visitNull(CelParser::NullContext* ctx) {
1409
3.76k
  return ExprToAny(factory_.NewNullConst(
1410
3.76k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1411
3.76k
}
1412
1413
1.67k
cel::SourceInfo ParserVisitor::GetSourceInfo() {
1414
1.67k
  cel::SourceInfo source_info;
1415
1.67k
  source_info.set_location(std::string(source_.description()));
1416
2.92M
  for (const auto& positions : factory_.positions()) {
1417
2.92M
    source_info.mutable_positions().insert(
1418
2.92M
        std::pair{positions.first, positions.second.begin});
1419
2.92M
  }
1420
1.67k
  source_info.mutable_line_offsets().reserve(source_.line_offsets().size());
1421
7.15M
  for (const auto& line_offset : source_.line_offsets()) {
1422
7.15M
    source_info.mutable_line_offsets().push_back(line_offset);
1423
7.15M
  }
1424
1425
1.67k
  source_info.mutable_macro_calls() = factory_.release_macro_calls();
1426
1.67k
  return source_info;
1427
1.67k
}
1428
1429
1.67k
EnrichedSourceInfo ParserVisitor::enriched_source_info() const {
1430
1.67k
  std::map<int64_t, std::pair<int32_t, int32_t>> offsets;
1431
2.92M
  for (const auto& positions : factory_.positions()) {
1432
2.92M
    offsets.insert(
1433
2.92M
        std::pair{positions.first,
1434
2.92M
                  std::pair{positions.second.begin, positions.second.end - 1}});
1435
2.92M
  }
1436
1.67k
  return EnrichedSourceInfo(std::move(offsets));
1437
1.67k
}
1438
1439
void ParserVisitor::syntaxError(antlr4::Recognizer* recognizer,
1440
                                antlr4::Token* offending_symbol, size_t line,
1441
                                size_t col, const std::string& msg,
1442
8.13M
                                std::exception_ptr e) {
1443
8.13M
  cel::SourceRange range;
1444
8.13M
  if (auto position = source_.GetPosition(cel::SourceLocation{
1445
8.13M
          static_cast<int32_t>(line), static_cast<int32_t>(col)});
1446
8.13M
      position) {
1447
8.13M
    range.begin = *position;
1448
8.13M
  }
1449
8.13M
  factory_.ReportError(range, absl::StrCat("Syntax error: ", msg));
1450
8.13M
}
1451
1452
7.15k
bool ParserVisitor::HasErrored() const { return factory_.HasErrors(); }
1453
1454
5.46k
std::vector<cel::ParseIssue> ParserVisitor::CollectIssues() {
1455
5.46k
  return factory_.CollectIssues();
1456
5.46k
}
1457
1458
Expr ParserVisitor::GlobalCallOrMacroImpl(int64_t expr_id,
1459
                                          absl::string_view function,
1460
2.61M
                                          std::vector<Expr> args) {
1461
2.61M
  if (auto macro = macro_registry_.FindMacro(function, args.size(), false);
1462
2.61M
      macro) {
1463
11.4k
    std::vector<Expr> macro_args;
1464
11.4k
    if (add_macro_calls_) {
1465
0
      macro_args.reserve(args.size());
1466
0
      for (const auto& arg : args) {
1467
0
        macro_args.push_back(factory_.BuildMacroCallArg(arg));
1468
0
      }
1469
0
    }
1470
11.4k
    factory_.BeginMacro(factory_.GetSourceRange(expr_id));
1471
11.4k
    auto expr = macro->Expand(factory_, std::nullopt, absl::MakeSpan(args));
1472
11.4k
    factory_.EndMacro();
1473
11.4k
    if (expr) {
1474
11.4k
      if (add_macro_calls_) {
1475
0
        factory_.AddMacroCall(expr->id(), function, std::nullopt,
1476
0
                              std::move(macro_args));
1477
0
      }
1478
      // We did not end up using `expr_id`. Delete metadata.
1479
11.4k
      factory_.EraseId(expr_id);
1480
11.4k
      return std::move(*expr);
1481
11.4k
    }
1482
11.4k
  }
1483
1484
2.59M
  return factory_.NewCall(expr_id, function, std::move(args));
1485
2.61M
}
1486
1487
Expr ParserVisitor::ReceiverCallOrMacroImpl(int64_t expr_id,
1488
                                            absl::string_view function,
1489
                                            Expr target,
1490
49.1k
                                            std::vector<Expr> args) {
1491
49.1k
  if (auto macro = macro_registry_.FindMacro(function, args.size(), true);
1492
49.1k
      macro) {
1493
32.3k
    Expr macro_target;
1494
32.3k
    std::vector<Expr> macro_args;
1495
32.3k
    if (add_macro_calls_) {
1496
0
      macro_args.reserve(args.size());
1497
0
      macro_target = factory_.BuildMacroCallArg(target);
1498
0
      for (const auto& arg : args) {
1499
0
        macro_args.push_back(factory_.BuildMacroCallArg(arg));
1500
0
      }
1501
0
    }
1502
32.3k
    factory_.BeginMacro(factory_.GetSourceRange(expr_id));
1503
32.3k
    auto expr = macro->Expand(factory_, std::ref(target), absl::MakeSpan(args));
1504
32.3k
    factory_.EndMacro();
1505
32.3k
    if (expr) {
1506
32.3k
      if (add_macro_calls_) {
1507
0
        factory_.AddMacroCall(expr->id(), function, std::move(macro_target),
1508
0
                              std::move(macro_args));
1509
0
      }
1510
      // We did not end up using `expr_id`. Delete metadata.
1511
32.3k
      factory_.EraseId(expr_id);
1512
32.3k
      return std::move(*expr);
1513
32.3k
    }
1514
32.3k
  }
1515
16.8k
  return factory_.NewMemberCall(expr_id, function, std::move(target),
1516
16.8k
                                std::move(args));
1517
49.1k
}
1518
1519
std::string ParserVisitor::ExtractQualifiedName(antlr4::ParserRuleContext* ctx,
1520
0
                                                const Expr& e) {
1521
0
  if (e == Expr{}) {
1522
0
    return "";
1523
0
  }
1524
0
1525
0
  if (const auto* ident_expr = absl::get_if<IdentExpr>(&e.kind()); ident_expr) {
1526
0
    return ident_expr->name();
1527
0
  }
1528
0
  if (const auto* select_expr = absl::get_if<SelectExpr>(&e.kind());
1529
0
      select_expr) {
1530
0
    std::string prefix = ExtractQualifiedName(ctx, select_expr->operand());
1531
0
    if (!prefix.empty()) {
1532
0
      return absl::StrCat(prefix, ".", select_expr->field());
1533
0
    }
1534
0
  }
1535
0
  factory_.ReportError(factory_.GetSourceRange(e.id()),
1536
0
                       "expected a qualified name");
1537
0
  return "";
1538
0
}
1539
1540
// Replacements for absl::StrReplaceAll for escaping standard whitespace
1541
// characters.
1542
static constexpr auto kStandardReplacements =
1543
    std::array<std::pair<absl::string_view, absl::string_view>, 3>{
1544
        std::make_pair("\n", "\\n"),
1545
        std::make_pair("\r", "\\r"),
1546
        std::make_pair("\t", "\\t"),
1547
    };
1548
1549
static constexpr absl::string_view kSingleQuote = "'";
1550
1551
// ExprRecursionListener extends the standard ANTLR CelParser to ensure that
1552
// recursive entries into the 'expr' rule are limited to a configurable depth so
1553
// as to prevent stack overflows.
1554
class ExprRecursionListener final : public ParseTreeListener {
1555
 public:
1556
  explicit ExprRecursionListener(
1557
      const int max_recursion_depth = kDefaultMaxRecursionDepth)
1558
7.15k
      : max_recursion_depth_(max_recursion_depth), recursion_depth_(0) {}
1559
0
  ~ExprRecursionListener() override {}
1560
1561
9.62M
  void visitTerminal(TerminalNode* node) override {};
1562
106k
  void visitErrorNode(ErrorNode* error) override {};
1563
  void enterEveryRule(ParserRuleContext* ctx) override;
1564
  void exitEveryRule(ParserRuleContext* ctx) override;
1565
1566
 private:
1567
  const int max_recursion_depth_;
1568
  int recursion_depth_;
1569
};
1570
1571
25.3M
void ExprRecursionListener::enterEveryRule(ParserRuleContext* ctx) {
1572
  // Throw a ParseCancellationException since the parsing would otherwise
1573
  // continue if this were treated as a syntax error and the problem would
1574
  // continue to manifest.
1575
25.3M
  if (ctx->getRuleIndex() == CelParser::RuleExpr) {
1576
1.10M
    if (recursion_depth_ > max_recursion_depth_) {
1577
21
      throw ParseCancellationException(
1578
21
          absl::StrFormat("Expression recursion limit exceeded. limit: %d",
1579
21
                          max_recursion_depth_));
1580
21
    }
1581
1.10M
    recursion_depth_++;
1582
1.10M
  }
1583
25.3M
}
1584
1585
25.4M
void ExprRecursionListener::exitEveryRule(ParserRuleContext* ctx) {
1586
25.4M
  if (ctx->getRuleIndex() == CelParser::RuleExpr) {
1587
1.10M
    recursion_depth_--;
1588
1.10M
  }
1589
25.4M
}
1590
1591
class RecoveryLimitErrorStrategy final : public DefaultErrorStrategy {
1592
 public:
1593
  explicit RecoveryLimitErrorStrategy(
1594
      int recovery_limit = kDefaultErrorRecoveryLimit,
1595
      int recovery_token_lookahead_limit =
1596
          kDefaultErrorRecoveryTokenLookaheadLimit)
1597
7.15k
      : recovery_limit_(recovery_limit),
1598
7.15k
        recovery_attempts_(0),
1599
7.15k
        recovery_token_lookahead_limit_(recovery_token_lookahead_limit) {}
1600
1601
16.9k
  void recover(Parser* recognizer, std::exception_ptr e) override {
1602
16.9k
    checkRecoveryLimit(recognizer);
1603
16.9k
    DefaultErrorStrategy::recover(recognizer, e);
1604
16.9k
  }
1605
1606
11.8k
  Token* recoverInline(Parser* recognizer) override {
1607
11.8k
    checkRecoveryLimit(recognizer);
1608
11.8k
    return DefaultErrorStrategy::recoverInline(recognizer);
1609
11.8k
  }
1610
1611
  // Override the ANTLR implementation to introduce a token lookahead limit as
1612
  // this prevents pathologically constructed, yet small (< 16kb) inputs from
1613
  // consuming inordinate amounts of compute.
1614
  //
1615
  // This method is only called on error recovery paths.
1616
19.1k
  void consumeUntil(Parser* recognizer, const IntervalSet& set) override {
1617
19.1k
    size_t ttype = recognizer->getInputStream()->LA(1);
1618
19.1k
    int recovery_search_depth = 0;
1619
108k
    while (ttype != Token::EOF && !set.contains(ttype) &&
1620
89.6k
           recovery_search_depth++ < recovery_token_lookahead_limit_) {
1621
89.5k
      recognizer->consume();
1622
89.5k
      ttype = recognizer->getInputStream()->LA(1);
1623
89.5k
    }
1624
    // Halt all parsing if the lookahead limit is reached during error recovery.
1625
19.1k
    if (recovery_search_depth == recovery_token_lookahead_limit_) {
1626
2
      throw ParseCancellationException("Unable to find a recovery token");
1627
2
    }
1628
19.1k
  }
1629
1630
 protected:
1631
31.3k
  std::string escapeWSAndQuote(const std::string& s) const override {
1632
31.3k
    std::string result;
1633
31.3k
    result.reserve(s.size() + 2);
1634
31.3k
    absl::StrAppend(&result, kSingleQuote, s, kSingleQuote);
1635
31.3k
    absl::StrReplaceAll(kStandardReplacements, &result);
1636
31.3k
    return result;
1637
31.3k
  }
1638
1639
 private:
1640
28.8k
  void checkRecoveryLimit(Parser* recognizer) {
1641
28.8k
    if (recovery_attempts_++ >= recovery_limit_) {
1642
597
      std::string too_many_errors =
1643
597
          absl::StrFormat("More than %d parse errors.", recovery_limit_);
1644
597
      recognizer->notifyErrorListeners(too_many_errors);
1645
597
      throw ParseCancellationException(too_many_errors);
1646
597
    }
1647
28.8k
  }
1648
1649
  int recovery_limit_;
1650
  int recovery_attempts_;
1651
  int recovery_token_lookahead_limit_;
1652
};
1653
1654
struct ParseResult {
1655
  cel::Expr expr;
1656
  cel::SourceInfo source_info;
1657
  EnrichedSourceInfo enriched_source_info;
1658
};
1659
1660
absl::StatusOr<ParseResult> ParseImpl(
1661
    const cel::Source& source, const cel::MacroRegistry& registry,
1662
    const ParserOptions& options,
1663
7.15k
    std::vector<cel::ParseIssue>* parse_issues = nullptr) {
1664
7.15k
  try {
1665
7.15k
    CodePointStream input(source.content(), source.description());
1666
7.15k
    if (input.size() > options.expression_size_codepoint_limit) {
1667
0
      return absl::InvalidArgumentError(absl::StrCat(
1668
0
          "expression size exceeds codepoint limit.", " input size: ",
1669
0
          input.size(), ", limit: ", options.expression_size_codepoint_limit));
1670
0
    }
1671
7.15k
    CelLexer lexer(&input);
1672
7.15k
    CommonTokenStream tokens(&lexer);
1673
7.15k
    CelParser parser(&tokens);
1674
7.15k
    ExprRecursionListener listener(options.max_recursion_depth);
1675
7.15k
    ParserVisitor visitor(
1676
7.15k
        source, options.max_recursion_depth, registry, options.add_macro_calls,
1677
7.15k
        options.enable_optional_syntax, options.enable_quoted_identifiers,
1678
7.15k
        options.enable_variadic_logical_operators);
1679
1680
7.15k
    lexer.removeErrorListeners();
1681
7.15k
    parser.removeErrorListeners();
1682
7.15k
    lexer.addErrorListener(&visitor);
1683
7.15k
    parser.addErrorListener(&visitor);
1684
7.15k
    parser.addParseListener(&listener);
1685
1686
    // Limit the number of error recovery attempts to prevent bad expressions
1687
    // from consuming lots of cpu / memory.
1688
7.15k
    parser.setErrorHandler(std::make_shared<RecoveryLimitErrorStrategy>(
1689
7.15k
        options.error_recovery_limit,
1690
7.15k
        options.error_recovery_token_lookahead_limit));
1691
1692
7.15k
    Expr expr;
1693
7.15k
    try {
1694
7.15k
      expr = ExprFromAny(visitor.visit(parser.start()));
1695
7.15k
    } catch (const ParseCancellationException& e) {
1696
620
      if (visitor.HasErrored()) {
1697
615
        auto issues = visitor.CollectIssues();
1698
615
        std::string error_message = FormatIssues(source, issues);
1699
615
        if (parse_issues != nullptr) {
1700
0
          *parse_issues = std::move(issues);
1701
0
        }
1702
615
        return absl::InvalidArgumentError(error_message);
1703
615
      }
1704
5
      return absl::CancelledError(e.what());
1705
620
    }
1706
1707
6.53k
    if (visitor.HasErrored()) {
1708
4.85k
      auto issues = visitor.CollectIssues();
1709
4.85k
      std::string error_message = FormatIssues(source, issues);
1710
4.85k
      if (parse_issues != nullptr) {
1711
0
        *parse_issues = std::move(issues);
1712
0
      }
1713
4.85k
      return absl::InvalidArgumentError(error_message);
1714
4.85k
    }
1715
1716
1.67k
    return {
1717
1.67k
        ParseResult{.expr = std::move(expr),
1718
1.67k
                    .source_info = visitor.GetSourceInfo(),
1719
1.67k
                    .enriched_source_info = visitor.enriched_source_info()}};
1720
6.53k
  } catch (const std::exception& e) {
1721
0
    return absl::AbortedError(e.what());
1722
0
  } catch (const char* what) {
1723
    // ANTLRv4 has historically thrown C string literals.
1724
0
    return absl::AbortedError(what);
1725
0
  } catch (...) {
1726
    // We guarantee to never throw and always return a status.
1727
0
    return absl::UnknownError("An unknown exception occurred");
1728
0
  }
1729
7.15k
}
1730
1731
class ParserImpl : public cel::Parser {
1732
 public:
1733
  explicit ParserImpl(const ParserOptions& options,
1734
                      cel::MacroRegistry macro_registry,
1735
                      absl::flat_hash_set<std::string> library_ids)
1736
0
      : options_(options),
1737
0
        macro_registry_(std::move(macro_registry)),
1738
0
        library_ids_(std::move(library_ids)) {}
1739
1740
  absl::StatusOr<std::unique_ptr<cel::Ast>> ParseImpl(
1741
      const cel::Source& source,
1742
0
      std::vector<cel::ParseIssue>* parse_issues) const override {
1743
0
    CEL_ASSIGN_OR_RETURN(auto parse_result,
1744
0
                         ::google::api::expr::parser::ParseImpl(
1745
0
                             source, macro_registry_, options_, parse_issues));
1746
0
    return std::make_unique<cel::Ast>(std::move(parse_result.expr),
1747
0
                                      std::move(parse_result.source_info));
1748
0
  }
1749
1750
  std::unique_ptr<cel::ParserBuilder> ToBuilder() const override;
1751
1752
 private:
1753
  const ParserOptions options_;
1754
  const cel::MacroRegistry macro_registry_;
1755
  absl::flat_hash_set<std::string> library_ids_;
1756
};
1757
1758
class ParserBuilderImpl : public cel::ParserBuilder {
1759
 public:
1760
  explicit ParserBuilderImpl(const ParserOptions& options)
1761
0
      : options_(options) {}
1762
1763
0
  ParserOptions& GetOptions() override { return options_; }
1764
1765
0
  absl::Status AddMacro(const cel::Macro& macro) override {
1766
0
    for (const auto& existing_macro : macros_) {
1767
0
      if (existing_macro.key() == macro.key()) {
1768
0
        return absl::AlreadyExistsError(
1769
0
            absl::StrCat("macro already exists: ", macro.key()));
1770
0
      }
1771
0
    }
1772
0
    macros_.push_back(macro);
1773
0
    return absl::OkStatus();
1774
0
  }
1775
1776
0
  absl::Status AddLibrary(cel::ParserLibrary library) override {
1777
0
    if (!library.id.empty()) {
1778
0
      auto [it, inserted] = library_ids_.insert(library.id);
1779
0
      if (!inserted) {
1780
0
        return absl::AlreadyExistsError(
1781
0
            absl::StrCat("parser library already exists: ", library.id));
1782
0
      }
1783
0
    }
1784
0
    libraries_.push_back(std::move(library));
1785
0
    return absl::OkStatus();
1786
0
  }
1787
1788
0
  absl::Status AddLibrarySubset(cel::ParserLibrarySubset subset) override {
1789
0
    if (subset.library_id.empty()) {
1790
0
      return absl::InvalidArgumentError("subset must have a library id");
1791
0
    }
1792
0
    std::string library_id = subset.library_id;
1793
0
    auto [it, inserted] =
1794
0
        library_subsets_.insert({library_id, std::move(subset)});
1795
0
    if (!inserted) {
1796
0
      return absl::AlreadyExistsError(
1797
0
          absl::StrCat("parser library subset already exists: ", library_id));
1798
0
    }
1799
0
    return absl::OkStatus();
1800
0
  }
1801
1802
0
  absl::StatusOr<std::unique_ptr<cel::Parser>> Build() override {
1803
0
    using std::swap;
1804
    // Save the old configured macros so they aren't affected by applying the
1805
    // libraries and can be restored if an error occurs.
1806
0
    std::vector<cel::Macro> individual_macros;
1807
0
    swap(individual_macros, macros_);
1808
0
    absl::Cleanup cleanup([&] { swap(macros_, individual_macros); });
1809
1810
0
    cel::MacroRegistry macro_registry;
1811
1812
0
    for (const auto& library : libraries_) {
1813
0
      CEL_RETURN_IF_ERROR(library.configure(*this));
1814
0
      if (!library.id.empty()) {
1815
0
        auto it = library_subsets_.find(library.id);
1816
0
        if (it != library_subsets_.end()) {
1817
0
          const cel::ParserLibrarySubset& subset = it->second;
1818
0
          for (const auto& macro : macros_) {
1819
0
            if (subset.should_include_macro(macro)) {
1820
0
              CEL_RETURN_IF_ERROR(macro_registry.RegisterMacro(macro));
1821
0
            }
1822
0
          }
1823
0
          macros_.clear();
1824
0
          continue;
1825
0
        }
1826
0
      }
1827
1828
0
      CEL_RETURN_IF_ERROR(macro_registry.RegisterMacros(macros_));
1829
0
      macros_.clear();
1830
0
    }
1831
1832
0
    absl::flat_hash_set<std::string> library_ids(library_ids_);
1833
1834
    // Hack to support adding the standard library macros either by option or
1835
    // with a library configurer.
1836
0
    if (!options_.disable_standard_macros && !library_ids_.contains("stdlib")) {
1837
0
      CEL_RETURN_IF_ERROR(macro_registry.RegisterMacros(Macro::AllMacros()));
1838
0
      library_ids.insert("stdlib");
1839
0
    }
1840
1841
0
    if (options_.enable_optional_syntax && !library_ids_.contains("optional")) {
1842
0
      CEL_RETURN_IF_ERROR(macro_registry.RegisterMacro(cel::OptMapMacro()));
1843
0
      CEL_RETURN_IF_ERROR(macro_registry.RegisterMacro(cel::OptFlatMapMacro()));
1844
0
      library_ids.insert("optional");
1845
0
    }
1846
0
    CEL_RETURN_IF_ERROR(macro_registry.RegisterMacros(individual_macros));
1847
0
    return std::make_unique<ParserImpl>(options_, std::move(macro_registry),
1848
0
                                        std::move(library_ids));
1849
0
  }
1850
1851
 private:
1852
  friend class ParserImpl;
1853
1854
  ParserOptions options_;
1855
  std::vector<cel::Macro> macros_;
1856
  absl::flat_hash_set<std::string> library_ids_;
1857
  std::vector<cel::ParserLibrary> libraries_;
1858
  absl::flat_hash_map<std::string, cel::ParserLibrarySubset> library_subsets_;
1859
};
1860
1861
0
std::unique_ptr<cel::ParserBuilder> ParserImpl::ToBuilder() const {
1862
0
  auto ins = std::make_unique<ParserBuilderImpl>(options_);
1863
0
  ins->library_ids_ = library_ids_;
1864
0
  ins->macros_ = macro_registry_.ListMacros();
1865
0
  return ins;
1866
0
}
1867
1868
}  // namespace
1869
1870
absl::StatusOr<ParsedExpr> Parse(absl::string_view expression,
1871
                                 absl::string_view description,
1872
7.24k
                                 const ParserOptions& options) {
1873
7.24k
  std::vector<Macro> macros;
1874
7.24k
  if (!options.disable_standard_macros) {
1875
7.24k
    macros = Macro::AllMacros();
1876
7.24k
  }
1877
7.24k
  if (options.enable_optional_syntax) {
1878
0
    macros.push_back(cel::OptMapMacro());
1879
0
    macros.push_back(cel::OptFlatMapMacro());
1880
0
  }
1881
7.24k
  return ParseWithMacros(expression, macros, description, options);
1882
7.24k
}
1883
1884
absl::StatusOr<ParsedExpr> ParseWithMacros(absl::string_view expression,
1885
                                           const std::vector<Macro>& macros,
1886
                                           absl::string_view description,
1887
7.24k
                                           const ParserOptions& options) {
1888
7.24k
  CEL_ASSIGN_OR_RETURN(auto verbose_parsed_expr,
1889
1.67k
                       EnrichedParse(expression, macros, description, options));
1890
1.67k
  return verbose_parsed_expr.parsed_expr();
1891
7.24k
}
1892
1893
absl::StatusOr<VerboseParsedExpr> EnrichedParse(
1894
    absl::string_view expression, const std::vector<Macro>& macros,
1895
7.24k
    absl::string_view description, const ParserOptions& options) {
1896
7.24k
  CEL_ASSIGN_OR_RETURN(auto source,
1897
7.15k
                       cel::NewSource(expression, std::string(description)));
1898
7.15k
  cel::MacroRegistry macro_registry;
1899
7.15k
  CEL_RETURN_IF_ERROR(macro_registry.RegisterMacros(macros));
1900
7.15k
  return EnrichedParse(*source, macro_registry, options);
1901
7.15k
}
1902
1903
absl::StatusOr<VerboseParsedExpr> EnrichedParse(
1904
    const cel::Source& source, const cel::MacroRegistry& registry,
1905
7.15k
    const ParserOptions& options) {
1906
7.15k
  CEL_ASSIGN_OR_RETURN(ParseResult parse_result,
1907
1.67k
                       ParseImpl(source, registry, options));
1908
1.67k
  ParsedExpr parsed_expr;
1909
1.67k
  CEL_RETURN_IF_ERROR(cel::ast_internal::ExprToProto(
1910
1.67k
      parse_result.expr, parsed_expr.mutable_expr()));
1911
1912
1.67k
  CEL_RETURN_IF_ERROR(cel::ast_internal::SourceInfoToProto(
1913
1.67k
      parse_result.source_info, parsed_expr.mutable_source_info()));
1914
1.67k
  return VerboseParsedExpr(std::move(parsed_expr),
1915
1.67k
                           std::move(parse_result.enriched_source_info));
1916
1.67k
}
1917
1918
absl::StatusOr<cel::expr::ParsedExpr> Parse(
1919
    const cel::Source& source, const cel::MacroRegistry& registry,
1920
0
    const ParserOptions& options) {
1921
0
  CEL_ASSIGN_OR_RETURN(auto verbose_expr,
1922
0
                       EnrichedParse(source, registry, options));
1923
0
  return verbose_expr.parsed_expr();
1924
0
}
1925
1926
}  // namespace google::api::expr::parser
1927
1928
namespace cel {
1929
1930
// Creates a new parser builder.
1931
//
1932
// Intended for use with the Compiler class, most users should prefer the free
1933
// functions above for independent parsing of expressions.
1934
0
std::unique_ptr<ParserBuilder> NewParserBuilder(const ParserOptions& options) {
1935
0
  return std::make_unique<google::api::expr::parser::ParserBuilderImpl>(
1936
0
      options);
1937
0
}
1938
1939
}  // namespace cel