/proc/self/cwd/runtime/runtime.h
Line | Count | Source |
1 | | // Copyright 2023 Google LLC |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | // |
15 | | // Interfaces for runtime concepts. |
16 | | |
17 | | #ifndef THIRD_PARTY_CEL_CPP_RUNTIME_RUNTIME_H_ |
18 | | #define THIRD_PARTY_CEL_CPP_RUNTIME_RUNTIME_H_ |
19 | | |
20 | | #include <cstdint> |
21 | | #include <memory> |
22 | | #include <utility> |
23 | | #include <vector> |
24 | | |
25 | | #include "absl/base/attributes.h" |
26 | | #include "absl/base/nullability.h" |
27 | | #include "absl/functional/any_invocable.h" |
28 | | #include "absl/status/status.h" |
29 | | #include "absl/status/statusor.h" |
30 | | #include "base/ast.h" |
31 | | #include "base/type_provider.h" |
32 | | #include "common/native_type.h" |
33 | | #include "common/value.h" |
34 | | #include "runtime/activation_interface.h" |
35 | | #include "runtime/runtime_issue.h" |
36 | | #include "google/protobuf/arena.h" |
37 | | #include "google/protobuf/descriptor.h" |
38 | | #include "google/protobuf/message.h" |
39 | | |
40 | | namespace cel { |
41 | | |
42 | | namespace runtime_internal { |
43 | | class RuntimeFriendAccess; |
44 | | } // namespace runtime_internal |
45 | | |
46 | | class EmbedderContext; |
47 | | |
48 | | // Options for the Program::Evaluate call. |
49 | | struct EvaluateOptions { |
50 | | // Optional message factory to use for the duration of the Evaluate call. |
51 | | // If unset, a default message factory will be provided by the runtime. |
52 | | google::protobuf::MessageFactory* absl_nullable message_factory = nullptr; |
53 | | |
54 | | // Optional embedder context to use for the duration of the Evaluate call. |
55 | | // This is used to access custom data in extension functions. |
56 | | // This is only propagated to functions that are marked as context sensitive. |
57 | | const EmbedderContext* absl_nullable embedder_context = nullptr; |
58 | | }; |
59 | | |
60 | | // Representation of an evaluable CEL expression. |
61 | | // |
62 | | // See Runtime below for creating new programs. |
63 | | class Program { |
64 | | public: |
65 | 0 | virtual ~Program() = default; |
66 | | |
67 | | // Evaluate the program. |
68 | | // |
69 | | // Non-recoverable errors (i.e. outside of CEL's notion of an error) are |
70 | | // returned as a non-ok absl::Status. These are propagated immediately and do |
71 | | // not participate in CEL's notion of error handling. |
72 | | // |
73 | | // CEL errors are represented as result with an Ok status and a held |
74 | | // cel::ErrorValue result. |
75 | | // |
76 | | // Activation manages instances of variables available in the cel expression's |
77 | | // environment. |
78 | | // |
79 | | // The arena will be used to as necessary to allocate values and must outlive |
80 | | // the returned value, as must this program. |
81 | | // |
82 | | // For consistency, users should use the same arena to create values |
83 | | // in the activation and for Program evaluation. |
84 | | absl::StatusOr<Value> Evaluate( |
85 | | google::protobuf::Arena* absl_nonnull arena ABSL_ATTRIBUTE_LIFETIME_BOUND, |
86 | | const ActivationInterface& activation, |
87 | 0 | const EvaluateOptions& options = {}) const ABSL_ATTRIBUTE_LIFETIME_BOUND { |
88 | 0 | return EvaluateImpl(activation, arena, options); |
89 | 0 | } |
90 | | |
91 | | ABSL_DEPRECATED("Use the EvaluateOptions overload instead.") |
92 | | absl::StatusOr<Value> Evaluate( |
93 | | google::protobuf::Arena* absl_nonnull arena ABSL_ATTRIBUTE_LIFETIME_BOUND, |
94 | | google::protobuf::MessageFactory* absl_nullable message_factory |
95 | | ABSL_ATTRIBUTE_LIFETIME_BOUND, |
96 | | const ActivationInterface& activation) const |
97 | 0 | ABSL_ATTRIBUTE_LIFETIME_BOUND { |
98 | 0 | return EvaluateImpl(activation, arena, {message_factory}); |
99 | 0 | } |
100 | | |
101 | | virtual const TypeProvider& GetTypeProvider() const = 0; |
102 | | |
103 | | protected: |
104 | | virtual absl::StatusOr<Value> EvaluateImpl( |
105 | | const ActivationInterface& activation, |
106 | | google::protobuf::Arena* absl_nonnull arena ABSL_ATTRIBUTE_LIFETIME_BOUND, |
107 | | const EvaluateOptions& options) const ABSL_ATTRIBUTE_LIFETIME_BOUND = 0; |
108 | | }; |
109 | | |
110 | | // Representation for a traceable CEL expression. |
111 | | // |
112 | | // Implementations provide an additional Trace method that evaluates the |
113 | | // expression and invokes a callback allowing callers to inspect intermediate |
114 | | // state during evaluation. |
115 | | class TraceableProgram : public Program { |
116 | | public: |
117 | | // EvaluationListener may be provided to an EvaluateWithCallback call to |
118 | | // inspect intermediate values during evaluation. |
119 | | // |
120 | | // The callback is called on after every program step that corresponds |
121 | | // to an AST expression node. The value provided is the top of the value |
122 | | // stack, corresponding to the result of evaluating the given sub expression. |
123 | | // |
124 | | // A returning a non-ok status stops evaluation and forwards the error. |
125 | | using EvaluationListener = absl::AnyInvocable<absl::Status( |
126 | | int64_t expr_id, const Value&, const google::protobuf::DescriptorPool* absl_nonnull, |
127 | | google::protobuf::MessageFactory* absl_nonnull, google::protobuf::Arena* absl_nonnull)>; |
128 | | |
129 | | using Program::Evaluate; |
130 | | |
131 | | // Evaluate the Program plan with a Listener. |
132 | | // |
133 | | // The given callback will be invoked after evaluating any program step |
134 | | // that corresponds to an AST node in the planned CEL expression. |
135 | | // |
136 | | // If the callback returns a non-ok status, evaluation stops and the Status |
137 | | // is forwarded as the result of the EvaluateWithCallback call. |
138 | | absl::StatusOr<Value> Trace( |
139 | | google::protobuf::Arena* absl_nonnull arena ABSL_ATTRIBUTE_LIFETIME_BOUND, |
140 | | const ActivationInterface& activation, |
141 | | EvaluationListener evaluation_listener, |
142 | 0 | const EvaluateOptions& options = {}) const ABSL_ATTRIBUTE_LIFETIME_BOUND { |
143 | 0 | return TraceImpl(activation, std::move(evaluation_listener), arena, |
144 | 0 | options); |
145 | 0 | } |
146 | | |
147 | | ABSL_DEPRECATED("Use the EvaluateOptions overload instead.") |
148 | | absl::StatusOr<Value> Trace( |
149 | | google::protobuf::Arena* absl_nonnull arena ABSL_ATTRIBUTE_LIFETIME_BOUND, |
150 | | google::protobuf::MessageFactory* absl_nullable message_factory |
151 | | ABSL_ATTRIBUTE_LIFETIME_BOUND, |
152 | | const ActivationInterface& activation, |
153 | | EvaluationListener evaluation_listener) const |
154 | 0 | ABSL_ATTRIBUTE_LIFETIME_BOUND { |
155 | 0 | return TraceImpl(activation, std::move(evaluation_listener), arena, |
156 | 0 | {message_factory}); |
157 | 0 | } |
158 | | |
159 | | protected: |
160 | | absl::StatusOr<Value> EvaluateImpl(const ActivationInterface& activation, |
161 | | google::protobuf::Arena* absl_nonnull arena |
162 | | ABSL_ATTRIBUTE_LIFETIME_BOUND, |
163 | | const EvaluateOptions& options) const |
164 | 0 | ABSL_ATTRIBUTE_LIFETIME_BOUND override { |
165 | 0 | return TraceImpl(activation, nullptr, arena, options); |
166 | 0 | } |
167 | | |
168 | | virtual absl::StatusOr<Value> TraceImpl( |
169 | | const ActivationInterface& activation, |
170 | | EvaluationListener evaluation_listener, |
171 | | google::protobuf::Arena* absl_nonnull arena ABSL_ATTRIBUTE_LIFETIME_BOUND, |
172 | | const EvaluateOptions& options) const ABSL_ATTRIBUTE_LIFETIME_BOUND = 0; |
173 | | }; |
174 | | |
175 | | // Interface for a CEL runtime. |
176 | | // |
177 | | // Manages the state necessary to generate Programs. |
178 | | // |
179 | | // Runtime instances should be created from a RuntimeBuilder rather than |
180 | | // instantiated directly. |
181 | | // |
182 | | // Implementations provided by CEL will be thread-compatible, but write |
183 | | // operations on the underlying environment (TypeRegistry, FunctionRegistry) or |
184 | | // on the implementation via down casting must be synchronized by the caller and |
185 | | // may invalidate any Programs created from the Runtime. |
186 | | class Runtime { |
187 | | public: |
188 | | struct CreateProgramOptions { |
189 | | // Optional output for collecting issues encountered while planning. |
190 | | // If non-null, vector is cleared and encountered issues are added. |
191 | | std::vector<RuntimeIssue>* issues = nullptr; |
192 | | }; |
193 | | |
194 | 0 | virtual ~Runtime() = default; |
195 | | |
196 | | absl::StatusOr<std::unique_ptr<Program>> CreateProgram( |
197 | 0 | std::unique_ptr<cel::Ast> ast) const { |
198 | 0 | return CreateProgram(std::move(ast), CreateProgramOptions{}); |
199 | 0 | } |
200 | | |
201 | | virtual absl::StatusOr<std::unique_ptr<Program>> CreateProgram( |
202 | | std::unique_ptr<cel::Ast> ast, |
203 | | const CreateProgramOptions& options) const = 0; |
204 | | |
205 | | absl::StatusOr<std::unique_ptr<TraceableProgram>> CreateTraceableProgram( |
206 | 0 | std::unique_ptr<cel::Ast> ast) const { |
207 | 0 | return CreateTraceableProgram(std::move(ast), CreateProgramOptions{}); |
208 | 0 | } |
209 | | |
210 | | virtual absl::StatusOr<std::unique_ptr<TraceableProgram>> |
211 | | CreateTraceableProgram(std::unique_ptr<cel::Ast> ast, |
212 | | const CreateProgramOptions& options) const = 0; |
213 | | |
214 | | virtual const TypeProvider& GetTypeProvider() const = 0; |
215 | | |
216 | | virtual const google::protobuf::DescriptorPool* absl_nonnull GetDescriptorPool() |
217 | | const = 0; |
218 | | |
219 | | virtual google::protobuf::MessageFactory* absl_nonnull GetMessageFactory() const = 0; |
220 | | |
221 | | private: |
222 | | friend class runtime_internal::RuntimeFriendAccess; |
223 | | |
224 | | virtual NativeTypeId GetNativeTypeId() const = 0; |
225 | | }; |
226 | | |
227 | | } // namespace cel |
228 | | |
229 | | #endif // THIRD_PARTY_CEL_CPP_RUNTIME_RUNTIME_H_ |