15
15
#include " codelab/exercise2.h"
16
16
17
17
#include < memory>
18
- #include < string>
19
18
19
+ #include " cel/expr/checked.pb.h"
20
20
#include " cel/expr/syntax.pb.h"
21
21
#include " google/rpc/context/attribute_context.pb.h"
22
22
#include " absl/status/status.h"
23
23
#include " absl/status/statusor.h"
24
24
#include " absl/strings/str_cat.h"
25
25
#include " absl/strings/string_view.h"
26
+ #include " codelab/cel_compiler.h"
27
+ #include " compiler/compiler.h"
28
+ #include " compiler/compiler_factory.h"
29
+ #include " compiler/standard_library.h"
26
30
#include " eval/public/activation.h"
27
31
#include " eval/public/builtin_func_registrar.h"
28
32
#include " eval/public/cel_expr_builder_factory.h"
29
33
#include " eval/public/cel_expression.h"
30
34
#include " eval/public/cel_options.h"
31
35
#include " eval/public/cel_value.h"
32
36
#include " internal/status_macros.h"
33
- #include " parser/parser.h"
34
37
#include " google/protobuf/arena.h"
38
+ #include " google/protobuf/descriptor.h"
39
+ #include " google/protobuf/message.h"
35
40
36
41
namespace cel_codelab {
37
42
namespace {
38
43
39
- using ::cel::expr::ParsedExpr;
40
- using ::google::api::expr::parser::Parse;
44
+ using ::cel::expr::CheckedExpr;
41
45
using ::google::api::expr::runtime::Activation;
42
46
using ::google::api::expr::runtime::CelError;
43
47
using ::google::api::expr::runtime::CelExpression;
@@ -48,23 +52,45 @@ using ::google::api::expr::runtime::InterpreterOptions;
48
52
using ::google::api::expr::runtime::RegisterBuiltinFunctions;
49
53
using ::google::rpc::context::AttributeContext;
50
54
55
+ absl::StatusOr<std::unique_ptr<cel::Compiler>> MakeCelCompiler () {
56
+ // Note: we are using the generated descriptor pool here for simplicity, but
57
+ // it has the drawback of including all message types that are linked into the
58
+ // binary instead of just the ones expected for the CEL environment.
59
+ google::protobuf::LinkMessageReflection<AttributeContext>();
60
+ CEL_ASSIGN_OR_RETURN (
61
+ std::unique_ptr<cel::CompilerBuilder> builder,
62
+ cel::NewCompilerBuilder (google::protobuf::DescriptorPool::generated_pool ()));
63
+
64
+ CEL_RETURN_IF_ERROR (builder->AddLibrary (cel::StandardCompilerLibrary ()));
65
+ // === Start Codelab ===
66
+ // Add 'AttributeContext' as a context message to the type checker and a
67
+ // boolean variable 'bool_var'. Relevant functions are on the
68
+ // TypeCheckerBuilder class (see CompilerBuilder::GetCheckerBuilder).
69
+ //
70
+ // We're reusing the same compiler for both evaluation paths here for brevity,
71
+ // but it's likely a better fit to configure a separate compiler per use case.
72
+ // === End Codelab ===
73
+
74
+ return builder->Build ();
75
+ }
76
+
51
77
// Parse a cel expression and evaluate it against the given activation and
52
78
// arena.
53
- absl::StatusOr<bool > ParseAndEvaluate (absl::string_view cel_expr,
54
- const Activation& activation,
55
- google::protobuf::Arena* arena) {
56
- CEL_ASSIGN_OR_RETURN (ParsedExpr parsed_expr, Parse (cel_expr));
57
-
79
+ absl::StatusOr<bool > EvalCheckedExpr (const CheckedExpr& checked_expr,
80
+ const Activation& activation,
81
+ google::protobuf::Arena* arena) {
58
82
// Setup a default environment for building expressions.
59
83
InterpreterOptions options;
60
- std::unique_ptr<CelExpressionBuilder> builder =
61
- CreateCelExpressionBuilder (options);
84
+ std::unique_ptr<CelExpressionBuilder> builder = CreateCelExpressionBuilder (
85
+ google::protobuf::DescriptorPool::generated_pool (),
86
+ google::protobuf::MessageFactory::generated_factory (), options);
62
87
CEL_RETURN_IF_ERROR (
63
88
RegisterBuiltinFunctions (builder->GetRegistry (), options));
64
89
90
+ // Note, the expression_plan below is reusable for different inputs, but we
91
+ // create one just in time for evaluation here.
65
92
CEL_ASSIGN_OR_RETURN (std::unique_ptr<CelExpression> expression_plan,
66
- builder->CreateExpression (&parsed_expr.expr (),
67
- &parsed_expr.source_info ()));
93
+ builder->CreateExpression (&checked_expr));
68
94
69
95
CEL_ASSIGN_OR_RETURN (CelValue result,
70
96
expression_plan->Evaluate (activation, arena));
@@ -80,26 +106,38 @@ absl::StatusOr<bool> ParseAndEvaluate(absl::string_view cel_expr,
80
106
}
81
107
} // namespace
82
108
83
- absl::StatusOr<bool > ParseAndEvaluate (absl::string_view cel_expr,
84
- bool bool_var) {
109
+ absl::StatusOr<bool > CompileAndEvaluateWithBoolVar (absl::string_view cel_expr,
110
+ bool bool_var) {
111
+ CEL_ASSIGN_OR_RETURN (std::unique_ptr<cel::Compiler> compiler,
112
+ MakeCelCompiler ());
113
+
114
+ CEL_ASSIGN_OR_RETURN (CheckedExpr checked_expr,
115
+ CompileToCheckedExpr (*compiler, cel_expr));
116
+
85
117
Activation activation;
86
118
google::protobuf::Arena arena;
87
119
// === Start Codelab ===
88
120
// Update the activation to bind the bool argument to 'bool_var'
89
121
// === End Codelab ===
90
122
91
- return ParseAndEvaluate (cel_expr , activation, &arena);
123
+ return EvalCheckedExpr (checked_expr , activation, &arena);
92
124
}
93
125
94
- absl::StatusOr<bool > ParseAndEvaluate (absl::string_view cel_expr,
95
- const AttributeContext& context) {
126
+ absl::StatusOr<bool > CompileAndEvaluateWithContext (
127
+ absl::string_view cel_expr, const AttributeContext& context) {
128
+ CEL_ASSIGN_OR_RETURN (std::unique_ptr<cel::Compiler> compiler,
129
+ MakeCelCompiler ());
130
+
131
+ CEL_ASSIGN_OR_RETURN (CheckedExpr checked_expr,
132
+ CompileToCheckedExpr (*compiler, cel_expr));
133
+
96
134
Activation activation;
97
135
google::protobuf::Arena arena;
98
136
// === Start Codelab ===
99
137
// Update the activation to bind the AttributeContext.
100
138
// === End Codelab ===
101
139
102
- return ParseAndEvaluate (cel_expr , activation, &arena);
140
+ return EvalCheckedExpr (checked_expr , activation, &arena);
103
141
}
104
142
105
143
} // namespace cel_codelab
0 commit comments