Coverage Report

Created: 2026-09-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/parser/internal/ast_factory.cc
Line
Count
Source
1
// Copyright 2026 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/internal/ast_factory.h"
16
17
#include <cstddef>
18
#include <cstdint>
19
#include <optional>
20
#include <string>
21
#include <utility>
22
23
#include "absl/functional/function_ref.h"
24
#include "absl/status/status.h"
25
#include "absl/status/statusor.h"
26
#include "absl/strings/string_view.h"
27
#include "common/expr.h"
28
#include "internal/status_macros.h"
29
#include "parser/internal/ast_factory_interface.h"
30
#include "parser/macro.h"
31
32
namespace cel::parser_internal {
33
34
0
ListNodeBuilder<cel::Expr>::ListNodeBuilder(int64_t id) {
35
0
  expr_.set_id(id);
36
0
  expr_.mutable_list_expr();
37
0
}
38
39
ListNodeBuilder<cel::Expr>& ListNodeBuilder<cel::Expr>::Add(cel::Expr element,
40
0
                                                            bool optional) {
41
0
  cel::ListExpr& list_val = expr_.mutable_list_expr();
42
0
  cel::ListExprElement expr_element;
43
0
  expr_element.set_expr(std::move(element));
44
0
  expr_element.set_optional(optional);
45
0
  list_val.mutable_elements().push_back(std::move(expr_element));
46
0
  return *this;
47
0
}
48
49
0
cel::Expr ListNodeBuilder<cel::Expr>::Build() { return std::move(expr_); }
50
51
0
MapNodeBuilder<cel::Expr>::MapNodeBuilder(int64_t id) {
52
0
  expr_.set_id(id);
53
0
  expr_.mutable_map_expr();
54
0
}
55
56
MapNodeBuilder<cel::Expr>& MapNodeBuilder<cel::Expr>::Add(int64_t id,
57
                                                          cel::Expr key,
58
                                                          cel::Expr value,
59
0
                                                          bool optional) {
60
0
  cel::MapExpr& map_val = expr_.mutable_map_expr();
61
0
  cel::MapExprEntry entry;
62
0
  entry.set_id(id);
63
0
  entry.set_key(std::move(key));
64
0
  entry.set_value(std::move(value));
65
0
  entry.set_optional(optional);
66
0
  map_val.mutable_entries().push_back(std::move(entry));
67
0
  return *this;
68
0
}
69
70
0
cel::Expr MapNodeBuilder<cel::Expr>::Build() { return std::move(expr_); }
71
72
0
StructNodeBuilder<cel::Expr>::StructNodeBuilder(int64_t id, std::string name) {
73
0
  expr_.set_id(id);
74
0
  expr_.mutable_struct_expr().set_name(std::move(name));
75
0
}
76
77
StructNodeBuilder<cel::Expr>& StructNodeBuilder<cel::Expr>::Add(
78
0
    int64_t id, std::string name, cel::Expr value, bool optional) {
79
0
  cel::StructExpr& struct_val = expr_.mutable_struct_expr();
80
0
  cel::StructExprField field;
81
0
  field.set_id(id);
82
0
  field.set_name(std::move(name));
83
0
  field.set_value(std::move(value));
84
0
  field.set_optional(optional);
85
0
  struct_val.mutable_fields().push_back(std::move(field));
86
0
  return *this;
87
0
}
88
89
0
cel::Expr StructNodeBuilder<cel::Expr>::Build() { return std::move(expr_); }
90
91
0
int64_t AstFactoryInterface<cel::Expr>::GetId(const cel::Expr& expr) const {
92
0
  return expr.id();
93
0
}
94
95
0
bool AstFactoryInterface<cel::Expr>::IsEmpty(const cel::Expr& expr) const {
96
0
  return expr.id() == 0;
97
0
}
98
99
0
bool AstFactoryInterface<cel::Expr>::IsConst(const cel::Expr& expr) const {
100
0
  return expr.has_const_expr();
101
0
}
102
103
0
bool AstFactoryInterface<cel::Expr>::IsIdent(const cel::Expr& expr) const {
104
0
  return expr.has_ident_expr();
105
0
}
106
107
absl::string_view AstFactoryInterface<cel::Expr>::GetIdentName(
108
0
    const cel::Expr& expr) const {
109
0
  return expr.has_ident_expr() ? absl::string_view(expr.ident_expr().name())
110
0
                               : absl::string_view();
111
0
}
112
113
0
bool AstFactoryInterface<cel::Expr>::IsSelect(const cel::Expr& expr) const {
114
0
  return expr.has_select_expr();
115
0
}
116
117
bool AstFactoryInterface<cel::Expr>::IsPresenceTest(
118
0
    const cel::Expr& expr) const {
119
0
  return expr.has_select_expr() && expr.select_expr().test_only();
120
0
}
121
122
const cel::Expr* AstFactoryInterface<cel::Expr>::GetSelectOperand(
123
0
    const cel::Expr& expr) const {
124
0
  return expr.has_select_expr() ? &expr.select_expr().operand() : nullptr;
125
0
}
126
127
absl::string_view AstFactoryInterface<cel::Expr>::GetSelectField(
128
0
    const cel::Expr& expr) const {
129
0
  return expr.has_select_expr() ? absl::string_view(expr.select_expr().field())
130
0
                                : absl::string_view();
131
0
}
132
133
absl::StatusOr<cel::Expr> AstFactoryInterface<cel::Expr>::CopyAndReplace(
134
    const cel::Expr& expr,
135
    absl::FunctionRef<std::optional<cel::Expr>(const cel::Expr&)> replacer,
136
0
    int max_recursion_depth) const {
137
0
  if (max_recursion_depth <= 0) {
138
0
    return absl::InvalidArgumentError("recursion limit exceeded");
139
0
  }
140
0
  std::optional<cel::Expr> replaced = replacer(expr);
141
0
  if (replaced.has_value()) {
142
0
    return std::move(*replaced);
143
0
  }
144
145
0
  cel::Expr new_expr;
146
0
  new_expr.set_id(expr.id());
147
148
0
  switch (expr.kind_case()) {
149
0
    case cel::ExprKindCase::kUnspecifiedExpr:
150
0
      break;
151
0
    case cel::ExprKindCase::kConstant:
152
0
      new_expr.set_const_expr(expr.const_expr());
153
0
      break;
154
0
    case cel::ExprKindCase::kIdentExpr:
155
0
      new_expr.set_ident_expr(cel::IdentExpr(expr.ident_expr().name()));
156
0
      break;
157
0
    case cel::ExprKindCase::kSelectExpr: {
158
0
      cel::SelectExpr& select = new_expr.mutable_select_expr();
159
0
      select.set_field(expr.select_expr().field());
160
0
      select.set_test_only(expr.select_expr().test_only());
161
0
      if (expr.select_expr().has_operand()) {
162
0
        CEL_ASSIGN_OR_RETURN(cel::Expr operand,
163
0
                             CopyAndReplace(expr.select_expr().operand(),
164
0
                                            replacer, max_recursion_depth - 1));
165
0
        select.set_operand(std::move(operand));
166
0
      }
167
0
      break;
168
0
    }
169
0
    case cel::ExprKindCase::kCallExpr: {
170
0
      cel::CallExpr& call = new_expr.mutable_call_expr();
171
0
      call.set_function(expr.call_expr().function());
172
0
      if (expr.call_expr().has_target()) {
173
0
        CEL_ASSIGN_OR_RETURN(cel::Expr target,
174
0
                             CopyAndReplace(expr.call_expr().target(), replacer,
175
0
                                            max_recursion_depth - 1));
176
0
        call.set_target(std::move(target));
177
0
      }
178
0
      call.mutable_args().reserve(expr.call_expr().args().size());
179
0
      for (const auto& arg : expr.call_expr().args()) {
180
0
        CEL_ASSIGN_OR_RETURN(
181
0
            cel::Expr new_arg,
182
0
            CopyAndReplace(arg, replacer, max_recursion_depth - 1));
183
0
        call.mutable_args().push_back(std::move(new_arg));
184
0
      }
185
0
      break;
186
0
    }
187
0
    case cel::ExprKindCase::kListExpr: {
188
0
      cel::ListExpr& list = new_expr.mutable_list_expr();
189
0
      list.mutable_elements().reserve(expr.list_expr().elements().size());
190
0
      for (const auto& elem : expr.list_expr().elements()) {
191
0
        cel::ListExprElement new_elem;
192
0
        new_elem.set_optional(elem.optional());
193
0
        if (elem.has_expr()) {
194
0
          CEL_ASSIGN_OR_RETURN(
195
0
              cel::Expr new_child,
196
0
              CopyAndReplace(elem.expr(), replacer, max_recursion_depth - 1));
197
0
          new_elem.set_expr(std::move(new_child));
198
0
        }
199
0
        list.mutable_elements().push_back(std::move(new_elem));
200
0
      }
201
0
      break;
202
0
    }
203
0
    case cel::ExprKindCase::kStructExpr: {
204
0
      cel::StructExpr& str = new_expr.mutable_struct_expr();
205
0
      str.set_name(expr.struct_expr().name());
206
0
      str.mutable_fields().reserve(expr.struct_expr().fields().size());
207
0
      for (const auto& field : expr.struct_expr().fields()) {
208
0
        cel::StructExprField new_field;
209
0
        new_field.set_id(field.id());
210
0
        new_field.set_name(field.name());
211
0
        new_field.set_optional(field.optional());
212
0
        if (field.has_value()) {
213
0
          CEL_ASSIGN_OR_RETURN(
214
0
              cel::Expr new_val,
215
0
              CopyAndReplace(field.value(), replacer, max_recursion_depth - 1));
216
0
          new_field.set_value(std::move(new_val));
217
0
        }
218
0
        str.mutable_fields().push_back(std::move(new_field));
219
0
      }
220
0
      break;
221
0
    }
222
0
    case cel::ExprKindCase::kMapExpr: {
223
0
      cel::MapExpr& map = new_expr.mutable_map_expr();
224
0
      map.mutable_entries().reserve(expr.map_expr().entries().size());
225
0
      for (const auto& entry : expr.map_expr().entries()) {
226
0
        cel::MapExprEntry new_entry;
227
0
        new_entry.set_id(entry.id());
228
0
        new_entry.set_optional(entry.optional());
229
0
        if (entry.has_key()) {
230
0
          CEL_ASSIGN_OR_RETURN(
231
0
              cel::Expr new_key,
232
0
              CopyAndReplace(entry.key(), replacer, max_recursion_depth - 1));
233
0
          new_entry.set_key(std::move(new_key));
234
0
        }
235
0
        if (entry.has_value()) {
236
0
          CEL_ASSIGN_OR_RETURN(
237
0
              cel::Expr new_val,
238
0
              CopyAndReplace(entry.value(), replacer, max_recursion_depth - 1));
239
0
          new_entry.set_value(std::move(new_val));
240
0
        }
241
0
        map.mutable_entries().push_back(std::move(new_entry));
242
0
      }
243
0
      break;
244
0
    }
245
0
    case cel::ExprKindCase::kComprehensionExpr: {
246
0
      cel::ComprehensionExpr& comp = new_expr.mutable_comprehension_expr();
247
0
      comp.set_iter_var(expr.comprehension_expr().iter_var());
248
0
      comp.set_iter_var2(expr.comprehension_expr().iter_var2());
249
0
      comp.set_accu_var(expr.comprehension_expr().accu_var());
250
0
      if (expr.comprehension_expr().has_accu_init()) {
251
0
        CEL_ASSIGN_OR_RETURN(
252
0
            cel::Expr new_accu_init,
253
0
            CopyAndReplace(expr.comprehension_expr().accu_init(), replacer,
254
0
                           max_recursion_depth - 1));
255
0
        comp.set_accu_init(std::move(new_accu_init));
256
0
      }
257
0
      if (expr.comprehension_expr().has_iter_range()) {
258
0
        CEL_ASSIGN_OR_RETURN(
259
0
            cel::Expr new_iter_range,
260
0
            CopyAndReplace(expr.comprehension_expr().iter_range(), replacer,
261
0
                           max_recursion_depth - 1));
262
0
        comp.set_iter_range(std::move(new_iter_range));
263
0
      }
264
0
      if (expr.comprehension_expr().has_loop_condition()) {
265
0
        CEL_ASSIGN_OR_RETURN(
266
0
            cel::Expr new_loop_condition,
267
0
            CopyAndReplace(expr.comprehension_expr().loop_condition(), replacer,
268
0
                           max_recursion_depth - 1));
269
0
        comp.set_loop_condition(std::move(new_loop_condition));
270
0
      }
271
0
      if (expr.comprehension_expr().has_loop_step()) {
272
0
        CEL_ASSIGN_OR_RETURN(
273
0
            cel::Expr new_loop_step,
274
0
            CopyAndReplace(expr.comprehension_expr().loop_step(), replacer,
275
0
                           max_recursion_depth - 1));
276
0
        comp.set_loop_step(std::move(new_loop_step));
277
0
      }
278
0
      if (expr.comprehension_expr().has_result()) {
279
0
        CEL_ASSIGN_OR_RETURN(cel::Expr new_result,
280
0
                             CopyAndReplace(expr.comprehension_expr().result(),
281
0
                                            replacer, max_recursion_depth - 1));
282
0
        comp.set_result(std::move(new_result));
283
0
      }
284
0
      break;
285
0
    }
286
0
  }
287
0
  return new_expr;
288
0
}
289
290
ListNodeBuilder<cel::Expr> AstFactoryInterface<cel::Expr>::NewListBuilder(
291
0
    int64_t id) {
292
0
  return ListNodeBuilder<cel::Expr>(id);
293
0
}
294
295
StructNodeBuilder<cel::Expr> AstFactoryInterface<cel::Expr>::NewStructBuilder(
296
0
    int64_t id, std::string name) {
297
0
  return StructNodeBuilder<cel::Expr>(id, std::move(name));
298
0
}
299
300
MapNodeBuilder<cel::Expr> AstFactoryInterface<cel::Expr>::NewMapBuilder(
301
0
    int64_t id) {
302
0
  return MapNodeBuilder<cel::Expr>(id);
303
0
}
304
305
std::optional<MacroExprExpander<cel::Expr>>
306
AstFactoryInterface<cel::Expr>::NewMacroExprExpander(std::string_view name,
307
                                                     size_t arg_count,
308
0
                                                     bool receiver_style) {
309
0
  if (macro_registry_ == nullptr) {
310
0
    return std::nullopt;
311
0
  }
312
0
  std::optional<cel::Macro> macro =
313
0
      macro_registry_->FindMacro(name, arg_count, receiver_style);
314
0
  if (!macro) {
315
0
    return std::nullopt;
316
0
  }
317
0
  return std::optional<MacroExprExpander<cel::Expr>>(std::in_place, *macro);
318
0
}
319
320
}  // namespace cel::parser_internal