Coverage Report

Created: 2023-05-25 06:18

/proc/self/cwd/parser/source_factory.h
Line
Count
Source (jump to first uncovered line)
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
#ifndef THIRD_PARTY_CEL_CPP_PARSER_SOURCE_FACTORY_H_
16
#define THIRD_PARTY_CEL_CPP_PARSER_SOURCE_FACTORY_H_
17
18
#include <cstdint>
19
#include <string>
20
#include <utility>
21
#include <vector>
22
23
#include "google/api/expr/v1alpha1/syntax.pb.h"
24
#include "absl/strings/string_view.h"
25
#include "absl/types/optional.h"
26
#include "antlr4-runtime.h"
27
#include "parser/internal/CelParser.h"
28
29
namespace google::api::expr::parser {
30
31
using google::api::expr::v1alpha1::Expr;
32
33
class EnrichedSourceInfo {
34
 public:
35
  explicit EnrichedSourceInfo(
36
      std::map<int64_t, std::pair<int32_t, int32_t>> offsets)
37
2.50k
      : offsets_(std::move(offsets)) {}
38
39
0
  const std::map<int64_t, std::pair<int32_t, int32_t>>& offsets() const {
40
0
    return offsets_;
41
0
  }
42
43
 private:
44
  // A map between node_id and pair of start position and end position
45
  std::map<int64_t, std::pair<int32_t, int32_t>> offsets_;
46
};
47
48
// Provide tools to generate expressions during parsing.
49
// Keeps track of ID and source location information.
50
// Shares functionality with //third_party/cel/go/parser/helper.go
51
class SourceFactory {
52
 public:
53
  struct SourceLocation {
54
    SourceLocation(int32_t line, int32_t col, int32_t offset_end,
55
                   const std::vector<int32_t>& line_offsets)
56
6.20M
        : line(line), col(col), offset_end(offset_end) {
57
6.20M
      if (line == 1) {
58
5.82M
        offset = col;
59
5.82M
      } else if (line > 1) {
60
382k
        offset = line_offsets[line - 2] + col;
61
382k
      } else {
62
1.81k
        offset = -1;
63
1.81k
      }
64
6.20M
    }
65
    int32_t line;
66
    int32_t col;
67
    int32_t offset_end;
68
    int32_t offset;
69
  };
70
71
  struct Error {
72
    Error(std::string message, SourceLocation location)
73
112k
        : message(std::move(message)), location(location) {}
74
    std::string message;
75
    SourceLocation location;
76
  };
77
78
  enum QuantifierKind {
79
    QUANTIFIER_ALL,
80
    QUANTIFIER_EXISTS,
81
    QUANTIFIER_EXISTS_ONE
82
  };
83
84
  explicit SourceFactory(absl::string_view expression);
85
86
  int64_t Id(const antlr4::Token* token);
87
  int64_t Id(antlr4::ParserRuleContext* ctx);
88
  int64_t Id(const SourceLocation& location);
89
90
  int64_t NextMacroId(int64_t macro_id);
91
92
  const SourceLocation& GetSourceLocation(int64_t id) const;
93
94
  static const SourceLocation NoLocation();
95
96
  Expr NewExpr(int64_t id);
97
  Expr NewExpr(antlr4::ParserRuleContext* ctx);
98
  Expr NewExpr(const antlr4::Token* token);
99
  Expr NewGlobalCall(int64_t id, const std::string& function,
100
                     const std::vector<Expr>& args);
101
  Expr NewGlobalCallForMacro(int64_t macro_id, const std::string& function,
102
                             const std::vector<Expr>& args);
103
  Expr NewReceiverCall(int64_t id, const std::string& function,
104
                       const Expr& target, const std::vector<Expr>& args);
105
  Expr NewIdent(const antlr4::Token* token, const std::string& ident_name);
106
  Expr NewIdentForMacro(int64_t macro_id, const std::string& ident_name);
107
  Expr NewSelect(::cel_parser_internal::CelParser::SelectOrCallContext* ctx,
108
                 Expr& operand, const std::string& field);
109
  Expr NewSelectForMacro(int64_t macro_id, const Expr& operand,
110
                         const std::string& field);
111
  Expr NewPresenceTestForMacro(int64_t macro_id, const Expr& operand,
112
                               const std::string& field);
113
  Expr NewObject(int64_t obj_id, const std::string& type_name,
114
                 const std::vector<Expr::CreateStruct::Entry>& entries);
115
  Expr::CreateStruct::Entry NewObjectField(int64_t field_id,
116
                                           const std::string& field,
117
                                           const Expr& value);
118
  Expr NewComprehension(int64_t id, const std::string& iter_var,
119
                        const Expr& iter_range, const std::string& accu_var,
120
                        const Expr& accu_init, const Expr& condition,
121
                        const Expr& step, const Expr& result);
122
123
  Expr FoldForMacro(int64_t macro_id, const std::string& iter_var,
124
                    const Expr& iter_range, const std::string& accu_var,
125
                    const Expr& accu_init, const Expr& condition,
126
                    const Expr& step, const Expr& result);
127
  Expr NewQuantifierExprForMacro(QuantifierKind kind, int64_t macro_id,
128
                                 const Expr& target,
129
                                 const std::vector<Expr>& args);
130
  Expr NewFilterExprForMacro(int64_t macro_id, const Expr& target,
131
                             const std::vector<Expr>& args);
132
133
  Expr NewList(int64_t list_id, const std::vector<Expr>& elems);
134
  Expr NewListForMacro(int64_t macro_id, const std::vector<Expr>& elems);
135
  Expr NewMap(int64_t map_id,
136
              const std::vector<Expr::CreateStruct::Entry>& entries);
137
  Expr NewMapForMacro(int64_t macro_id, const Expr& target,
138
                      const std::vector<Expr>& args);
139
  Expr::CreateStruct::Entry NewMapEntry(int64_t entry_id, const Expr& key,
140
                                        const Expr& value);
141
  Expr NewLiteralInt(antlr4::ParserRuleContext* ctx, int64_t value);
142
  Expr NewLiteralIntForMacro(int64_t macro_id, int64_t value);
143
  Expr NewLiteralUint(antlr4::ParserRuleContext* ctx, uint64_t value);
144
  Expr NewLiteralDouble(antlr4::ParserRuleContext* ctx, double value);
145
  Expr NewLiteralString(antlr4::ParserRuleContext* ctx, const std::string& s);
146
  Expr NewLiteralBytes(antlr4::ParserRuleContext* ctx, const std::string& b);
147
  Expr NewLiteralBool(antlr4::ParserRuleContext* ctx, bool b);
148
  Expr NewLiteralBoolForMacro(int64_t macro_id, bool b);
149
  Expr NewLiteralNull(antlr4::ParserRuleContext* ctx);
150
151
  Expr ReportError(int64_t expr_id, absl::string_view msg);
152
  Expr ReportError(antlr4::ParserRuleContext* ctx, absl::string_view msg);
153
  Expr ReportError(int32_t line, int32_t col, absl::string_view msg);
154
  Expr ReportError(const SourceLocation& loc, absl::string_view msg);
155
156
  bool IsReserved(absl::string_view ident_name);
157
  google::api::expr::v1alpha1::SourceInfo source_info() const;
158
  EnrichedSourceInfo enriched_source_info() const;
159
9.21k
  const std::vector<Error>& errors() const { return errors_truncated_; }
160
  std::string ErrorMessage(absl::string_view description,
161
                           absl::string_view expression) const;
162
163
  Expr BuildArgForMacroCall(const Expr& expr);
164
  void AddMacroCall(int64_t macro_id, const Expr& target,
165
                    const std::vector<Expr>& args, std::string function);
166
167
 private:
168
  void CalcLineOffsets(absl::string_view expression);
169
  absl::optional<int32_t> FindLineOffset(int32_t line) const;
170
  std::string GetSourceLine(int32_t line, absl::string_view expression) const;
171
172
 private:
173
  int64_t next_id_;
174
  std::map<int64_t, SourceLocation> positions_;
175
  // Truncated at kMaxErrorsToReport.
176
  std::vector<Error> errors_truncated_;
177
  int64_t num_errors_;
178
  std::vector<int32_t> line_offsets_;
179
  std::map<int64_t, Expr> macro_calls_;
180
};
181
182
}  // namespace google::api::expr::parser
183
184
#endif  // THIRD_PARTY_CEL_CPP_PARSER_SOURCE_FACTORY_H_