-
Notifications
You must be signed in to change notification settings - Fork 52
/
cel_expression.h
153 lines (129 loc) · 6.18 KB
/
cel_expression.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#ifndef THIRD_PARTY_CEL_CPP_EVAL_PUBLIC_CEL_EXPRESSION_H_
#define THIRD_PARTY_CEL_CPP_EVAL_PUBLIC_CEL_EXPRESSION_H_
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include <utility>
#include "google/api/expr/v1alpha1/checked.pb.h"
#include "google/api/expr/v1alpha1/syntax.pb.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "eval/public/base_activation.h"
#include "eval/public/cel_function_registry.h"
#include "eval/public/cel_type_registry.h"
#include "eval/public/cel_value.h"
namespace google::api::expr::runtime {
// CelEvaluationListener is the callback that is passed to (and called by)
// CelExpression::Trace. It gets an expression node ID from the original
// expression, its value and the arena object. If an expression node
// is evaluated multiple times (e.g. as a part of Comprehension.loop_step)
// then the order of the callback invocations is guaranteed to correspond
// the order of variable sub-elements (e.g. the order of elements returned
// by Comprehension.iter_range).
using CelEvaluationListener = std::function<absl::Status(
int64_t expr_id, const CelValue&, google::protobuf::Arena*)>;
// An opaque state used for evaluation of a CEL expression.
class CelEvaluationState {
public:
virtual ~CelEvaluationState() = default;
};
// Base interface for expression evaluating objects.
class CelExpression {
public:
virtual ~CelExpression() = default;
// Initializes the state
virtual std::unique_ptr<CelEvaluationState> InitializeState(
google::protobuf::Arena* arena) const = 0;
// Evaluates expression and returns value.
// activation contains bindings from parameter names to values
// arena parameter specifies Arena object where output result and
// internal data will be allocated.
virtual absl::StatusOr<CelValue> Evaluate(const BaseActivation& activation,
google::protobuf::Arena* arena) const = 0;
// Evaluates expression and returns value.
// activation contains bindings from parameter names to values
// state must be non-null and created prior to calling Evaluate by
// InitializeState.
virtual absl::StatusOr<CelValue> Evaluate(
const BaseActivation& activation, CelEvaluationState* state) const = 0;
// Trace evaluates expression calling the callback on each sub-tree.
virtual absl::StatusOr<CelValue> Trace(
const BaseActivation& activation, google::protobuf::Arena* arena,
CelEvaluationListener callback) const = 0;
// Trace evaluates expression calling the callback on each sub-tree.
// state must be non-null and created prior to calling Evaluate by
// InitializeState.
virtual absl::StatusOr<CelValue> Trace(
const BaseActivation& activation, CelEvaluationState* state,
CelEvaluationListener callback) const = 0;
};
// Base class for Expression Builder implementations
// Provides user with factory to register extension functions.
// ExpressionBuilder MUST NOT be destroyed before CelExpression objects
// it built.
class CelExpressionBuilder {
public:
CelExpressionBuilder()
: func_registry_(std::make_unique<CelFunctionRegistry>()),
type_registry_(std::make_unique<CelTypeRegistry>()),
container_("") {}
virtual ~CelExpressionBuilder() = default;
// Creates CelExpression object from AST tree.
// expr specifies root of AST tree
//
// IMPORTANT: The `expr` and `source_info` must outlive the resulting
// CelExpression.
virtual absl::StatusOr<std::unique_ptr<CelExpression>> CreateExpression(
const google::api::expr::v1alpha1::Expr* expr,
const google::api::expr::v1alpha1::SourceInfo* source_info) const = 0;
// Creates CelExpression object from AST tree.
// expr specifies root of AST tree.
// non-fatal build warnings are written to warnings if encountered.
//
// IMPORTANT: The `expr` and `source_info` must outlive the resulting
// CelExpression.
virtual absl::StatusOr<std::unique_ptr<CelExpression>> CreateExpression(
const google::api::expr::v1alpha1::Expr* expr,
const google::api::expr::v1alpha1::SourceInfo* source_info,
std::vector<absl::Status>* warnings) const = 0;
// Creates CelExpression object from a checked expression.
// This includes an AST, source info, type hints and ident hints.
//
// IMPORTANT: The `checked_expr` must outlive the resulting CelExpression.
virtual absl::StatusOr<std::unique_ptr<CelExpression>> CreateExpression(
const google::api::expr::v1alpha1::CheckedExpr* checked_expr) const {
// Default implementation just passes through the expr and source info.
return CreateExpression(&checked_expr->expr(),
&checked_expr->source_info());
}
// Creates CelExpression object from a checked expression.
// This includes an AST, source info, type hints and ident hints.
// non-fatal build warnings are written to warnings if encountered.
//
// IMPORTANT: The `checked_expr` must outlive the resulting CelExpression.
virtual absl::StatusOr<std::unique_ptr<CelExpression>> CreateExpression(
const google::api::expr::v1alpha1::CheckedExpr* checked_expr,
std::vector<absl::Status>* warnings) const {
// Default implementation just passes through the expr and source_info.
return CreateExpression(&checked_expr->expr(), &checked_expr->source_info(),
warnings);
}
// CelFunction registry. Extension function should be registered with it
// prior to expression creation.
CelFunctionRegistry* GetRegistry() const { return func_registry_.get(); }
// CEL Type registry. Provides a means to resolve the CEL built-in types to
// CelValue instances, and to extend the set of types and enums known to
// expressions by registering them ahead of time.
CelTypeRegistry* GetTypeRegistry() const { return type_registry_.get(); }
virtual void set_container(std::string container) {
container_ = std::move(container);
}
absl::string_view container() const { return container_; }
private:
std::unique_ptr<CelFunctionRegistry> func_registry_;
std::unique_ptr<CelTypeRegistry> type_registry_;
std::string container_;
};
} // namespace google::api::expr::runtime
#endif // THIRD_PARTY_CEL_CPP_EVAL_PUBLIC_CEL_EXPRESSION_H_