Skip to content

Commit a9eec46

Browse files
authored
Export of internal changes (#49)
-- 284576129: BEGIN_PUBLIC Define an abstract class for Activation. This would be used by a Wasm context to implement FindValue, as opposed to maintaining an embedded Activation. Values have unmanaged lifetimes, meaning if it difficult to add/remove values from an Activation repeatedly. END_PUBLIC -- 284290583: Migrate existing users of the tools/build_defs/golden_test macros to use the new macro location. This CL is supposed to be a no-op, and https://paste.googleplex.com/5747263567560704?raw shows it will be. If I've messed up, or e.g. an intervening depot CL means something unexpected happens, that's fine; please fix-forward. This CL is #2 out of 3 in http://b/145011071#comment2. Tested: TAP --sample ran all affected tests and none failed http://test/OCL:283986728:BASE:284250161:1575670327474:2f203dc8 -- 284044257: BEGIN_PUBLIC Fix parsing bug with raw strings (e.g. r""). Switch conformance tests to use C++ parser instead of Go parser. END_PUBLIC PiperOrigin-RevId: 284576129
1 parent 4767e5d commit a9eec46

File tree

12 files changed

+72
-33
lines changed

12 files changed

+72
-33
lines changed

common/escaping.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ absl::optional<std::string> unescape(const std::string& s, bool is_bytes) {
266266
// Raw string preceded by the 'r|R' prefix.
267267
bool is_raw_literal = false;
268268
if (value[0] == 'r' || value[0] == 'R') {
269-
value.resize(value.size() - 1);
269+
value = value.substr(1, n - 1);
270270
n = value.size();
271271
is_raw_literal = true;
272272
}

common/escaping_test.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ std::vector<TestInfo> test_cases = {
3535
{R"("\\")", "\\"},
3636
{"'''x''x'''", "x''x"},
3737
{R"("""x""x""")", R"(x""x)"},
38+
{R"(r"")", ""},
3839
// Octal 303 -> Code point 195 (Ã)
3940
// Octal 277 -> Code point 191 (¿)
4041
{R"("\303\277")", "ÿ"},

conformance/BUILD

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ cc_binary(
3838
"//eval/eval:container_backed_map_impl",
3939
"//eval/public:builtin_func_registrar",
4040
"//eval/public:cel_expr_builder_factory",
41+
"//parser",
4142
"@com_github_grpc_grpc//:grpc++",
4243
"@com_google_absl//absl/strings",
4344
"@com_google_googleapis//google/api/expr/v1alpha1:checked_cc_proto",
4445
"@com_google_googleapis//google/api/expr/v1alpha1:conformance_service_cc_grpc",
4546
"@com_google_googleapis//google/api/expr/v1alpha1:syntax_cc_proto",
47+
"@com_google_googleapis//google/rpc:code_cc_proto",
4648
"@com_google_protobuf//:protobuf",
4749
],
4850
)
@@ -53,8 +55,8 @@ cc_binary(
5355
srcs = [":" + driver],
5456
args = [
5557
"$(location @com_google_cel_spec//tests/simple:simple_test)",
56-
"--server=$(location @com_google_cel_go//server/main:cel_server)",
57-
"--eval_server=$(location :server)",
58+
"--server=$(location :server)",
59+
"--check_server=$(location @com_google_cel_go//server/main:cel_server)",
5860
# Requires container support
5961
"--skip_test=basic/namespace/self_eval_container_lookup,self_eval_container_lookup_unchecked",
6062
# Requires heteregenous equality spec clarification
@@ -83,8 +85,8 @@ sh_test(
8385
srcs = ["@com_google_cel_spec//tests:conftest-nofail.sh"],
8486
args = [
8587
"$(location @com_google_cel_spec//tests/simple:simple_test)",
86-
"--server=$(location @com_google_cel_go//server/main:cel_server)",
87-
"--eval_server=$(location :server)",
88+
"--server=$(location :server)",
89+
"--check_server=$(location @com_google_cel_go//server/main:cel_server)",
8890
] + ["$(location " + test + ")" for test in DASHBOARD_TESTS],
8991
data = [
9092
":server",

conformance/server.cc

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
#include "google/api/expr/v1alpha1/syntax.pb.h"
66
#include "google/api/expr/v1alpha1/value.pb.h"
77
#include "google/protobuf/struct.pb.h"
8+
#include "google/rpc/code.pb.h"
89
#include "grpcpp/grpcpp.h"
910
#include "absl/strings/str_split.h"
1011
#include "eval/eval/container_backed_list_impl.h"
1112
#include "eval/eval/container_backed_map_impl.h"
1213
#include "eval/public/builtin_func_registrar.h"
1314
#include "eval/public/cel_expr_builder_factory.h"
15+
#include "parser/parser.h"
1416
#include "base/statusor.h"
1517

1618

@@ -190,12 +192,25 @@ class ConformanceServiceImpl final
190192
Status Parse(grpc::ServerContext* context,
191193
const v1alpha1::ParseRequest* request,
192194
v1alpha1::ParseResponse* response) override {
193-
return Status(StatusCode::UNIMPLEMENTED, "only Eval is supported");
195+
if (request->cel_source().empty()) {
196+
return Status(StatusCode::INVALID_ARGUMENT, "No source code.");
197+
}
198+
auto parse_status = parser::Parse(request->cel_source(), "");
199+
if (!parse_status.ok()) {
200+
auto issue = response->add_issues();
201+
*issue->mutable_message() = std::string(parse_status.status().message());
202+
issue->set_code(google::rpc::Code::INVALID_ARGUMENT);
203+
} else {
204+
google::api::expr::v1alpha1::ParsedExpr out;
205+
out = parse_status.ValueOrDie();
206+
response->mutable_parsed_expr()->CopyFrom(out);
207+
}
208+
return Status::OK;
194209
}
195210
Status Check(grpc::ServerContext* context,
196211
const v1alpha1::CheckRequest* request,
197212
v1alpha1::CheckResponse* response) override {
198-
return Status(StatusCode::UNIMPLEMENTED, "only Eval is supported");
213+
return Status(StatusCode::UNIMPLEMENTED, "Check is not supported");
199214
}
200215
Status Eval(grpc::ServerContext* context,
201216
const v1alpha1::EvalRequest* request,

eval/eval/evaluator_core.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ const ExpressionStep* ExecutionFrame::Next() {
1818
}
1919

2020
cel_base::StatusOr<CelValue> CelExpressionFlatImpl::Evaluate(
21-
const Activation& activation, google::protobuf::Arena* arena) const {
21+
const BaseActivation& activation, google::protobuf::Arena* arena) const {
2222
return Trace(activation, arena, CelEvaluationListener());
2323
}
2424

2525
cel_base::StatusOr<CelValue> CelExpressionFlatImpl::Trace(
26-
const Activation& activation, google::protobuf::Arena* arena,
26+
const BaseActivation& activation, google::protobuf::Arena* arena,
2727
CelEvaluationListener callback) const {
2828
ExecutionFrame frame(&path_, activation, arena, max_iterations_);
2929

eval/eval/evaluator_core.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class ExecutionFrame {
9595
// flat is the flattened sequence of execution steps that will be evaluated.
9696
// activation provides bindings between parameter names and values.
9797
// arena serves as allocation manager during the expression evaluation.
98-
ExecutionFrame(const ExecutionPath* flat, const Activation& activation,
98+
ExecutionFrame(const ExecutionPath* flat, const BaseActivation& activation,
9999
google::protobuf::Arena* arena, int max_iterations)
100100
: pc_(0UL),
101101
execution_path_(flat),
@@ -129,7 +129,7 @@ class ExecutionFrame {
129129
google::protobuf::Arena* arena() { return arena_; }
130130

131131
// Returns reference to Activation
132-
const Activation& activation() const { return activation_; }
132+
const BaseActivation& activation() const { return activation_; }
133133

134134
// Returns reference to iter_vars
135135
std::map<std::string, CelValue>& iter_vars() { return iter_vars_; }
@@ -151,7 +151,7 @@ class ExecutionFrame {
151151
private:
152152
size_t pc_; // pc_ - Program Counter. Current position on execution path.
153153
const ExecutionPath* execution_path_;
154-
const Activation& activation_;
154+
const BaseActivation& activation_;
155155
ValueStack value_stack_;
156156
google::protobuf::Arena* arena_;
157157
const int max_iterations_;
@@ -173,11 +173,11 @@ class CelExpressionFlatImpl : public CelExpression {
173173
: path_(std::move(path)), max_iterations_(max_iterations) {}
174174

175175
// Implementation of CelExpression evaluate method.
176-
cel_base::StatusOr<CelValue> Evaluate(const Activation& activation,
176+
cel_base::StatusOr<CelValue> Evaluate(const BaseActivation& activation,
177177
google::protobuf::Arena* arena) const override;
178178

179179
// Implementation of CelExpression trace method.
180-
cel_base::StatusOr<CelValue> Trace(const Activation& activation,
180+
cel_base::StatusOr<CelValue> Trace(const BaseActivation& activation,
181181
google::protobuf::Arena* arena,
182182
CelEvaluationListener callback) const override;
183183

eval/eval/function_step.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ cel_base::StatusOr<const CelFunction*> LazyFunctionStep::ResolveFunction(
149149

150150
CelFunctionDescriptor matcher{name_, receiver_style_, arg_types};
151151

152-
const Activation& activation = frame->activation();
152+
const BaseActivation& activation = frame->activation();
153153
for (auto provider : providers_) {
154154
auto status = provider->GetFunction(matcher, activation);
155155
if (!status.ok()) {

eval/public/activation.h

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,53 @@ namespace api {
1717
namespace expr {
1818
namespace runtime {
1919

20+
// Base class for an activation.
21+
class BaseActivation {
22+
public:
23+
BaseActivation() = default;
24+
25+
// Non-copyable/non-assignable
26+
BaseActivation(const BaseActivation&) = delete;
27+
BaseActivation& operator=(const BaseActivation&) = delete;
28+
29+
// Return a list of function overloads for the given name.
30+
virtual std::vector<const CelFunction*> FindFunctionOverloads(
31+
absl::string_view) const = 0;
32+
33+
// Provide the value that is bound to the name, if found.
34+
// arena parameter is provided to support the case when we want to pass the
35+
// ownership of returned object ( Message/List/Map ) to Evaluator.
36+
virtual absl::optional<CelValue> FindValue(absl::string_view,
37+
google::protobuf::Arena*) const = 0;
38+
39+
// Check whether a select path is unknown.
40+
virtual bool IsPathUnknown(absl::string_view) const = 0;
41+
42+
virtual ~BaseActivation() {}
43+
};
44+
2045
// Instance of Activation class is used by evaluator.
2146
// It provides binding between references used in expressions
2247
// and actual values.
23-
class Activation {
48+
class Activation : public BaseActivation {
2449
public:
2550
Activation() = default;
2651

2752
// Non-copyable/non-assignable
2853
Activation(const Activation&) = delete;
2954
Activation& operator=(const Activation&) = delete;
3055

31-
// Return list of function overloads for the given name.
56+
// BaseActivation
3257
std::vector<const CelFunction*> FindFunctionOverloads(
33-
absl::string_view name) const;
58+
absl::string_view name) const override;
3459

35-
// Provide value that is bound to the name, if found.
36-
// arena parameter is provided to support the case when we want to pass the
37-
// ownership of returned object ( Message/List/Map ) to Evaluator.
3860
absl::optional<CelValue> FindValue(absl::string_view name,
39-
google::protobuf::Arena* arena) const;
61+
google::protobuf::Arena* arena) const override;
62+
63+
bool IsPathUnknown(absl::string_view path) const override {
64+
return google::protobuf::util::FieldMaskUtil::IsPathInFieldMask(std::string(path),
65+
unknown_paths_);
66+
}
4067

4168
// Insert a function into the activation (ie a lazily bound function). Returns
4269
// a status if the name and shape of the function matches another one that has
@@ -75,12 +102,6 @@ class Activation {
75102
return unknown_paths_;
76103
}
77104

78-
// Check whether select path is unknown.
79-
bool IsPathUnknown(absl::string_view path) const {
80-
return google::protobuf::util::FieldMaskUtil::IsPathInFieldMask(std::string(path),
81-
unknown_paths_);
82-
}
83-
84105
private:
85106
class ValueEntry {
86107
public:

eval/public/cel_expression.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ class CelExpression {
3434
// activation contains bindings from parameter names to values
3535
// arena parameter specifies Arena object where output result and
3636
// internal data will be allocated.
37-
virtual cel_base::StatusOr<CelValue> Evaluate(const Activation& activation,
37+
virtual cel_base::StatusOr<CelValue> Evaluate(const BaseActivation& activation,
3838
google::protobuf::Arena* arena) const = 0;
3939

4040
// Trace evaluates expression calling the callback on each sub-tree.
4141
virtual cel_base::StatusOr<CelValue> Trace(
42-
const Activation& activation, google::protobuf::Arena* arena,
42+
const BaseActivation& activation, google::protobuf::Arena* arena,
4343
CelEvaluationListener callback) const = 0;
4444
};
4545

eval/public/cel_function_provider.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class ActivationFunctionProviderImpl : public CelFunctionProvider {
1313
ActivationFunctionProviderImpl() {}
1414
cel_base::StatusOr<const CelFunction*> GetFunction(
1515
const CelFunctionDescriptor& descriptor,
16-
const Activation& activation) const override {
16+
const BaseActivation& activation) const override {
1717
std::vector<const CelFunction*> overloads =
1818
activation.FindFunctionOverloads(descriptor.name());
1919

0 commit comments

Comments
 (0)