Coverage Report

Created: 2025-11-29 07:01

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
3.07M
std::any ExprPtrToAny(std::unique_ptr<Expr>&& expr) {
93
3.07M
  return std::make_any<Expr*>(expr.release());
94
3.07M
}
95
96
3.07M
std::any ExprToAny(Expr&& expr) {
97
3.07M
  return ExprPtrToAny(std::make_unique<Expr>(std::move(expr)));
98
3.07M
}
99
100
3.07M
std::unique_ptr<Expr> ExprPtrFromAny(std::any&& any) {
101
3.07M
  return absl::WrapUnique(std::any_cast<Expr*>(std::move(any)));
102
3.07M
}
103
104
3.07M
Expr ExprFromAny(std::any&& any) {
105
3.07M
  auto expr = ExprPtrFromAny(std::move(any));
106
3.07M
  return std::move(*expr);
107
3.07M
}
108
109
struct ParserError {
110
  std::string message;
111
  SourceRange range;
112
};
113
114
std::string DisplayParserError(const cel::Source& source,
115
58.4k
                               const ParserError& error) {
116
58.4k
  auto location =
117
58.4k
      source.GetLocation(error.range.begin).value_or(SourceLocation{});
118
58.4k
  return absl::StrCat(absl::StrFormat("ERROR: %s:%zu:%zu: %s",
119
58.4k
                                      source.description(), location.line,
120
                                      // add one to the 0-based column
121
58.4k
                                      location.column + 1, error.message),
122
58.4k
                      source.DisplayErrorLocation(location));
123
58.4k
}
124
125
629k
int32_t PositiveOrMax(int32_t value) {
126
629k
  return value >= 0 ? value : std::numeric_limits<int32_t>::max();
127
629k
}
128
129
2.06M
SourceRange SourceRangeFromToken(const antlr4::Token* token) {
130
2.06M
  SourceRange range;
131
2.06M
  if (token != nullptr) {
132
2.06M
    if (auto start = token->getStartIndex(); start != INVALID_INDEX) {
133
2.06M
      range.begin = static_cast<int32_t>(start);
134
2.06M
    }
135
2.06M
    if (auto end = token->getStopIndex(); end != INVALID_INDEX) {
136
2.06M
      range.end = static_cast<int32_t>(end + 1);
137
2.06M
    }
138
2.06M
  }
139
2.06M
  return range;
140
2.06M
}
141
142
SourceRange SourceRangeFromParserRuleContext(
143
1.11M
    const antlr4::ParserRuleContext* context) {
144
1.11M
  SourceRange range;
145
1.11M
  if (context != nullptr) {
146
1.11M
    if (auto start = context->getStart() != nullptr
147
1.11M
                         ? context->getStart()->getStartIndex()
148
1.11M
                         : INVALID_INDEX;
149
1.11M
        start != INVALID_INDEX) {
150
1.11M
      range.begin = static_cast<int32_t>(start);
151
1.11M
    }
152
1.11M
    if (auto end = context->getStop() != nullptr
153
1.11M
                       ? context->getStop()->getStopIndex()
154
1.11M
                       : INVALID_INDEX;
155
1.11M
        end != INVALID_INDEX) {
156
1.11M
      range.end = static_cast<int32_t>(end + 1);
157
1.11M
    }
158
1.11M
  }
159
1.11M
  return range;
160
1.11M
}
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
4.20k
      : MacroExprFactory(accu_var), source_(source) {}
169
170
3.48k
  void BeginMacro(SourceRange macro_position) {
171
3.48k
    macro_position_ = macro_position;
172
3.48k
  }
173
174
3.48k
  void EndMacro() { macro_position_ = SourceRange{}; }
175
176
3.27k
  Expr ReportError(absl::string_view message) override {
177
3.27k
    return ReportError(macro_position_, message);
178
3.27k
  }
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
1.79M
  Expr ReportError(SourceRange range, absl::string_view message) {
185
1.79M
    ++error_count_;
186
1.79M
    if (errors_.size() <= 100) {
187
58.4k
      errors_.push_back(ParserError{std::string(message), range});
188
58.4k
    }
189
1.79M
    return NewUnspecified(NextId(range));
190
1.79M
  }
191
192
1.96k
  Expr ReportErrorAt(const Expr& expr, absl::string_view message) override {
193
1.96k
    return ReportError(GetSourceRange(expr.id()), message);
194
1.96k
  }
195
196
5.44k
  SourceRange GetSourceRange(int64_t id) const {
197
5.44k
    if (auto it = positions_.find(id); it != positions_.end()) {
198
5.28k
      return it->second;
199
5.28k
    }
200
163
    return SourceRange{};
201
5.44k
  }
202
203
4.98M
  int64_t NextId(const SourceRange& range) {
204
4.98M
    auto id = expr_id_++;
205
4.98M
    if (range.begin != -1 || range.end != -1) {
206
4.97M
      positions_.insert(std::pair{id, range});
207
4.97M
    }
208
4.98M
    return id;
209
4.98M
  }
210
211
4.58k
  bool HasErrors() const { return error_count_ != 0; }
212
213
2.87k
  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
2.87k
    std::stable_sort(
219
2.87k
        errors_.begin(), errors_.end(),
220
157k
        [](const ParserError& lhs, const ParserError& rhs) -> bool {
221
157k
          auto lhs_begin = PositiveOrMax(lhs.range.begin);
222
157k
          auto lhs_end = PositiveOrMax(lhs.range.end);
223
157k
          auto rhs_begin = PositiveOrMax(rhs.range.begin);
224
157k
          auto rhs_end = PositiveOrMax(rhs.range.end);
225
157k
          return lhs_begin < rhs_begin ||
226
146k
                 (lhs_begin == rhs_begin && lhs_end < rhs_end);
227
157k
        });
228
    // Build the summary error message using the sorted errors.
229
2.87k
    bool errors_truncated = error_count_ > 100;
230
2.87k
    std::vector<std::string> messages;
231
2.87k
    messages.reserve(
232
2.87k
        errors_.size() +
233
2.87k
        errors_truncated);  // Reserve space for the transform and an
234
                            // additional element when truncation occurs.
235
2.87k
    std::transform(errors_.begin(), errors_.end(), std::back_inserter(messages),
236
58.4k
                   [this](const ParserError& error) {
237
58.4k
                     return cel::DisplayParserError(source_, error);
238
58.4k
                   });
239
2.87k
    if (errors_truncated) {
240
256
      messages.emplace_back(
241
256
          absl::StrCat(error_count_ - 100, " more errors were truncated."));
242
256
    }
243
2.87k
    return absl::StrJoin(messages, "\n");
244
2.87k
  }
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
2.64k
  const absl::btree_map<int64_t, SourceRange>& positions() const {
370
2.64k
    return positions_;
371
2.64k
  }
372
373
0
  const absl::flat_hash_map<int64_t, Expr>& macro_calls() const {
374
0
    return macro_calls_;
375
0
  }
376
377
1.32k
  absl::flat_hash_map<int64_t, Expr> release_macro_calls() {
378
1.32k
    using std::swap;
379
1.32k
    absl::flat_hash_map<int64_t, Expr> result;
380
1.32k
    swap(result, macro_calls_);
381
1.32k
    return result;
382
1.32k
  }
383
384
3.48k
  void EraseId(ExprId id) {
385
3.48k
    positions_.erase(id);
386
3.48k
    if (expr_id_ == id + 1) {
387
0
      --expr_id_;
388
0
    }
389
3.48k
  }
390
391
 protected:
392
14.7k
  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
4.20k
      : buffer_(buffer),
450
4.20k
        source_name_(source_name),
451
4.20k
        size_(buffer_.size()),
452
4.20k
        index_(0) {}
453
454
91.8M
  void consume() override {
455
91.8M
    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
91.8M
    index_++;
460
91.8M
  }
461
462
200M
  size_t LA(ptrdiff_t i) override {
463
200M
    if (ABSL_PREDICT_FALSE(i == 0)) {
464
0
      return 0;
465
0
    }
466
200M
    auto p = static_cast<ptrdiff_t>(index_);
467
200M
    if (i < 0) {
468
0
      i++;
469
0
      if (p + i - 1 < 0) {
470
0
        return IntStream::EOF;
471
0
      }
472
0
    }
473
200M
    if (p + i - 1 >= static_cast<ptrdiff_t>(size_)) {
474
9.45k
      return IntStream::EOF;
475
9.45k
    }
476
200M
    return buffer_.at(static_cast<size_t>(p + i - 1));
477
200M
  }
478
479
14.8M
  ptrdiff_t mark() override { return -1; }
480
481
14.8M
  void release(ptrdiff_t marker) override {}
482
483
68.6M
  size_t index() override { return index_; }
484
485
6.53M
  void seek(size_t index) override { index_ = std::min(index, size_); }
486
487
4.14M
  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
5.90M
  std::string getText(const antlr4::misc::Interval& interval) override {
495
5.90M
    if (ABSL_PREDICT_FALSE(interval.a < 0 || interval.b < 0)) {
496
0
      return std::string();
497
0
    }
498
5.90M
    size_t start = static_cast<size_t>(interval.a);
499
5.90M
    if (ABSL_PREDICT_FALSE(start >= size_)) {
500
0
      return std::string();
501
0
    }
502
5.90M
    size_t stop = static_cast<size_t>(interval.b);
503
5.90M
    if (ABSL_PREDICT_FALSE(stop >= size_)) {
504
271
      stop = size_ - 1;
505
271
    }
506
5.90M
    return buffer_.ToString(static_cast<cel::SourcePosition>(start),
507
5.90M
                            static_cast<cel::SourcePosition>(stop) + 1);
508
5.90M
  }
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
2.75M
      : recursion_depth_(recursion_depth) {
525
2.75M
    ++recursion_depth_;
526
2.75M
  }
527
528
2.75M
  ~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
548
    : factory_(factory), function_(std::move(function)) {
571
548
  terms_.push_back(std::move(expr));
572
548
}
573
574
37.9k
void ExpressionBalancer::AddTerm(int64_t op, Expr term) {
575
37.9k
  terms_.push_back(std::move(term));
576
37.9k
  ops_.push_back(op);
577
37.9k
}
578
579
548
Expr ExpressionBalancer::Balance() {
580
548
  if (terms_.size() == 1) {
581
0
    return std::move(terms_[0]);
582
0
  }
583
548
  return BalancedTree(0, ops_.size() - 1);
584
548
}
585
586
37.9k
Expr ExpressionBalancer::BalancedTree(int lo, int hi) {
587
37.9k
  int mid = (lo + hi + 1) / 2;
588
589
37.9k
  std::vector<Expr> arguments;
590
37.9k
  arguments.reserve(2);
591
592
37.9k
  if (mid == lo) {
593
16.1k
    arguments.push_back(std::move(terms_[mid]));
594
21.8k
  } else {
595
21.8k
    arguments.push_back(BalancedTree(lo, mid - 1));
596
21.8k
  }
597
598
37.9k
  if (mid == hi) {
599
22.3k
    arguments.push_back(std::move(terms_[mid + 1]));
600
22.3k
  } else {
601
15.5k
    arguments.push_back(BalancedTree(mid + 1, hi));
602
15.5k
  }
603
37.9k
  return factory_.NewCall(ops_[mid], function_, std::move(arguments));
604
37.9k
}
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
4.20k
      : source_(source),
616
4.20k
        factory_(source_, accu_var),
617
4.20k
        macro_registry_(macro_registry),
618
4.20k
        recursion_depth_(0),
619
4.20k
        max_recursion_depth_(max_recursion_depth),
620
4.20k
        add_macro_calls_(add_macro_calls),
621
4.20k
        enable_optional_syntax_(enable_optional_syntax),
622
4.20k
        enable_quoted_identifiers_(enable_quoted_identifiers) {}
623
624
4.20k
  ~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
850k
                         Args&&... args) {
684
850k
    std::vector<Expr> arguments;
685
850k
    arguments.reserve(sizeof...(Args));
686
850k
    (arguments.push_back(std::forward<Args>(args)), ...);
687
850k
    return GlobalCallOrMacroImpl(expr_id, function, std::move(arguments));
688
850k
  }
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
735k
                         Args&&... args) {
684
735k
    std::vector<Expr> arguments;
685
735k
    arguments.reserve(sizeof...(Args));
686
735k
    (arguments.push_back(std::forward<Args>(args)), ...);
687
735k
    return GlobalCallOrMacroImpl(expr_id, function, std::move(arguments));
688
735k
  }
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
114k
                         Args&&... args) {
684
114k
    std::vector<Expr> arguments;
685
114k
    arguments.reserve(sizeof...(Args));
686
114k
    (arguments.push_back(std::forward<Args>(args)), ...);
687
114k
    return GlobalCallOrMacroImpl(expr_id, function, std::move(arguments));
688
114k
  }
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
56.3M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
56.3M
  return dynamic_cast<T*>(tree);
719
56.3M
}
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
4.16M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
4.16M
  return dynamic_cast<T*>(tree);
719
4.16M
}
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
135k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
135k
  return dynamic_cast<T*>(tree);
719
135k
}
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
125k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
125k
  return dynamic_cast<T*>(tree);
719
125k
}
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
3.08k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
3.08k
  return dynamic_cast<T*>(tree);
719
3.08k
}
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
12.0k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
12.0k
  return dynamic_cast<T*>(tree);
719
12.0k
}
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
175
T* tree_as(antlr4::tree::ParseTree* tree) {
718
175
  return dynamic_cast<T*>(tree);
719
175
}
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
3.76M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
3.76M
  return dynamic_cast<T*>(tree);
719
3.76M
}
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
1.88M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
1.88M
  return dynamic_cast<T*>(tree);
719
1.88M
}
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.11M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
1.11M
  return dynamic_cast<T*>(tree);
719
1.11M
}
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.11M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
1.11M
  return dynamic_cast<T*>(tree);
719
1.11M
}
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.11M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
1.11M
  return dynamic_cast<T*>(tree);
719
1.11M
}
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.11M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
1.11M
  return dynamic_cast<T*>(tree);
719
1.11M
}
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.10M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
1.10M
  return dynamic_cast<T*>(tree);
719
1.10M
}
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.10M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
1.10M
  return dynamic_cast<T*>(tree);
719
1.10M
}
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
412k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
412k
  return dynamic_cast<T*>(tree);
719
412k
}
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
407k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
407k
  return dynamic_cast<T*>(tree);
719
407k
}
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
396k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
396k
  return dynamic_cast<T*>(tree);
719
396k
}
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
3.88k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
3.88k
  return dynamic_cast<T*>(tree);
719
3.88k
}
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
1.52k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
1.52k
  return dynamic_cast<T*>(tree);
719
1.52k
}
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
992
T* tree_as(antlr4::tree::ParseTree* tree) {
718
992
  return dynamic_cast<T*>(tree);
719
992
}
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
619
T* tree_as(antlr4::tree::ParseTree* tree) {
718
619
  return dynamic_cast<T*>(tree);
719
619
}
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
5.63M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
5.63M
  return dynamic_cast<T*>(tree);
719
5.63M
}
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
5.63M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
5.63M
  return dynamic_cast<T*>(tree);
719
5.63M
}
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
5.63M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
5.63M
  return dynamic_cast<T*>(tree);
719
5.63M
}
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
5.63M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
5.63M
  return dynamic_cast<T*>(tree);
719
5.63M
}
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
5.63M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
5.63M
  return dynamic_cast<T*>(tree);
719
5.63M
}
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
5.62M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
5.62M
  return dynamic_cast<T*>(tree);
719
5.62M
}
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
2.01M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
2.01M
  return dynamic_cast<T*>(tree);
719
2.01M
}
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
2.28M
T* tree_as(antlr4::tree::ParseTree* tree) {
718
2.28M
  return dynamic_cast<T*>(tree);
719
2.28M
}
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
122k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
122k
  return dynamic_cast<T*>(tree);
719
122k
}
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
122k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
122k
  return dynamic_cast<T*>(tree);
719
122k
}
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
2.24k
T* tree_as(antlr4::tree::ParseTree* tree) {
718
2.24k
  return dynamic_cast<T*>(tree);
719
2.24k
}
Unexecuted instantiation: parser.cc:antlr4::ParserRuleContext* google::api::expr::parser::(anonymous namespace)::tree_as<antlr4::ParserRuleContext, void>(antlr4::tree::ParseTree*)
720
721
2.75M
std::any ParserVisitor::visit(antlr4::tree::ParseTree* tree) {
722
2.75M
  ScopedIncrement inc(recursion_depth_);
723
2.75M
  if (recursion_depth_ > max_recursion_depth_) {
724
2.89k
    return ExprToAny(factory_.ReportError(
725
2.89k
        absl::StrFormat("Exceeded max recursion depth of %d when parsing.",
726
2.89k
                        max_recursion_depth_)));
727
2.89k
  }
728
2.75M
  tree = UnnestContext(tree);
729
2.75M
  if (auto* ctx = tree_as<CelParser::StartContext>(tree)) {
730
0
    return visitStart(ctx);
731
2.75M
  } else if (auto* ctx = tree_as<CelParser::ExprContext>(tree)) {
732
514
    return visitExpr(ctx);
733
2.75M
  } else if (auto* ctx = tree_as<CelParser::ConditionalAndContext>(tree)) {
734
130
    return visitConditionalAnd(ctx);
735
2.75M
  } else if (auto* ctx = tree_as<CelParser::ConditionalOrContext>(tree)) {
736
418
    return visitConditionalOr(ctx);
737
2.75M
  } else if (auto* ctx = tree_as<CelParser::RelationContext>(tree)) {
738
3.03k
    return visitRelation(ctx);
739
2.75M
  } else if (auto* ctx = tree_as<CelParser::CalcContext>(tree)) {
740
731k
    return visitCalc(ctx);
741
2.01M
  } else if (auto* ctx = tree_as<CelParser::LogicalNotContext>(tree)) {
742
774
    return visitLogicalNot(ctx);
743
2.01M
  } else if (auto* ctx = tree_as<CelParser::PrimaryExprContext>(tree)) {
744
1.88M
    return visitPrimaryExpr(ctx);
745
1.88M
  } else if (auto* ctx = tree_as<CelParser::MemberExprContext>(tree)) {
746
0
    return visitMemberExpr(ctx);
747
135k
  } else if (auto* ctx = tree_as<CelParser::SelectContext>(tree)) {
748
9.26k
    return visitSelect(ctx);
749
125k
  } else if (auto* ctx = tree_as<CelParser::MemberCallContext>(tree)) {
750
3.52k
    return visitMemberCall(ctx);
751
122k
  } else if (auto* ctx = tree_as<CelParser::MapInitializerListContext>(tree)) {
752
0
    return visitMapInitializerList(ctx);
753
122k
  } else if (auto* ctx = tree_as<CelParser::NegateContext>(tree)) {
754
119k
    return visitNegate(ctx);
755
119k
  } else if (auto* ctx = tree_as<CelParser::IndexContext>(tree)) {
756
840
    return visitIndex(ctx);
757
2.24k
  } else if (auto* ctx = tree_as<CelParser::UnaryContext>(tree)) {
758
1.86k
    return visitUnary(ctx);
759
1.86k
  } else if (auto* ctx = tree_as<CelParser::CreateListContext>(tree)) {
760
0
    return visitCreateList(ctx);
761
379
  } else if (auto* ctx = tree_as<CelParser::CreateMessageContext>(tree)) {
762
0
    return visitCreateMessage(ctx);
763
379
  } else if (auto* ctx = tree_as<CelParser::CreateMapContext>(tree)) {
764
0
    return visitCreateMap(ctx);
765
0
  }
766
767
379
  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
379
  return ExprToAny(factory_.ReportError("<<nil>> parsetree"));
774
379
}
775
776
1.88M
std::any ParserVisitor::visitPrimaryExpr(CelParser::PrimaryExprContext* pctx) {
777
1.88M
  CelParser::PrimaryContext* primary = pctx->primary();
778
1.88M
  if (auto* ctx = tree_as<CelParser::NestedContext>(primary)) {
779
0
    return visitNested(ctx);
780
1.88M
  } else if (auto* ctx = tree_as<CelParser::IdentContext>(primary)) {
781
766k
    return visitIdent(ctx);
782
1.11M
  } else if (auto* ctx = tree_as<CelParser::GlobalCallContext>(primary)) {
783
2.74k
    return visitGlobalCall(ctx);
784
1.11M
  } else if (auto* ctx = tree_as<CelParser::CreateListContext>(primary)) {
785
1.76k
    return visitCreateList(ctx);
786
1.11M
  } else if (auto* ctx = tree_as<CelParser::CreateMapContext>(primary)) {
787
1.44k
    return visitCreateMap(ctx);
788
1.10M
  } else if (auto* ctx = tree_as<CelParser::CreateMessageContext>(primary)) {
789
1.68k
    return visitCreateMessage(ctx);
790
1.10M
  } else if (auto* ctx = tree_as<CelParser::ConstantLiteralContext>(primary)) {
791
1.10M
    return visitConstantLiteral(ctx);
792
1.10M
  }
793
388
  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
388
    return ExprToAny(factory_.NewUnspecified(factory_.NextId({})));
798
388
  }
799
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(pctx),
800
0
                                        "invalid primary expression"));
801
388
}
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
2.75M
    antlr4::tree::ParseTree* tree) {
824
2.75M
  antlr4::tree::ParseTree* last = nullptr;
825
3.01M
  while (tree != last) {
826
2.88M
    last = tree;
827
828
2.88M
    if (auto* ctx = tree_as<CelParser::StartContext>(tree)) {
829
3.70k
      tree = ctx->expr();
830
3.70k
    }
831
832
2.88M
    if (auto* ctx = tree_as<CelParser::ExprContext>(tree)) {
833
790k
      if (ctx->op != nullptr) {
834
514
        return ctx;
835
514
      }
836
789k
      tree = ctx->e;
837
789k
    }
838
839
2.88M
    if (auto* ctx = tree_as<CelParser::ConditionalOrContext>(tree)) {
840
1.11M
      if (!ctx->ops.empty()) {
841
418
        return ctx;
842
418
      }
843
1.11M
      tree = ctx->e;
844
1.11M
    }
845
846
2.88M
    if (auto* ctx = tree_as<CelParser::ConditionalAndContext>(tree)) {
847
1.13M
      if (!ctx->ops.empty()) {
848
130
        return ctx;
849
130
      }
850
1.13M
      tree = ctx->e;
851
1.13M
    }
852
853
2.88M
    if (auto* ctx = tree_as<CelParser::RelationContext>(tree)) {
854
1.15M
      if (ctx->calc() == nullptr) {
855
3.03k
        return ctx;
856
3.03k
      }
857
1.15M
      tree = ctx->calc();
858
1.15M
    }
859
860
2.87M
    if (auto* ctx = tree_as<CelParser::CalcContext>(tree)) {
861
2.61M
      if (ctx->unary() == nullptr) {
862
731k
        return ctx;
863
731k
      }
864
1.88M
      tree = ctx->unary();
865
1.88M
    }
866
867
2.14M
    if (auto* ctx = tree_as<CelParser::MemberExprContext>(tree)) {
868
1.76M
      tree = ctx->member();
869
1.76M
    }
870
871
2.14M
    if (auto* ctx = tree_as<CelParser::PrimaryExprContext>(tree)) {
872
1.88M
      if (auto* nested = tree_as<CelParser::NestedContext>(ctx->primary())) {
873
509
        tree = nested->e;
874
1.88M
      } else {
875
1.88M
        return ctx;
876
1.88M
      }
877
1.88M
    }
878
2.14M
  }
879
880
135k
  return tree;
881
2.75M
}
882
883
324k
std::any ParserVisitor::visitExpr(CelParser::ExprContext* ctx) {
884
324k
  auto result = ExprFromAny(visit(ctx->e));
885
324k
  if (!ctx->op) {
886
324k
    return ExprToAny(std::move(result));
887
324k
  }
888
576
  std::vector<Expr> arguments;
889
576
  arguments.reserve(3);
890
576
  arguments.push_back(std::move(result));
891
576
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
892
576
  arguments.push_back(ExprFromAny(visit(ctx->e1)));
893
576
  arguments.push_back(ExprFromAny(visit(ctx->e2)));
894
895
576
  return ExprToAny(
896
576
      factory_.NewCall(op_id, CelOperator::CONDITIONAL, std::move(arguments)));
897
324k
}
898
899
std::any ParserVisitor::visitConditionalOr(
900
418
    CelParser::ConditionalOrContext* ctx) {
901
418
  auto result = ExprFromAny(visit(ctx->e));
902
418
  if (ctx->ops.empty()) {
903
0
    return ExprToAny(std::move(result));
904
0
  }
905
418
  ExpressionBalancer b(factory_, CelOperator::LOGICAL_OR, std::move(result));
906
18.6k
  for (size_t i = 0; i < ctx->ops.size(); ++i) {
907
18.2k
    auto op = ctx->ops[i];
908
18.2k
    if (i >= ctx->e1.size()) {
909
0
      return ExprToAny(
910
0
          factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
911
0
                               "unexpected character, wanted '||'"));
912
0
    }
913
18.2k
    auto next = ExprFromAny(visit(ctx->e1[i]));
914
18.2k
    int64_t op_id = factory_.NextId(SourceRangeFromToken(op));
915
18.2k
    b.AddTerm(op_id, std::move(next));
916
18.2k
  }
917
418
  return ExprToAny(b.Balance());
918
418
}
919
920
std::any ParserVisitor::visitConditionalAnd(
921
130
    CelParser::ConditionalAndContext* ctx) {
922
130
  auto result = ExprFromAny(visit(ctx->e));
923
130
  if (ctx->ops.empty()) {
924
0
    return ExprToAny(std::move(result));
925
0
  }
926
130
  ExpressionBalancer b(factory_, CelOperator::LOGICAL_AND, std::move(result));
927
19.8k
  for (size_t i = 0; i < ctx->ops.size(); ++i) {
928
19.6k
    auto op = ctx->ops[i];
929
19.6k
    if (i >= ctx->e1.size()) {
930
0
      return ExprToAny(
931
0
          factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
932
0
                               "unexpected character, wanted '&&'"));
933
0
    }
934
19.6k
    auto next = ExprFromAny(visit(ctx->e1[i]));
935
19.6k
    int64_t op_id = factory_.NextId(SourceRangeFromToken(op));
936
19.6k
    b.AddTerm(op_id, std::move(next));
937
19.6k
  }
938
130
  return ExprToAny(b.Balance());
939
130
}
940
941
3.03k
std::any ParserVisitor::visitRelation(CelParser::RelationContext* ctx) {
942
3.03k
  if (ctx->calc()) {
943
0
    return visit(ctx->calc());
944
0
  }
945
3.03k
  std::string op_text;
946
3.03k
  if (ctx->op) {
947
3.03k
    op_text = ctx->op->getText();
948
3.03k
  }
949
3.03k
  auto op = ReverseLookupOperator(op_text);
950
3.03k
  if (op) {
951
3.03k
    auto lhs = ExprFromAny(visit(ctx->relation(0)));
952
3.03k
    int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
953
3.03k
    auto rhs = ExprFromAny(visit(ctx->relation(1)));
954
3.03k
    return ExprToAny(
955
3.03k
        GlobalCallOrMacro(op_id, *op, std::move(lhs), std::move(rhs)));
956
3.03k
  }
957
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
958
0
                                        "operator not found"));
959
3.03k
}
960
961
731k
std::any ParserVisitor::visitCalc(CelParser::CalcContext* ctx) {
962
731k
  if (ctx->unary()) {
963
0
    return visit(ctx->unary());
964
0
  }
965
731k
  std::string op_text;
966
731k
  if (ctx->op) {
967
731k
    op_text = ctx->op->getText();
968
731k
  }
969
731k
  auto op = ReverseLookupOperator(op_text);
970
731k
  if (op) {
971
731k
    auto lhs = ExprFromAny(visit(ctx->calc(0)));
972
731k
    int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
973
731k
    auto rhs = ExprFromAny(visit(ctx->calc(1)));
974
731k
    return ExprToAny(
975
731k
        GlobalCallOrMacro(op_id, *op, std::move(lhs), std::move(rhs)));
976
731k
  }
977
0
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
978
0
                                        "operator not found"));
979
731k
}
980
981
1.86k
std::any ParserVisitor::visitUnary(CelParser::UnaryContext* ctx) {
982
1.86k
  return ExprToAny(factory_.NewStringConst(
983
1.86k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)), "<<error>>"));
984
1.86k
}
985
986
774
std::any ParserVisitor::visitLogicalNot(CelParser::LogicalNotContext* ctx) {
987
774
  if (ctx->ops.size() % 2 == 0) {
988
171
    return visit(ctx->member());
989
171
  }
990
603
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->ops[0]));
991
603
  auto target = ExprFromAny(visit(ctx->member()));
992
603
  return ExprToAny(
993
603
      GlobalCallOrMacro(op_id, CelOperator::LOGICAL_NOT, std::move(target)));
994
774
}
995
996
119k
std::any ParserVisitor::visitNegate(CelParser::NegateContext* ctx) {
997
119k
  if (ctx->ops.size() % 2 == 0) {
998
4.94k
    return visit(ctx->member());
999
4.94k
  }
1000
114k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->ops[0]));
1001
114k
  auto target = ExprFromAny(visit(ctx->member()));
1002
114k
  return ExprToAny(
1003
114k
      GlobalCallOrMacro(op_id, CelOperator::NEGATE, std::move(target)));
1004
119k
}
1005
1006
std::string ParserVisitor::NormalizeIdentifier(
1007
12.0k
    CelParser::EscapeIdentContext* ctx) {
1008
12.0k
  if (auto* raw_id = tree_as<CelParser::SimpleIdentifierContext>(ctx); raw_id) {
1009
11.8k
    return raw_id->id->getText();
1010
11.8k
  }
1011
175
  if (auto* escaped_id = tree_as<CelParser::EscapedIdentifierContext>(ctx);
1012
175
      escaped_id) {
1013
30
    if (!enable_quoted_identifiers_) {
1014
30
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1015
30
                           "unsupported syntax '`'");
1016
30
    }
1017
30
    auto escaped_id_text = escaped_id->id->getText();
1018
30
    return escaped_id_text.substr(1, escaped_id_text.size() - 2);
1019
30
  }
1020
1021
  // Fallthrough might occur if the parser is in an error state.
1022
145
  return "";
1023
175
}
1024
1025
9.26k
std::any ParserVisitor::visitSelect(CelParser::SelectContext* ctx) {
1026
9.26k
  auto operand = ExprFromAny(visit(ctx->member()));
1027
  // Handle the error case where no valid identifier is specified.
1028
9.26k
  if (!ctx->id || !ctx->op) {
1029
0
    return ExprToAny(factory_.NewUnspecified(
1030
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1031
0
  }
1032
9.26k
  auto id = NormalizeIdentifier(ctx->id);
1033
9.26k
  if (ctx->opt != nullptr) {
1034
1.47k
    if (!enable_optional_syntax_) {
1035
1.47k
      return ExprToAny(factory_.ReportError(
1036
1.47k
          SourceRangeFromParserRuleContext(ctx), "unsupported syntax '.?'"));
1037
1.47k
    }
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
1.47k
  }
1046
7.78k
  return ExprToAny(
1047
7.78k
      factory_.NewSelect(factory_.NextId(SourceRangeFromToken(ctx->op)),
1048
7.78k
                         std::move(operand), std::move(id)));
1049
9.26k
}
1050
1051
3.52k
std::any ParserVisitor::visitMemberCall(CelParser::MemberCallContext* ctx) {
1052
3.52k
  auto operand = ExprFromAny(visit(ctx->member()));
1053
  // Handle the error case where no valid identifier is specified.
1054
3.52k
  if (!ctx->id) {
1055
0
    return ExprToAny(factory_.NewUnspecified(
1056
0
        factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1057
0
  }
1058
3.52k
  auto id = ctx->id->getText();
1059
3.52k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->open));
1060
3.52k
  auto args = visitList(ctx->args);
1061
3.52k
  return ExprToAny(
1062
3.52k
      ReceiverCallOrMacroImpl(op_id, id, std::move(operand), std::move(args)));
1063
3.52k
}
1064
1065
840
std::any ParserVisitor::visitIndex(CelParser::IndexContext* ctx) {
1066
840
  auto target = ExprFromAny(visit(ctx->member()));
1067
840
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1068
840
  auto index = ExprFromAny(visit(ctx->index));
1069
840
  if (!enable_optional_syntax_ && ctx->opt != nullptr) {
1070
158
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1071
158
                                          "unsupported syntax '.?'"));
1072
158
  }
1073
682
  return ExprToAny(GlobalCallOrMacro(
1074
682
      op_id, ctx->opt != nullptr ? "_[?_]" : CelOperator::INDEX,
1075
682
      std::move(target), std::move(index)));
1076
840
}
1077
1078
std::any ParserVisitor::visitCreateMessage(
1079
1.68k
    CelParser::CreateMessageContext* ctx) {
1080
1.68k
  std::vector<std::string> parts;
1081
1.68k
  parts.reserve(ctx->ids.size());
1082
22.1k
  for (const auto* id : ctx->ids) {
1083
22.1k
    parts.push_back(id->getText());
1084
22.1k
  }
1085
1.68k
  std::string name;
1086
1.68k
  if (ctx->leadingDot) {
1087
994
    name.push_back('.');
1088
994
    name.append(absl::StrJoin(parts, "."));
1089
994
  } else {
1090
690
    name = absl::StrJoin(parts, ".");
1091
690
  }
1092
1.68k
  int64_t obj_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1093
1.68k
  std::vector<StructExprField> fields;
1094
1.68k
  if (ctx->entries) {
1095
230
    fields = visitFields(ctx->entries);
1096
230
  }
1097
1.68k
  return ExprToAny(
1098
1.68k
      factory_.NewStruct(obj_id, std::move(name), std::move(fields)));
1099
1.68k
}
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
230
    CelParser::FieldInitializerListContext* ctx) {
1109
230
  std::vector<StructExprField> res;
1110
230
  if (!ctx || ctx->fields.empty()) {
1111
0
    return res;
1112
0
  }
1113
1114
230
  res.reserve(ctx->fields.size());
1115
3.04k
  for (size_t i = 0; i < ctx->fields.size(); ++i) {
1116
2.84k
    if (i >= ctx->cols.size() || i >= ctx->values.size()) {
1117
      // This is the result of a syntax error detected elsewhere.
1118
38
      return res;
1119
38
    }
1120
2.81k
    auto* f = ctx->fields[i];
1121
2.81k
    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
2.81k
    std::string id = NormalizeIdentifier(f->escapeIdent());
1128
1129
2.81k
    int64_t init_id = factory_.NextId(SourceRangeFromToken(ctx->cols[i]));
1130
2.81k
    if (!enable_optional_syntax_ && f->opt) {
1131
32
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1132
32
                           "unsupported syntax '?'");
1133
32
      continue;
1134
32
    }
1135
2.77k
    auto value = ExprFromAny(visit(ctx->values[i]));
1136
2.77k
    res.push_back(factory_.NewStructField(init_id, std::move(id),
1137
2.77k
                                          std::move(value), f->opt != nullptr));
1138
2.77k
  }
1139
1140
192
  return res;
1141
230
}
1142
1143
766k
std::any ParserVisitor::visitIdent(CelParser::IdentContext* ctx) {
1144
766k
  std::string ident_name;
1145
766k
  if (ctx->leadingDot) {
1146
796
    ident_name = ".";
1147
796
  }
1148
766k
  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
766k
  if (cel::internal::LexisIsReserved(ctx->id->getText())) {
1154
226
    return ExprToAny(factory_.ReportError(
1155
226
        SourceRangeFromParserRuleContext(ctx),
1156
226
        absl::StrFormat("reserved identifier: %s", ctx->id->getText())));
1157
226
  }
1158
1159
766k
  ident_name += ctx->id->getText();
1160
1161
766k
  return ExprToAny(factory_.NewIdent(
1162
766k
      factory_.NextId(SourceRangeFromToken(ctx->id)), std::move(ident_name)));
1163
766k
}
1164
1165
2.74k
std::any ParserVisitor::visitGlobalCall(CelParser::GlobalCallContext* ctx) {
1166
2.74k
  std::string ident_name;
1167
2.74k
  if (ctx->leadingDot) {
1168
160
    ident_name = ".";
1169
160
  }
1170
2.74k
  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
2.74k
  if (cel::internal::LexisIsReserved(ctx->id->getText())) {
1176
4
    return ExprToAny(factory_.ReportError(
1177
4
        SourceRangeFromParserRuleContext(ctx),
1178
4
        absl::StrFormat("reserved identifier: %s", ctx->id->getText())));
1179
4
  }
1180
1181
2.74k
  ident_name += ctx->id->getText();
1182
1183
2.74k
  int64_t op_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1184
2.74k
  auto args = visitList(ctx->args);
1185
2.74k
  return ExprToAny(
1186
2.74k
      GlobalCallOrMacroImpl(op_id, std::move(ident_name), std::move(args)));
1187
2.74k
}
1188
1189
0
std::any ParserVisitor::visitNested(CelParser::NestedContext* ctx) {
1190
0
  return visit(ctx->e);
1191
0
}
1192
1193
1.76k
std::any ParserVisitor::visitCreateList(CelParser::CreateListContext* ctx) {
1194
1.76k
  int64_t list_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1195
1.76k
  auto elems = visitList(ctx->elems);
1196
1.76k
  return ExprToAny(factory_.NewList(list_id, std::move(elems)));
1197
1.76k
}
1198
1199
std::vector<ListExprElement> ParserVisitor::visitList(
1200
1.76k
    CelParser::ListInitContext* ctx) {
1201
1.76k
  std::vector<ListExprElement> rv;
1202
1.76k
  if (!ctx) return rv;
1203
1.43k
  rv.reserve(ctx->elems.size());
1204
278k
  for (size_t i = 0; i < ctx->elems.size(); ++i) {
1205
277k
    auto* expr_ctx = ctx->elems[i];
1206
277k
    if (expr_ctx == nullptr) {
1207
0
      return rv;
1208
0
    }
1209
277k
    if (!enable_optional_syntax_ && expr_ctx->opt != nullptr) {
1210
91
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1211
91
                           "unsupported syntax '?'");
1212
91
      rv.push_back(factory_.NewListElement(factory_.NewUnspecified(0), false));
1213
91
      continue;
1214
91
    }
1215
277k
    rv.push_back(factory_.NewListElement(ExprFromAny(visitExpr(expr_ctx->e)),
1216
277k
                                         expr_ctx->opt != nullptr));
1217
277k
  }
1218
1.43k
  return rv;
1219
1.43k
}
1220
1221
6.26k
std::vector<Expr> ParserVisitor::visitList(CelParser::ExprListContext* ctx) {
1222
6.26k
  std::vector<Expr> rv;
1223
6.26k
  if (!ctx) return rv;
1224
5.31k
  std::transform(ctx->e.begin(), ctx->e.end(), std::back_inserter(rv),
1225
47.0k
                 [this](CelParser::ExprContext* expr_ctx) {
1226
47.0k
                   return ExprFromAny(visitExpr(expr_ctx));
1227
47.0k
                 });
1228
5.31k
  return rv;
1229
6.26k
}
1230
1231
1.44k
std::any ParserVisitor::visitCreateMap(CelParser::CreateMapContext* ctx) {
1232
1.44k
  int64_t struct_id = factory_.NextId(SourceRangeFromToken(ctx->op));
1233
1.44k
  std::vector<MapExprEntry> entries;
1234
1.44k
  if (ctx->entries) {
1235
958
    entries = visitEntries(ctx->entries);
1236
958
  }
1237
1.44k
  return ExprToAny(factory_.NewMap(struct_id, std::move(entries)));
1238
1.44k
}
1239
1240
std::any ParserVisitor::visitConstantLiteral(
1241
1.10M
    CelParser::ConstantLiteralContext* clctx) {
1242
1.10M
  CelParser::LiteralContext* literal = clctx->literal();
1243
1.10M
  if (auto* ctx = tree_as<CelParser::IntContext>(literal)) {
1244
695k
    return visitInt(ctx);
1245
695k
  } else if (auto* ctx = tree_as<CelParser::UintContext>(literal)) {
1246
4.87k
    return visitUint(ctx);
1247
407k
  } else if (auto* ctx = tree_as<CelParser::DoubleContext>(literal)) {
1248
10.6k
    return visitDouble(ctx);
1249
396k
  } else if (auto* ctx = tree_as<CelParser::StringContext>(literal)) {
1250
392k
    return visitString(ctx);
1251
392k
  } else if (auto* ctx = tree_as<CelParser::BytesContext>(literal)) {
1252
2.35k
    return visitBytes(ctx);
1253
2.35k
  } else if (auto* ctx = tree_as<CelParser::BoolFalseContext>(literal)) {
1254
530
    return visitBoolFalse(ctx);
1255
992
  } else if (auto* ctx = tree_as<CelParser::BoolTrueContext>(literal)) {
1256
373
    return visitBoolTrue(ctx);
1257
619
  } else if (auto* ctx = tree_as<CelParser::NullContext>(literal)) {
1258
466
    return visitNull(ctx);
1259
466
  }
1260
153
  return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(clctx),
1261
153
                                        "invalid constant literal expression"));
1262
1.10M
}
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
958
    CelParser::MapInitializerListContext* ctx) {
1272
958
  std::vector<MapExprEntry> res;
1273
958
  if (!ctx || ctx->keys.empty()) {
1274
0
    return res;
1275
0
  }
1276
1277
958
  res.reserve(ctx->cols.size());
1278
392k
  for (size_t i = 0; i < ctx->cols.size(); ++i) {
1279
391k
    auto id = factory_.NextId(SourceRangeFromToken(ctx->cols[i]));
1280
391k
    if (!enable_optional_syntax_ && ctx->keys[i]->opt) {
1281
29
      factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1282
29
                           "unsupported syntax '?'");
1283
29
      res.push_back(factory_.NewMapEntry(0, factory_.NewUnspecified(0),
1284
29
                                         factory_.NewUnspecified(0), false));
1285
29
      continue;
1286
29
    }
1287
391k
    auto key = ExprFromAny(visit(ctx->keys[i]->e));
1288
391k
    auto value = ExprFromAny(visit(ctx->values[i]));
1289
391k
    res.push_back(factory_.NewMapEntry(id, std::move(key), std::move(value),
1290
391k
                                       ctx->keys[i]->opt != nullptr));
1291
391k
  }
1292
958
  return res;
1293
958
}
1294
1295
695k
std::any ParserVisitor::visitInt(CelParser::IntContext* ctx) {
1296
695k
  std::string value;
1297
695k
  if (ctx->sign) {
1298
5.25k
    value = ctx->sign->getText();
1299
5.25k
  }
1300
695k
  value += ctx->tok->getText();
1301
695k
  int64_t int_value;
1302
695k
  if (absl::StartsWith(ctx->tok->getText(), "0x")) {
1303
896
    if (absl::SimpleHexAtoi(value, &int_value)) {
1304
401
      return ExprToAny(factory_.NewIntConst(
1305
401
          factory_.NextId(SourceRangeFromParserRuleContext(ctx)), int_value));
1306
495
    } else {
1307
495
      return ExprToAny(factory_.ReportError(
1308
495
          SourceRangeFromParserRuleContext(ctx), "invalid hex int literal"));
1309
495
    }
1310
896
  }
1311
694k
  if (absl::SimpleAtoi(value, &int_value)) {
1312
692k
    return ExprToAny(factory_.NewIntConst(
1313
692k
        factory_.NextId(SourceRangeFromParserRuleContext(ctx)), int_value));
1314
692k
  } else {
1315
1.78k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1316
1.78k
                                          "invalid int literal"));
1317
1.78k
  }
1318
694k
}
1319
1320
4.87k
std::any ParserVisitor::visitUint(CelParser::UintContext* ctx) {
1321
4.87k
  std::string value = ctx->tok->getText();
1322
  // trim the 'u' designator included in the uint literal.
1323
4.87k
  if (!value.empty()) {
1324
4.87k
    value.resize(value.size() - 1);
1325
4.87k
  }
1326
4.87k
  uint64_t uint_value;
1327
4.87k
  if (absl::StartsWith(ctx->tok->getText(), "0x")) {
1328
3.22k
    if (absl::SimpleHexAtoi(value, &uint_value)) {
1329
811
      return ExprToAny(factory_.NewUintConst(
1330
811
          factory_.NextId(SourceRangeFromParserRuleContext(ctx)), uint_value));
1331
2.41k
    } else {
1332
2.41k
      return ExprToAny(factory_.ReportError(
1333
2.41k
          SourceRangeFromParserRuleContext(ctx), "invalid hex uint literal"));
1334
2.41k
    }
1335
3.22k
  }
1336
1.64k
  if (absl::SimpleAtoi(value, &uint_value)) {
1337
903
    return ExprToAny(factory_.NewUintConst(
1338
903
        factory_.NextId(SourceRangeFromParserRuleContext(ctx)), uint_value));
1339
903
  } else {
1340
743
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1341
743
                                          "invalid uint literal"));
1342
743
  }
1343
1.64k
}
1344
1345
10.6k
std::any ParserVisitor::visitDouble(CelParser::DoubleContext* ctx) {
1346
10.6k
  std::string value;
1347
10.6k
  if (ctx->sign) {
1348
932
    value = ctx->sign->getText();
1349
932
  }
1350
10.6k
  value += ctx->tok->getText();
1351
10.6k
  double double_value;
1352
10.6k
  if (absl::SimpleAtod(value, &double_value)) {
1353
10.6k
    return ExprToAny(factory_.NewDoubleConst(
1354
10.6k
        factory_.NextId(SourceRangeFromParserRuleContext(ctx)), double_value));
1355
10.6k
  } else {
1356
0
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1357
0
                                          "invalid double literal"));
1358
0
  }
1359
10.6k
}
1360
1361
392k
std::any ParserVisitor::visitString(CelParser::StringContext* ctx) {
1362
392k
  auto status_or_value = cel::internal::ParseStringLiteral(ctx->tok->getText());
1363
392k
  if (!status_or_value.ok()) {
1364
987
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1365
987
                                          status_or_value.status().message()));
1366
987
  }
1367
391k
  return ExprToAny(factory_.NewStringConst(
1368
391k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)),
1369
391k
      std::move(status_or_value).value()));
1370
392k
}
1371
1372
2.35k
std::any ParserVisitor::visitBytes(CelParser::BytesContext* ctx) {
1373
2.35k
  auto status_or_value = cel::internal::ParseBytesLiteral(ctx->tok->getText());
1374
2.35k
  if (!status_or_value.ok()) {
1375
1.00k
    return ExprToAny(factory_.ReportError(SourceRangeFromParserRuleContext(ctx),
1376
1.00k
                                          status_or_value.status().message()));
1377
1.00k
  }
1378
1.35k
  return ExprToAny(factory_.NewBytesConst(
1379
1.35k
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)),
1380
1.35k
      std::move(status_or_value).value()));
1381
2.35k
}
1382
1383
373
std::any ParserVisitor::visitBoolTrue(CelParser::BoolTrueContext* ctx) {
1384
373
  return ExprToAny(factory_.NewBoolConst(
1385
373
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)), true));
1386
373
}
1387
1388
530
std::any ParserVisitor::visitBoolFalse(CelParser::BoolFalseContext* ctx) {
1389
530
  return ExprToAny(factory_.NewBoolConst(
1390
530
      factory_.NextId(SourceRangeFromParserRuleContext(ctx)), false));
1391
530
}
1392
1393
466
std::any ParserVisitor::visitNull(CelParser::NullContext* ctx) {
1394
466
  return ExprToAny(factory_.NewNullConst(
1395
466
      factory_.NextId(SourceRangeFromParserRuleContext(ctx))));
1396
466
}
1397
1398
1.32k
cel::SourceInfo ParserVisitor::GetSourceInfo() {
1399
1.32k
  cel::SourceInfo source_info;
1400
1.32k
  source_info.set_location(std::string(source_.description()));
1401
1.71M
  for (const auto& positions : factory_.positions()) {
1402
1.71M
    source_info.mutable_positions().insert(
1403
1.71M
        std::pair{positions.first, positions.second.begin});
1404
1.71M
  }
1405
1.32k
  source_info.mutable_line_offsets().reserve(source_.line_offsets().size());
1406
1.28M
  for (const auto& line_offset : source_.line_offsets()) {
1407
1.28M
    source_info.mutable_line_offsets().push_back(line_offset);
1408
1.28M
  }
1409
1410
1.32k
  source_info.mutable_macro_calls() = factory_.release_macro_calls();
1411
1.32k
  return source_info;
1412
1.32k
}
1413
1414
1.32k
EnrichedSourceInfo ParserVisitor::enriched_source_info() const {
1415
1.32k
  std::map<int64_t, std::pair<int32_t, int32_t>> offsets;
1416
1.71M
  for (const auto& positions : factory_.positions()) {
1417
1.71M
    offsets.insert(
1418
1.71M
        std::pair{positions.first,
1419
1.71M
                  std::pair{positions.second.begin, positions.second.end - 1}});
1420
1.71M
  }
1421
1.32k
  return EnrichedSourceInfo(std::move(offsets));
1422
1.32k
}
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
1.78M
                                std::exception_ptr e) {
1428
1.78M
  cel::SourceRange range;
1429
1.78M
  if (auto position = source_.GetPosition(cel::SourceLocation{
1430
1.78M
          static_cast<int32_t>(line), static_cast<int32_t>(col)});
1431
1.78M
      position) {
1432
1.78M
    range.begin = *position;
1433
1.78M
  }
1434
1.78M
  factory_.ReportError(range, absl::StrCat("Syntax error: ", msg));
1435
1.78M
}
1436
1437
4.20k
bool ParserVisitor::HasErrored() const { return factory_.HasErrors(); }
1438
1439
2.87k
std::string ParserVisitor::ErrorMessage() { return factory_.ErrorMessage(); }
1440
1441
Expr ParserVisitor::GlobalCallOrMacroImpl(int64_t expr_id,
1442
                                          absl::string_view function,
1443
853k
                                          std::vector<Expr> args) {
1444
853k
  if (auto macro = macro_registry_.FindMacro(function, args.size(), false);
1445
853k
      macro) {
1446
1.60k
    std::vector<Expr> macro_args;
1447
1.60k
    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
1.60k
    factory_.BeginMacro(factory_.GetSourceRange(expr_id));
1454
1.60k
    auto expr = macro->Expand(factory_, absl::nullopt, absl::MakeSpan(args));
1455
1.60k
    factory_.EndMacro();
1456
1.60k
    if (expr) {
1457
1.60k
      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
1.60k
      factory_.EraseId(expr_id);
1463
1.60k
      return std::move(*expr);
1464
1.60k
    }
1465
1.60k
  }
1466
1467
851k
  return factory_.NewCall(expr_id, function, std::move(args));
1468
853k
}
1469
1470
Expr ParserVisitor::ReceiverCallOrMacroImpl(int64_t expr_id,
1471
                                            absl::string_view function,
1472
                                            Expr target,
1473
3.52k
                                            std::vector<Expr> args) {
1474
3.52k
  if (auto macro = macro_registry_.FindMacro(function, args.size(), true);
1475
3.52k
      macro) {
1476
1.87k
    Expr macro_target;
1477
1.87k
    std::vector<Expr> macro_args;
1478
1.87k
    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
1.87k
    factory_.BeginMacro(factory_.GetSourceRange(expr_id));
1486
1.87k
    auto expr = macro->Expand(factory_, std::ref(target), absl::MakeSpan(args));
1487
1.87k
    factory_.EndMacro();
1488
1.87k
    if (expr) {
1489
1.87k
      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
1.87k
      factory_.EraseId(expr_id);
1495
1.87k
      return std::move(*expr);
1496
1.87k
    }
1497
1.87k
  }
1498
1.65k
  return factory_.NewMemberCall(expr_id, function, std::move(target),
1499
1.65k
                                std::move(args));
1500
3.52k
}
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
4.20k
      : max_recursion_depth_(max_recursion_depth), recursion_depth_(0) {}
1542
0
  ~ExprRecursionListener() override {}
1543
1544
6.47M
  void visitTerminal(TerminalNode* node) override {};
1545
57.6k
  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
18.9M
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
18.9M
  if (ctx->getRuleIndex() == CelParser::RuleExpr) {
1559
1.15M
    if (recursion_depth_ > max_recursion_depth_) {
1560
6
      throw ParseCancellationException(
1561
6
          absl::StrFormat("Expression recursion limit exceeded. limit: %d",
1562
6
                          max_recursion_depth_));
1563
6
    }
1564
1.15M
    recursion_depth_++;
1565
1.15M
  }
1566
18.9M
}
1567
1568
18.9M
void ExprRecursionListener::exitEveryRule(ParserRuleContext* ctx) {
1569
18.9M
  if (ctx->getRuleIndex() == CelParser::RuleExpr) {
1570
1.15M
    recursion_depth_--;
1571
1.15M
  }
1572
18.9M
}
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
4.20k
      : recovery_limit_(recovery_limit),
1581
4.20k
        recovery_attempts_(0),
1582
4.20k
        recovery_token_lookahead_limit_(recovery_token_lookahead_limit) {}
1583
1584
9.13k
  void recover(Parser* recognizer, std::exception_ptr e) override {
1585
9.13k
    checkRecoveryLimit(recognizer);
1586
9.13k
    DefaultErrorStrategy::recover(recognizer, e);
1587
9.13k
  }
1588
1589
6.24k
  Token* recoverInline(Parser* recognizer) override {
1590
6.24k
    checkRecoveryLimit(recognizer);
1591
6.24k
    return DefaultErrorStrategy::recoverInline(recognizer);
1592
6.24k
  }
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
9.74k
  void consumeUntil(Parser* recognizer, const IntervalSet& set) override {
1600
9.74k
    size_t ttype = recognizer->getInputStream()->LA(1);
1601
9.74k
    int recovery_search_depth = 0;
1602
61.2k
    while (ttype != Token::EOF && !set.contains(ttype) &&
1603
51.5k
           recovery_search_depth++ < recovery_token_lookahead_limit_) {
1604
51.4k
      recognizer->consume();
1605
51.4k
      ttype = recognizer->getInputStream()->LA(1);
1606
51.4k
    }
1607
    // Halt all parsing if the lookahead limit is reached during error recovery.
1608
9.74k
    if (recovery_search_depth == recovery_token_lookahead_limit_) {
1609
3
      throw ParseCancellationException("Unable to find a recovery token");
1610
3
    }
1611
9.74k
  }
1612
1613
 protected:
1614
13.5k
  std::string escapeWSAndQuote(const std::string& s) const override {
1615
13.5k
    std::string result;
1616
13.5k
    result.reserve(s.size() + 2);
1617
13.5k
    absl::StrAppend(&result, kSingleQuote, s, kSingleQuote);
1618
13.5k
    absl::StrReplaceAll(kStandardReplacements, &result);
1619
13.5k
    return result;
1620
13.5k
  }
1621
1622
 private:
1623
15.3k
  void checkRecoveryLimit(Parser* recognizer) {
1624
15.3k
    if (recovery_attempts_++ >= recovery_limit_) {
1625
483
      std::string too_many_errors =
1626
483
          absl::StrFormat("More than %d parse errors.", recovery_limit_);
1627
483
      recognizer->notifyErrorListeners(too_many_errors);
1628
483
      throw ParseCancellationException(too_many_errors);
1629
483
    }
1630
15.3k
  }
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
4.20k
                                      const ParserOptions& options) {
1646
4.20k
  try {
1647
4.20k
    CodePointStream input(source.content(), source.description());
1648
4.20k
    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
4.20k
    CelLexer lexer(&input);
1654
4.20k
    CommonTokenStream tokens(&lexer);
1655
4.20k
    CelParser parser(&tokens);
1656
4.20k
    ExprRecursionListener listener(options.max_recursion_depth);
1657
4.20k
    absl::string_view accu_var = cel::kAccumulatorVariableName;
1658
4.20k
    if (options.enable_hidden_accumulator_var) {
1659
4.20k
      accu_var = cel::kHiddenAccumulatorVariableName;
1660
4.20k
    }
1661
4.20k
    ParserVisitor visitor(source, options.max_recursion_depth, accu_var,
1662
4.20k
                          registry, options.add_macro_calls,
1663
4.20k
                          options.enable_optional_syntax,
1664
4.20k
                          options.enable_quoted_identifiers);
1665
1666
4.20k
    lexer.removeErrorListeners();
1667
4.20k
    parser.removeErrorListeners();
1668
4.20k
    lexer.addErrorListener(&visitor);
1669
4.20k
    parser.addErrorListener(&visitor);
1670
4.20k
    parser.addParseListener(&listener);
1671
1672
    // Limit the number of error recovery attempts to prevent bad expressions
1673
    // from consuming lots of cpu / memory.
1674
4.20k
    parser.setErrorHandler(std::make_shared<RecoveryLimitErrorStrategy>(
1675
4.20k
        options.error_recovery_limit,
1676
4.20k
        options.error_recovery_token_lookahead_limit));
1677
1678
4.20k
    Expr expr;
1679
4.20k
    try {
1680
4.20k
      expr = ExprFromAny(visitor.visit(parser.start()));
1681
4.20k
    } catch (const ParseCancellationException& e) {
1682
492
      if (visitor.HasErrored()) {
1683
489
        return absl::InvalidArgumentError(visitor.ErrorMessage());
1684
489
      }
1685
3
      return absl::CancelledError(e.what());
1686
492
    }
1687
1688
3.70k
    if (visitor.HasErrored()) {
1689
2.38k
      return absl::InvalidArgumentError(visitor.ErrorMessage());
1690
2.38k
    }
1691
1692
1.32k
    return {
1693
1.32k
        ParseResult{.expr = std::move(expr),
1694
1.32k
                    .source_info = visitor.GetSourceInfo(),
1695
1.32k
                    .enriched_source_info = visitor.enriched_source_info()}};
1696
3.70k
  } 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
4.20k
}
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
4.23k
                                 const ParserOptions& options) {
1826
4.23k
  std::vector<Macro> macros;
1827
4.23k
  if (!options.disable_standard_macros) {
1828
4.23k
    macros = Macro::AllMacros();
1829
4.23k
  }
1830
4.23k
  if (options.enable_optional_syntax) {
1831
0
    macros.push_back(cel::OptMapMacro());
1832
0
    macros.push_back(cel::OptFlatMapMacro());
1833
0
  }
1834
4.23k
  return ParseWithMacros(expression, macros, description, options);
1835
4.23k
}
1836
1837
absl::StatusOr<ParsedExpr> ParseWithMacros(absl::string_view expression,
1838
                                           const std::vector<Macro>& macros,
1839
                                           absl::string_view description,
1840
4.23k
                                           const ParserOptions& options) {
1841
4.23k
  CEL_ASSIGN_OR_RETURN(auto verbose_parsed_expr,
1842
1.32k
                       EnrichedParse(expression, macros, description, options));
1843
1.32k
  return verbose_parsed_expr.parsed_expr();
1844
4.23k
}
1845
1846
absl::StatusOr<VerboseParsedExpr> EnrichedParse(
1847
    absl::string_view expression, const std::vector<Macro>& macros,
1848
4.23k
    absl::string_view description, const ParserOptions& options) {
1849
4.23k
  CEL_ASSIGN_OR_RETURN(auto source,
1850
4.20k
                       cel::NewSource(expression, std::string(description)));
1851
4.20k
  cel::MacroRegistry macro_registry;
1852
4.20k
  CEL_RETURN_IF_ERROR(macro_registry.RegisterMacros(macros));
1853
4.20k
  return EnrichedParse(*source, macro_registry, options);
1854
4.20k
}
1855
1856
absl::StatusOr<VerboseParsedExpr> EnrichedParse(
1857
    const cel::Source& source, const cel::MacroRegistry& registry,
1858
4.20k
    const ParserOptions& options) {
1859
4.20k
  CEL_ASSIGN_OR_RETURN(ParseResult parse_result,
1860
1.32k
                       ParseImpl(source, registry, options));
1861
1.32k
  ParsedExpr parsed_expr;
1862
1.32k
  CEL_RETURN_IF_ERROR(cel::ast_internal::ExprToProto(
1863
1.32k
      parse_result.expr, parsed_expr.mutable_expr()));
1864
1865
1.32k
  CEL_RETURN_IF_ERROR(cel::ast_internal::SourceInfoToProto(
1866
1.32k
      parse_result.source_info, parsed_expr.mutable_source_info()));
1867
1.32k
  return VerboseParsedExpr(std::move(parsed_expr),
1868
1.32k
                           std::move(parse_result.enriched_source_info));
1869
1.32k
}
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