Coverage Report

Created: 2025-12-29 06:46

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