| 26 | namespace cel { |
| 27 | |
| 28 | Expr MacroExprFactory::Copy(const Expr& expr) { |
| 29 | // Copying logic is recursive at the moment, we alter it to be iterative in |
| 30 | // the future. |
| 31 | return absl::visit( |
| 32 | absl::Overload( |
| 33 | [this, &expr](const UnspecifiedExpr&) -> Expr { |
| 34 | return NewUnspecified(CopyId(expr)); |
| 35 | }, |
| 36 | [this, &expr](const Constant& const_expr) -> Expr { |
| 37 | return NewConst(CopyId(expr), const_expr); |
| 38 | }, |
| 39 | [this, &expr](const IdentExpr& ident_expr) -> Expr { |
| 40 | return NewIdent(CopyId(expr), ident_expr.name()); |
| 41 | }, |
| 42 | [this, &expr](const SelectExpr& select_expr) -> Expr { |
| 43 | const auto id = CopyId(expr); |
| 44 | return select_expr.test_only() |
| 45 | ? NewPresenceTest(id, Copy(select_expr.operand()), |
| 46 | select_expr.field()) |
| 47 | : NewSelect(id, Copy(select_expr.operand()), |
| 48 | select_expr.field()); |
| 49 | }, |
| 50 | [this, &expr](const CallExpr& call_expr) -> Expr { |
| 51 | const auto id = CopyId(expr); |
| 52 | absl::optional<Expr> target; |
| 53 | if (call_expr.has_target()) { |
| 54 | target = Copy(call_expr.target()); |
| 55 | } |
| 56 | std::vector<Expr> args; |
| 57 | args.reserve(call_expr.args().size()); |
| 58 | for (const auto& arg : call_expr.args()) { |
| 59 | args.push_back(Copy(arg)); |
| 60 | } |
| 61 | return target.has_value() |
| 62 | ? NewMemberCall(id, call_expr.function(), |
| 63 | std::move(*target), std::move(args)) |
| 64 | : NewCall(id, call_expr.function(), std::move(args)); |
| 65 | }, |
| 66 | [this, &expr](const ListExpr& list_expr) -> Expr { |
| 67 | const auto id = CopyId(expr); |
| 68 | std::vector<ListExprElement> elements; |
| 69 | elements.reserve(list_expr.elements().size()); |
| 70 | for (const auto& element : list_expr.elements()) { |
| 71 | elements.push_back(Copy(element)); |
| 72 | } |
| 73 | return NewList(id, std::move(elements)); |
| 74 | }, |
| 75 | [this, &expr](const StructExpr& struct_expr) -> Expr { |
| 76 | const auto id = CopyId(expr); |
| 77 | std::vector<StructExprField> fields; |
| 78 | fields.reserve(struct_expr.fields().size()); |
| 79 | for (const auto& field : struct_expr.fields()) { |
| 80 | fields.push_back(Copy(field)); |
| 81 | } |
| 82 | return NewStruct(id, struct_expr.name(), std::move(fields)); |
| 83 | }, |
| 84 | [this, &expr](const MapExpr& map_expr) -> Expr { |
| 85 | const auto id = CopyId(expr); |