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
- #include " google/protobuf/arena.h"
23
22
#include " absl/status/status.h"
24
23
#include " absl/status/statusor.h"
25
24
#include " absl/strings/str_cat.h"
26
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"
27
30
#include " eval/public/activation.h"
28
31
#include " eval/public/builtin_func_registrar.h"
29
32
#include " eval/public/cel_expr_builder_factory.h"
30
33
#include " eval/public/cel_expression.h"
31
34
#include " eval/public/cel_options.h"
32
35
#include " eval/public/cel_value.h"
33
36
#include " internal/status_macros.h"
34
- #include " parser/parser.h"
35
37
#include " google/protobuf/arena.h"
38
+ #include " google/protobuf/descriptor.h"
39
+ #include " google/protobuf/message.h"
36
40
37
41
namespace cel_codelab {
38
42
namespace {
39
43
40
- using ::cel::expr::ParsedExpr;
41
- using ::google::api::expr::parser::Parse;
44
+ using ::cel::expr::CheckedExpr;
42
45
using ::google::api::expr::runtime::Activation;
43
46
using ::google::api::expr::runtime::CelError;
44
47
using ::google::api::expr::runtime::CelExpression;
@@ -49,23 +52,45 @@ using ::google::api::expr::runtime::InterpreterOptions;
49
52
using ::google::api::expr::runtime::RegisterBuiltinFunctions;
50
53
using ::google::rpc::context::AttributeContext;
51
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
+
52
77
// Parse a cel expression and evaluate it against the given activation and
53
78
// arena.
54
- absl::StatusOr<bool > ParseAndEvaluate (absl::string_view cel_expr,
55
- const Activation& activation,
56
- google::protobuf::Arena* arena) {
57
- CEL_ASSIGN_OR_RETURN (ParsedExpr parsed_expr, Parse (cel_expr));
58
-
79
+ absl::StatusOr<bool > EvalCheckedExpr (const CheckedExpr& checked_expr,
80
+ const Activation& activation,
81
+ google::protobuf::Arena* arena) {
59
82
// Setup a default environment for building expressions.
60
83
InterpreterOptions options;
61
- std::unique_ptr<CelExpressionBuilder> builder =
62
- CreateCelExpressionBuilder (options);
84
+ std::unique_ptr<CelExpressionBuilder> builder = CreateCelExpressionBuilder (
85
+ google::protobuf::DescriptorPool::generated_pool (),
86
+ google::protobuf::MessageFactory::generated_factory (), options);
63
87
CEL_RETURN_IF_ERROR (
64
88
RegisterBuiltinFunctions (builder->GetRegistry (), options));
65
89
90
+ // Note, the expression_plan below is reusable for different inputs, but we
91
+ // create one just in time for evaluation here.
66
92
CEL_ASSIGN_OR_RETURN (std::unique_ptr<CelExpression> expression_plan,
67
- builder->CreateExpression (&parsed_expr.expr (),
68
- &parsed_expr.source_info ()));
93
+ builder->CreateExpression (&checked_expr));
69
94
70
95
CEL_ASSIGN_OR_RETURN (CelValue result,
71
96
expression_plan->Evaluate (activation, arena));
@@ -81,26 +106,38 @@ absl::StatusOr<bool> ParseAndEvaluate(absl::string_view cel_expr,
81
106
}
82
107
} // namespace
83
108
84
- absl::StatusOr<bool > ParseAndEvaluate (absl::string_view cel_expr,
85
- 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
+
86
117
Activation activation;
87
118
google::protobuf::Arena arena;
88
119
// === Start Codelab ===
89
120
// Update the activation to bind the bool argument to 'bool_var'
90
121
// === End Codelab ===
91
122
92
- return ParseAndEvaluate (cel_expr , activation, &arena);
123
+ return EvalCheckedExpr (checked_expr , activation, &arena);
93
124
}
94
125
95
- absl::StatusOr<bool > ParseAndEvaluate (absl::string_view cel_expr,
96
- 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
+
97
134
Activation activation;
98
135
google::protobuf::Arena arena;
99
136
// === Start Codelab ===
100
137
// Update the activation to bind the AttributeContext.
101
138
// === End Codelab ===
102
139
103
- return ParseAndEvaluate (cel_expr , activation, &arena);
140
+ return EvalCheckedExpr (checked_expr , activation, &arena);
104
141
}
105
142
106
143
} // namespace cel_codelab
0 commit comments