Skip to content

Commit ed733ed

Browse files
dmitriplotnikovcopybara-github
authored andcommitted
[Pratt Parser] Avoid deep-cloning cel::Expr
PiperOrigin-RevId: 953542275
1 parent a0f5a4f commit ed733ed

2 files changed

Lines changed: 104 additions & 57 deletions

File tree

parser/internal/ast_factory.cc

Lines changed: 73 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -139,113 +139,146 @@ absl::StatusOr<cel::Expr> AstFactoryInterface<cel::Expr>::CopyAndReplace(
139139
}
140140
std::optional<cel::Expr> replaced = replacer(expr);
141141
if (replaced.has_value()) {
142-
return *replaced;
142+
return std::move(*replaced);
143143
}
144144

145-
cel::Expr new_expr = expr;
146-
switch (new_expr.kind_case()) {
145+
cel::Expr new_expr;
146+
new_expr.set_id(expr.id());
147+
148+
switch (expr.kind_case()) {
147149
case cel::ExprKindCase::kUnspecifiedExpr:
150+
break;
148151
case cel::ExprKindCase::kConstant:
152+
new_expr.set_const_expr(expr.const_expr());
153+
break;
149154
case cel::ExprKindCase::kIdentExpr:
155+
new_expr.set_ident_expr(cel::IdentExpr(expr.ident_expr().name()));
150156
break;
151157
case cel::ExprKindCase::kSelectExpr: {
152158
cel::SelectExpr& select = new_expr.mutable_select_expr();
153-
if (select.has_operand()) {
159+
select.set_field(expr.select_expr().field());
160+
select.set_test_only(expr.select_expr().test_only());
161+
if (expr.select_expr().has_operand()) {
154162
CEL_ASSIGN_OR_RETURN(cel::Expr operand,
155-
CopyAndReplace(select.operand(), replacer,
156-
max_recursion_depth - 1));
163+
CopyAndReplace(expr.select_expr().operand(),
164+
replacer, max_recursion_depth - 1));
157165
select.set_operand(std::move(operand));
158166
}
159167
break;
160168
}
161169
case cel::ExprKindCase::kCallExpr: {
162170
cel::CallExpr& call = new_expr.mutable_call_expr();
163-
if (call.has_target()) {
164-
CEL_ASSIGN_OR_RETURN(
165-
cel::Expr target,
166-
CopyAndReplace(call.target(), replacer, max_recursion_depth - 1));
171+
call.set_function(expr.call_expr().function());
172+
if (expr.call_expr().has_target()) {
173+
CEL_ASSIGN_OR_RETURN(cel::Expr target,
174+
CopyAndReplace(expr.call_expr().target(), replacer,
175+
max_recursion_depth - 1));
167176
call.set_target(std::move(target));
168177
}
169-
for (auto& arg : call.mutable_args()) {
178+
call.mutable_args().reserve(expr.call_expr().args().size());
179+
for (const auto& arg : expr.call_expr().args()) {
170180
CEL_ASSIGN_OR_RETURN(
171181
cel::Expr new_arg,
172182
CopyAndReplace(arg, replacer, max_recursion_depth - 1));
173-
arg = std::move(new_arg);
183+
call.mutable_args().push_back(std::move(new_arg));
174184
}
175185
break;
176186
}
177187
case cel::ExprKindCase::kListExpr: {
178188
cel::ListExpr& list = new_expr.mutable_list_expr();
179-
for (auto& elem : list.mutable_elements()) {
189+
list.mutable_elements().reserve(expr.list_expr().elements().size());
190+
for (const auto& elem : expr.list_expr().elements()) {
191+
cel::ListExprElement new_elem;
192+
new_elem.set_optional(elem.optional());
180193
if (elem.has_expr()) {
181194
CEL_ASSIGN_OR_RETURN(
182-
cel::Expr new_elem,
195+
cel::Expr new_child,
183196
CopyAndReplace(elem.expr(), replacer, max_recursion_depth - 1));
184-
elem.set_expr(std::move(new_elem));
197+
new_elem.set_expr(std::move(new_child));
185198
}
199+
list.mutable_elements().push_back(std::move(new_elem));
186200
}
187201
break;
188202
}
189203
case cel::ExprKindCase::kStructExpr: {
190204
cel::StructExpr& str = new_expr.mutable_struct_expr();
191-
for (auto& field : str.mutable_fields()) {
205+
str.set_name(expr.struct_expr().name());
206+
str.mutable_fields().reserve(expr.struct_expr().fields().size());
207+
for (const auto& field : expr.struct_expr().fields()) {
208+
cel::StructExprField new_field;
209+
new_field.set_id(field.id());
210+
new_field.set_name(field.name());
211+
new_field.set_optional(field.optional());
192212
if (field.has_value()) {
193213
CEL_ASSIGN_OR_RETURN(
194214
cel::Expr new_val,
195215
CopyAndReplace(field.value(), replacer, max_recursion_depth - 1));
196-
field.set_value(std::move(new_val));
216+
new_field.set_value(std::move(new_val));
197217
}
218+
str.mutable_fields().push_back(std::move(new_field));
198219
}
199220
break;
200221
}
201222
case cel::ExprKindCase::kMapExpr: {
202223
cel::MapExpr& map = new_expr.mutable_map_expr();
203-
for (auto& entry : map.mutable_entries()) {
224+
map.mutable_entries().reserve(expr.map_expr().entries().size());
225+
for (const auto& entry : expr.map_expr().entries()) {
226+
cel::MapExprEntry new_entry;
227+
new_entry.set_id(entry.id());
228+
new_entry.set_optional(entry.optional());
204229
if (entry.has_key()) {
205230
CEL_ASSIGN_OR_RETURN(
206231
cel::Expr new_key,
207232
CopyAndReplace(entry.key(), replacer, max_recursion_depth - 1));
208-
entry.set_key(std::move(new_key));
233+
new_entry.set_key(std::move(new_key));
209234
}
210235
if (entry.has_value()) {
211236
CEL_ASSIGN_OR_RETURN(
212237
cel::Expr new_val,
213238
CopyAndReplace(entry.value(), replacer, max_recursion_depth - 1));
214-
entry.set_value(std::move(new_val));
239+
new_entry.set_value(std::move(new_val));
215240
}
241+
map.mutable_entries().push_back(std::move(new_entry));
216242
}
217243
break;
218244
}
219245
case cel::ExprKindCase::kComprehensionExpr: {
220246
cel::ComprehensionExpr& comp = new_expr.mutable_comprehension_expr();
221-
if (comp.has_accu_init()) {
222-
CEL_ASSIGN_OR_RETURN(cel::Expr new_accu_init,
223-
CopyAndReplace(comp.accu_init(), replacer,
224-
max_recursion_depth - 1));
247+
comp.set_iter_var(expr.comprehension_expr().iter_var());
248+
comp.set_iter_var2(expr.comprehension_expr().iter_var2());
249+
comp.set_accu_var(expr.comprehension_expr().accu_var());
250+
if (expr.comprehension_expr().has_accu_init()) {
251+
CEL_ASSIGN_OR_RETURN(
252+
cel::Expr new_accu_init,
253+
CopyAndReplace(expr.comprehension_expr().accu_init(), replacer,
254+
max_recursion_depth - 1));
225255
comp.set_accu_init(std::move(new_accu_init));
226256
}
227-
if (comp.has_iter_range()) {
228-
CEL_ASSIGN_OR_RETURN(cel::Expr new_iter_range,
229-
CopyAndReplace(comp.iter_range(), replacer,
230-
max_recursion_depth - 1));
257+
if (expr.comprehension_expr().has_iter_range()) {
258+
CEL_ASSIGN_OR_RETURN(
259+
cel::Expr new_iter_range,
260+
CopyAndReplace(expr.comprehension_expr().iter_range(), replacer,
261+
max_recursion_depth - 1));
231262
comp.set_iter_range(std::move(new_iter_range));
232263
}
233-
if (comp.has_loop_condition()) {
234-
CEL_ASSIGN_OR_RETURN(cel::Expr new_loop_condition,
235-
CopyAndReplace(comp.loop_condition(), replacer,
236-
max_recursion_depth - 1));
264+
if (expr.comprehension_expr().has_loop_condition()) {
265+
CEL_ASSIGN_OR_RETURN(
266+
cel::Expr new_loop_condition,
267+
CopyAndReplace(expr.comprehension_expr().loop_condition(), replacer,
268+
max_recursion_depth - 1));
237269
comp.set_loop_condition(std::move(new_loop_condition));
238270
}
239-
if (comp.has_loop_step()) {
240-
CEL_ASSIGN_OR_RETURN(cel::Expr new_loop_step,
241-
CopyAndReplace(comp.loop_step(), replacer,
242-
max_recursion_depth - 1));
271+
if (expr.comprehension_expr().has_loop_step()) {
272+
CEL_ASSIGN_OR_RETURN(
273+
cel::Expr new_loop_step,
274+
CopyAndReplace(expr.comprehension_expr().loop_step(), replacer,
275+
max_recursion_depth - 1));
243276
comp.set_loop_step(std::move(new_loop_step));
244277
}
245-
if (comp.has_result()) {
246-
CEL_ASSIGN_OR_RETURN(
247-
cel::Expr new_result,
248-
CopyAndReplace(comp.result(), replacer, max_recursion_depth - 1));
278+
if (expr.comprehension_expr().has_result()) {
279+
CEL_ASSIGN_OR_RETURN(cel::Expr new_result,
280+
CopyAndReplace(expr.comprehension_expr().result(),
281+
replacer, max_recursion_depth - 1));
249282
comp.set_result(std::move(new_result));
250283
}
251284
break;

parser/internal/pratt_parser_worker.h

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,13 @@ ExprNode PrattParserWorker<ExprNode>::ParseBinaryAndTernary(int min_prec) {
322322
return lhs;
323323
}
324324
ExprNode false_expr = ParseBinaryAndTernary(0);
325-
lhs = ast_factory_.NewCall(
326-
op_id, CelOperator::CONDITIONAL,
327-
std::vector<ExprNode>{std::move(lhs), std::move(true_expr),
328-
std::move(false_expr)});
325+
std::vector<ExprNode> args;
326+
args.reserve(3);
327+
args.push_back(std::move(lhs));
328+
args.push_back(std::move(true_expr));
329+
args.push_back(std::move(false_expr));
330+
lhs = ast_factory_.NewCall(op_id, CelOperator::CONDITIONAL,
331+
std::move(args));
329332
continue;
330333
}
331334

@@ -340,9 +343,12 @@ ExprNode PrattParserWorker<ExprNode>::ParseBinaryAndTernary(int min_prec) {
340343
Token op_tok = NextToken();
341344
int64_t op_id = NextId(op_tok);
342345
ExprNode rhs = ParseBinaryAndTernary(op_info.precedence + 1);
343-
lhs = ast_factory_.NewCall(
344-
op_id, std::string(op_info.name),
345-
std::vector<ExprNode>{std::move(lhs), std::move(rhs)});
346+
std::vector<ExprNode> args;
347+
args.reserve(2);
348+
args.push_back(std::move(lhs));
349+
args.push_back(std::move(rhs));
350+
lhs =
351+
ast_factory_.NewCall(op_id, std::string(op_info.name), std::move(args));
346352
}
347353
return lhs;
348354
}
@@ -396,11 +402,12 @@ ExprNode PrattParserWorker<ExprNode>::ParseSelectorChain() {
396402
NormalizeIdent(id_tok, /*allow_quoted=*/!is_member_call);
397403
if (optional) {
398404
int64_t op_id = NextId(dot_tok);
399-
lhs = ast_factory_.NewCall(
400-
op_id, "_?._",
401-
std::vector<ExprNode>{
402-
std::move(lhs),
403-
ast_factory_.NewStringConst(NextId(id_tok), id_text)});
405+
std::vector<ExprNode> args;
406+
args.reserve(2);
407+
args.push_back(std::move(lhs));
408+
args.push_back(
409+
ast_factory_.NewStringConst(NextId(id_tok), std::move(id_text)));
410+
lhs = ast_factory_.NewCall(op_id, "_?._", std::move(args));
404411
} else if (peek_token_.type == TokenType::kLeftParen) {
405412
Token lparen = NextToken();
406413
int64_t call_id = NextId(lparen);
@@ -429,9 +436,12 @@ ExprNode PrattParserWorker<ExprNode>::ParseSelectorChain() {
429436
}
430437
ExprNode index = ParseExpr();
431438
Expect(TokenType::kRightBracket, "expected ']'");
432-
lhs = ast_factory_.NewCall(
433-
op_id, optional ? "_[?_]" : CelOperator::INDEX,
434-
std::vector<ExprNode>{std::move(lhs), std::move(index)});
439+
std::vector<ExprNode> args;
440+
args.reserve(2);
441+
args.push_back(std::move(lhs));
442+
args.push_back(std::move(index));
443+
lhs = ast_factory_.NewCall(op_id, optional ? "_[?_]" : CelOperator::INDEX,
444+
std::move(args));
435445
} else if (tok == TokenType::kLeftBrace) {
436446
int32_t struct_pos = GetLeftmostPosition(lhs);
437447
if (auto struct_name = ExtractStructName(lhs); struct_name.has_value()) {
@@ -455,8 +465,10 @@ ExprNode PrattParserWorker<ExprNode>::ParseUnary() {
455465
Token op = NextToken();
456466
int64_t op_id = NextId(op);
457467
ExprNode operand = ParseSelectorChain();
468+
std::vector<ExprNode> args;
469+
args.push_back(std::move(operand));
458470
return ast_factory_.NewCall(op_id, std::string(CelOperator::LOGICAL_NOT),
459-
std::vector<ExprNode>{std::move(operand)});
471+
std::move(args));
460472
}
461473
if (tok == TokenType::kMinus) {
462474
Token op = NextToken();
@@ -505,8 +517,10 @@ ExprNode PrattParserWorker<ExprNode>::ParseUnary() {
505517
// Regular negate call
506518
int64_t op_id = NextId(op);
507519
ExprNode operand = ParseSelectorChain();
520+
std::vector<ExprNode> args;
521+
args.push_back(std::move(operand));
508522
return ast_factory_.NewCall(op_id, std::string(CelOperator::NEGATE),
509-
std::vector<ExprNode>{std::move(operand)});
523+
std::move(args));
510524
}
511525
return ParsePrimary();
512526
}

0 commit comments

Comments
 (0)