@@ -71,6 +71,11 @@ using ::google::api::expr::runtime::ProgramOptimizer;
7171using ::google::api::expr::runtime::ProgramOptimizerFactory;
7272using ::google::api::expr::runtime::Resolver;
7373
74+ enum class IsConst {
75+ kConditional ,
76+ kNonConst ,
77+ };
78+
7479class ConstantFoldingExtension : public ProgramOptimizer {
7580 public:
7681 ConstantFoldingExtension (
@@ -92,10 +97,6 @@ class ConstantFoldingExtension : public ProgramOptimizer {
9297 const Expr& node) override ;
9398
9499 private:
95- enum class IsConst {
96- kConditional ,
97- kNonConst ,
98- };
99100 // Most constant folding evaluations are simple
100101 // binary operators.
101102 static constexpr size_t kDefaultStackLimit = 4 ;
@@ -114,51 +115,42 @@ class ConstantFoldingExtension : public ProgramOptimizer {
114115 std::vector<IsConst> is_const_;
115116};
116117
117- absl::Status ConstantFoldingExtension::OnPreVisit (PlannerContext& context,
118- const Expr& node) {
119- struct IsConstVisitor {
120- IsConst operator ()(const Constant&) { return IsConst::kConditional ; }
121- IsConst operator ()(const IdentExpr&) { return IsConst::kNonConst ; }
122- IsConst operator ()(const ComprehensionExpr&) {
118+ IsConst IsConstExpr (const Expr& expr, const Resolver& resolver) {
119+ switch (expr.kind_case ()) {
120+ case ExprKindCase::kConstant :
121+ return IsConst::kConditional ;
122+ case ExprKindCase::kIdentExpr :
123+ return IsConst::kNonConst ;
124+ case ExprKindCase::kComprehensionExpr :
123125 // Not yet supported, need to identify whether range and
124126 // iter vars are compatible with const folding.
125127 return IsConst::kNonConst ;
126- }
127- IsConst operator ()(const StructExpr& create_struct) {
128+ case ExprKindCase::kStructExpr :
128129 return IsConst::kNonConst ;
129- }
130- IsConst operator ()(const cel::MapExpr& map_expr) {
131- // Not yet supported but should be possible in the future.
130+ case ExprKindCase::kMapExpr :
132131 // Empty maps are rare and not currently supported as they may eventually
133132 // have similar issues to empty list when used within comprehensions or
134133 // macros.
135- if (map_expr.entries ().empty ()) {
134+ if (expr. map_expr () .entries ().empty ()) {
136135 return IsConst::kNonConst ;
137136 }
138137 return IsConst::kConditional ;
139- }
140- IsConst operator ()(const ListExpr& create_list) {
141- if (create_list.elements ().empty ()) {
142- // TODO: Don't fold for empty list to allow comprehension
138+ case ExprKindCase::kListExpr :
139+ if (expr.list_expr ().elements ().empty ()) {
140+ // Don't fold for empty list to allow comprehension
143141 // list append optimization.
144142 return IsConst::kNonConst ;
145143 }
146144 return IsConst::kConditional ;
147- }
148-
149- IsConst operator ()(const SelectExpr&) { return IsConst::kConditional ; }
150-
151- IsConst operator ()(const cel::UnspecifiedExpr&) {
152- return IsConst::kNonConst ;
153- }
154-
155- IsConst operator ()(const CallExpr& call) {
145+ case ExprKindCase::kSelectExpr :
146+ return IsConst::kConditional ;
147+ case ExprKindCase::kCallExpr : {
148+ const auto & call = expr.call_expr ();
156149 // Short Circuiting operators not yet supported.
157150 if (call.function () == kAnd || call.function () == kOr ||
158151 call.function () == kTernary ) {
159152 return IsConst::kNonConst ;
160153 }
161-
162154 // For now we skip constant folding for cel.@block. We do not yet setup
163155 // slots. When we enable constant folding for comprehensions (like
164156 // cel.bind), we can address cel.@block.
@@ -167,23 +159,24 @@ absl::Status ConstantFoldingExtension::OnPreVisit(PlannerContext& context,
167159 }
168160
169161 int arg_len = call.args ().size () + (call.has_target () ? 1 : 0 );
170- std::vector<cel::Kind> arg_matcher (arg_len, cel::Kind::kAny );
171162 // Check for any lazy overloads (activation dependant)
172163 if (!resolver
173- .FindLazyOverloads (call.function (), call.has_target (),
174- arg_matcher)
164+ .FindLazyOverloads (call.function (), call.has_target (), arg_len)
175165 .empty ()) {
176166 return IsConst::kNonConst ;
177167 }
178168
179169 return IsConst::kConditional ;
180170 }
171+ case ExprKindCase::kUnspecifiedExpr :
172+ default :
173+ return IsConst::kNonConst ;
174+ }
175+ }
181176
182- const Resolver& resolver;
183- };
184-
185- IsConst is_const =
186- absl::visit (IsConstVisitor{context.resolver ()}, node.kind ());
177+ absl::Status ConstantFoldingExtension::OnPreVisit (PlannerContext& context,
178+ const Expr& node) {
179+ IsConst is_const = IsConstExpr (node, context.resolver ());
187180 is_const_.push_back (is_const);
188181
189182 return absl::OkStatus ();
0 commit comments