Skip to content

Commit a254193

Browse files
Implement getField CEL function (#90)
I'm proposing this as an eventual replacement (before 1.0) of our hack around the fact that the in identifier is reserved in CEL. We need this for protovalidate-cc especially so we can start removing our cel-cpp patches. Protovalidate PR: bufbuild/protovalidate#352
1 parent 86d5a71 commit a254193

23 files changed

+155
-231
lines changed

MODULE.bazel

+2-4
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,12 @@ archive_override(
3434
module_name = "cel-cpp",
3535
strip_prefix = "cel-cpp-0.11.0",
3636
patches=[
37-
"@protovalidate-cc//deps:patches/cel_cpp/0001-Allow-message-field-access-using-index-operator.patch",
38-
"@protovalidate-cc//deps:patches/cel_cpp/0002-Add-missing-include-for-absl-StrCat.patch",
39-
"@protovalidate-cc//deps:patches/cel_cpp/0003-Fix-build-on-Windows-MSVC.patch",
37+
"@protovalidate-cc//deps:patches/cel_cpp/0001-Fix-build-on-Windows-MSVC.patch",
4038
],
4139
patch_args=["-p1"],
4240
urls = [
4341
"https://github.com/google/cel-cpp/archive/v0.11.0.tar.gz"
4442
]
4543
)
4644

47-
bazel_dep(name = "protovalidate", version = "0.10.6", repo_name = "com_github_bufbuild_protovalidate")
45+
bazel_dep(name = "protovalidate", version = "0.11.0", repo_name = "com_github_bufbuild_protovalidate")

MODULE.bazel.lock

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MODULE.bazel.tmpl

+1-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ archive_override(
3434
module_name = "cel-cpp",
3535
strip_prefix = "cel-cpp-{{cel_cpp.meta.version}}",
3636
patches=[
37-
"@protovalidate-cc//deps:patches/cel_cpp/0001-Allow-message-field-access-using-index-operator.patch",
38-
"@protovalidate-cc//deps:patches/cel_cpp/0002-Add-missing-include-for-absl-StrCat.patch",
39-
"@protovalidate-cc//deps:patches/cel_cpp/0003-Fix-build-on-Windows-MSVC.patch",
37+
"@protovalidate-cc//deps:patches/cel_cpp/0001-Fix-build-on-Windows-MSVC.patch",
4038
],
4139
patch_args=["-p1"],
4240
urls = [

bazel/deps.bzl

+1-3
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,7 @@ cc_library(
101101
"com_google_cel_cpp": shared_dep(
102102
name="cel_cpp",
103103
patches=[
104-
"@com_github_bufbuild_protovalidate_cc//deps:patches/cel_cpp/0001-Allow-message-field-access-using-index-operator.patch",
105-
"@com_github_bufbuild_protovalidate_cc//deps:patches/cel_cpp/0002-Add-missing-include-for-absl-StrCat.patch",
106-
"@com_github_bufbuild_protovalidate_cc//deps:patches/cel_cpp/0003-Fix-build-on-Windows-MSVC.patch",
104+
"@com_github_bufbuild_protovalidate_cc//deps:patches/cel_cpp/0001-Fix-build-on-Windows-MSVC.patch",
107105
],
108106
patch_args=["-p1"],
109107
),

buf/validate/BUILD.bazel

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ cc_test(
3030
deps = [
3131
":validator",
3232
"@com_github_bufbuild_protovalidate//proto/protovalidate-testing/buf/validate/conformance/cases:buf_validate_conformance_cases_proto_cc",
33-
"@com_github_bufbuild_protovalidate//proto/protovalidate-testing/buf/validate/conformance/cases/custom_constraints:buf_validate_conformance_cases_custom_constraints_cc_proto",
33+
"@com_github_bufbuild_protovalidate//proto/protovalidate-testing/buf/validate/conformance/cases/custom_rules:buf_validate_conformance_cases_custom_rules_cc_proto",
3434
"@com_google_cel_cpp//eval/public:activation",
3535
"@com_google_cel_cpp//eval/public:builtin_func_registrar",
3636
"@com_google_cel_cpp//eval/public:cel_expr_builder_factory",

buf/validate/internal/BUILD.bazel

+2
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ cc_library(
139139
"@com_google_absl//absl/status",
140140
"@com_google_cel_cpp//eval/public:cel_function_adapter",
141141
"@com_google_cel_cpp//eval/public:cel_function_registry",
142+
"@com_google_cel_cpp//eval/public/containers:field_access",
143+
"@com_google_cel_cpp//eval/public/containers:field_backed_list_impl",
142144
"@com_google_cel_cpp//eval/public/containers:container_backed_map_impl",
143145
"@com_googlesource_code_re2//:re2",
144146
],

buf/validate/internal/cel_constraint_rules.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ absl::Status ProcessConstraint(
4040
// Add violation with the constraint message.
4141
Violation violation;
4242
violation.set_message(expr.constraint.message());
43-
violation.set_constraint_id(expr.constraint.id());
43+
violation.set_rule_id(expr.constraint.id());
4444
if (expr.rulePath.has_value()) {
4545
*violation.mutable_rule() = *expr.rulePath;
4646
}
@@ -51,7 +51,7 @@ absl::Status ProcessConstraint(
5151
// Add violation with custom message.
5252
Violation violation;
5353
violation.set_message(std::string(result.StringOrDie().value()));
54-
violation.set_constraint_id(expr.constraint.id());
54+
violation.set_rule_id(expr.constraint.id());
5555
if (expr.rulePath.has_value()) {
5656
*violation.mutable_rule() = *expr.rulePath;
5757
}
@@ -89,7 +89,7 @@ cel::runtime::CelValue ProtoFieldToCelValue(
8989

9090
absl::Status CelConstraintRules::Add(
9191
google::api::expr::runtime::CelExpressionBuilder& builder,
92-
Constraint constraint,
92+
Rule constraint,
9393
absl::optional<FieldPath> rulePath,
9494
const google::protobuf::FieldDescriptor* rule) {
9595
auto pexpr_or = cel::parser::Parse(constraint.expression());
@@ -113,7 +113,7 @@ absl::Status CelConstraintRules::Add(
113113
std::string_view expression,
114114
absl::optional<FieldPath> rulePath,
115115
const google::protobuf::FieldDescriptor* rule) {
116-
Constraint constraint;
116+
Rule constraint;
117117
*constraint.mutable_id() = id;
118118
*constraint.mutable_message() = message;
119119
*constraint.mutable_expression() = expression;

buf/validate/internal/cel_constraint_rules.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace buf::validate::internal {
2626

2727
// A compiled constraint expression.
2828
struct CompiledConstraint {
29-
buf::validate::Constraint constraint;
29+
buf::validate::Rule constraint;
3030
std::unique_ptr<google::api::expr::runtime::CelExpression> expr;
3131
const absl::optional<FieldPath> rulePath;
3232
const google::protobuf::FieldDescriptor* rule;
@@ -41,7 +41,7 @@ class CelConstraintRules : public ConstraintRules {
4141

4242
absl::Status Add(
4343
google::api::expr::runtime::CelExpressionBuilder& builder,
44-
Constraint constraint,
44+
Rule constraint,
4545
absl::optional<FieldPath> rulePath,
4646
const google::protobuf::FieldDescriptor* rule);
4747
absl::Status Add(

buf/validate/internal/cel_rules.h

+22-22
Original file line numberDiff line numberDiff line change
@@ -33,27 +33,27 @@ constexpr int ruleFieldNumber() = delete;
3333
return fieldNumber; \
3434
}
3535

36-
MAP_RULES_TO_FIELD_NUMBER(FloatRules, FieldConstraints::kFloatFieldNumber)
37-
MAP_RULES_TO_FIELD_NUMBER(DoubleRules, FieldConstraints::kDoubleFieldNumber)
38-
MAP_RULES_TO_FIELD_NUMBER(Int32Rules, FieldConstraints::kInt32FieldNumber)
39-
MAP_RULES_TO_FIELD_NUMBER(Int64Rules, FieldConstraints::kInt64FieldNumber)
40-
MAP_RULES_TO_FIELD_NUMBER(UInt32Rules, FieldConstraints::kUint32FieldNumber)
41-
MAP_RULES_TO_FIELD_NUMBER(UInt64Rules, FieldConstraints::kUint64FieldNumber)
42-
MAP_RULES_TO_FIELD_NUMBER(SInt32Rules, FieldConstraints::kSint32FieldNumber)
43-
MAP_RULES_TO_FIELD_NUMBER(SInt64Rules, FieldConstraints::kSint64FieldNumber)
44-
MAP_RULES_TO_FIELD_NUMBER(Fixed32Rules, FieldConstraints::kFixed32FieldNumber)
45-
MAP_RULES_TO_FIELD_NUMBER(Fixed64Rules, FieldConstraints::kFixed64FieldNumber)
46-
MAP_RULES_TO_FIELD_NUMBER(SFixed32Rules, FieldConstraints::kSfixed32FieldNumber)
47-
MAP_RULES_TO_FIELD_NUMBER(SFixed64Rules, FieldConstraints::kSfixed64FieldNumber)
48-
MAP_RULES_TO_FIELD_NUMBER(BoolRules, FieldConstraints::kBoolFieldNumber)
49-
MAP_RULES_TO_FIELD_NUMBER(StringRules, FieldConstraints::kStringFieldNumber)
50-
MAP_RULES_TO_FIELD_NUMBER(BytesRules, FieldConstraints::kBytesFieldNumber)
51-
MAP_RULES_TO_FIELD_NUMBER(EnumRules, FieldConstraints::kEnumFieldNumber)
52-
MAP_RULES_TO_FIELD_NUMBER(RepeatedRules, FieldConstraints::kRepeatedFieldNumber)
53-
MAP_RULES_TO_FIELD_NUMBER(MapRules, FieldConstraints::kMapFieldNumber)
54-
MAP_RULES_TO_FIELD_NUMBER(AnyRules, FieldConstraints::kAnyFieldNumber)
55-
MAP_RULES_TO_FIELD_NUMBER(DurationRules, FieldConstraints::kDurationFieldNumber)
56-
MAP_RULES_TO_FIELD_NUMBER(TimestampRules, FieldConstraints::kTimestampFieldNumber)
36+
MAP_RULES_TO_FIELD_NUMBER(FloatRules, FieldRules::kFloatFieldNumber)
37+
MAP_RULES_TO_FIELD_NUMBER(DoubleRules, FieldRules::kDoubleFieldNumber)
38+
MAP_RULES_TO_FIELD_NUMBER(Int32Rules, FieldRules::kInt32FieldNumber)
39+
MAP_RULES_TO_FIELD_NUMBER(Int64Rules, FieldRules::kInt64FieldNumber)
40+
MAP_RULES_TO_FIELD_NUMBER(UInt32Rules, FieldRules::kUint32FieldNumber)
41+
MAP_RULES_TO_FIELD_NUMBER(UInt64Rules, FieldRules::kUint64FieldNumber)
42+
MAP_RULES_TO_FIELD_NUMBER(SInt32Rules, FieldRules::kSint32FieldNumber)
43+
MAP_RULES_TO_FIELD_NUMBER(SInt64Rules, FieldRules::kSint64FieldNumber)
44+
MAP_RULES_TO_FIELD_NUMBER(Fixed32Rules, FieldRules::kFixed32FieldNumber)
45+
MAP_RULES_TO_FIELD_NUMBER(Fixed64Rules, FieldRules::kFixed64FieldNumber)
46+
MAP_RULES_TO_FIELD_NUMBER(SFixed32Rules, FieldRules::kSfixed32FieldNumber)
47+
MAP_RULES_TO_FIELD_NUMBER(SFixed64Rules, FieldRules::kSfixed64FieldNumber)
48+
MAP_RULES_TO_FIELD_NUMBER(BoolRules, FieldRules::kBoolFieldNumber)
49+
MAP_RULES_TO_FIELD_NUMBER(StringRules, FieldRules::kStringFieldNumber)
50+
MAP_RULES_TO_FIELD_NUMBER(BytesRules, FieldRules::kBytesFieldNumber)
51+
MAP_RULES_TO_FIELD_NUMBER(EnumRules, FieldRules::kEnumFieldNumber)
52+
MAP_RULES_TO_FIELD_NUMBER(RepeatedRules, FieldRules::kRepeatedFieldNumber)
53+
MAP_RULES_TO_FIELD_NUMBER(MapRules, FieldRules::kMapFieldNumber)
54+
MAP_RULES_TO_FIELD_NUMBER(AnyRules, FieldRules::kAnyFieldNumber)
55+
MAP_RULES_TO_FIELD_NUMBER(DurationRules, FieldRules::kDurationFieldNumber)
56+
MAP_RULES_TO_FIELD_NUMBER(TimestampRules, FieldRules::kTimestampFieldNumber)
5757

5858
#undef MAP_RULES_TO_FIELD_NUMBER
5959

@@ -97,7 +97,7 @@ absl::Status BuildCelRules(
9797
FieldPath rulePath;
9898
*rulePath.mutable_elements()->Add() = fieldPathElement(field);
9999
*rulePath.mutable_elements()->Add() =
100-
staticFieldPathElement<FieldConstraints, ruleFieldNumber<R>()>();
100+
staticFieldPathElement<FieldRules, ruleFieldNumber<R>()>();
101101
if (!field->options().HasExtension(buf::validate::predefined)) {
102102
continue;
103103
}

buf/validate/internal/constraints.cc

+18-18
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ absl::Status MessageConstraintRules::Validate(
127127
absl::Status FieldConstraintRules::Validate(
128128
ConstraintContext& ctx, const google::protobuf::Message& message) const {
129129
static const google::protobuf::FieldDescriptor* requiredField =
130-
FieldConstraints::descriptor()->FindFieldByNumber(
131-
FieldConstraints::kRequiredFieldNumber);
130+
FieldRules::descriptor()->FindFieldByNumber(
131+
FieldRules::kRequiredFieldNumber);
132132
google::api::expr::runtime::Activation activation;
133133
cel::runtime::CelValue result;
134134
std::string subPath;
@@ -141,11 +141,11 @@ absl::Status FieldConstraintRules::Validate(
141141
return absl::OkStatus();
142142
} else if (required_) {
143143
Violation violation;
144-
*violation.mutable_constraint_id() = "required";
144+
*violation.mutable_rule_id() = "required";
145145
*violation.mutable_message() = "value is required";
146146
*violation.mutable_field()->mutable_elements()->Add() = fieldPathElement(field_);
147147
*violation.mutable_rule()->mutable_elements()->Add() =
148-
staticFieldPathElement<FieldConstraints, FieldConstraints::kRequiredFieldNumber>();
148+
staticFieldPathElement<FieldRules, FieldRules::kRequiredFieldNumber>();
149149
ctx.violations.emplace_back(
150150
std::move(violation),
151151
ProtoField{&message, field_},
@@ -161,11 +161,11 @@ absl::Status FieldConstraintRules::Validate(
161161
return absl::OkStatus();
162162
} else if (required_) {
163163
Violation violation;
164-
*violation.mutable_constraint_id() = "required";
164+
*violation.mutable_rule_id() = "required";
165165
*violation.mutable_message() = "value is required";
166166
*violation.mutable_field()->mutable_elements()->Add() = fieldPathElement(field_);
167167
*violation.mutable_rule()->mutable_elements()->Add() =
168-
staticFieldPathElement<FieldConstraints, FieldConstraints::kRequiredFieldNumber>();
168+
staticFieldPathElement<FieldRules, FieldRules::kRequiredFieldNumber>();
169169
ctx.violations.emplace_back(
170170
std::move(violation),
171171
ProtoField{&message, field_},
@@ -176,11 +176,11 @@ absl::Status FieldConstraintRules::Validate(
176176
if (!message.GetReflection()->HasField(message, field_)) {
177177
if (required_) {
178178
Violation violation;
179-
*violation.mutable_constraint_id() = "required";
179+
*violation.mutable_rule_id() = "required";
180180
*violation.mutable_message() = "value is required";
181181
*violation.mutable_field()->mutable_elements()->Add() = fieldPathElement(field_);
182182
*violation.mutable_rule()->mutable_elements()->Add() =
183-
staticFieldPathElement<FieldConstraints, FieldConstraints::kRequiredFieldNumber>();
183+
staticFieldPathElement<FieldRules, FieldRules::kRequiredFieldNumber>();
184184
ctx.violations.emplace_back(
185185
std::move(violation),
186186
ProtoField{&message, field_},
@@ -235,11 +235,11 @@ absl::Status EnumConstraintRules::Validate(
235235
auto value = message.GetReflection()->GetEnumValue(message, field_);
236236
if (field_->enum_type()->FindValueByNumber(value) == nullptr) {
237237
Violation violation;
238-
*violation.mutable_constraint_id() = "enum.defined_only";
238+
*violation.mutable_rule_id() = "enum.defined_only";
239239
*violation.mutable_message() = "value must be one of the defined enum values";
240240
*violation.mutable_field()->mutable_elements()->Add() = fieldPathElement(field_);
241241
*violation.mutable_rule()->mutable_elements()->Add() = fieldPathElement(EnumRules::descriptor()->FindFieldByNumber(EnumRules::kDefinedOnlyFieldNumber));
242-
*violation.mutable_rule()->mutable_elements()->Add() = fieldPathElement(FieldConstraints::descriptor()->FindFieldByNumber(FieldConstraints::kEnumFieldNumber));
242+
*violation.mutable_rule()->mutable_elements()->Add() = fieldPathElement(FieldRules::descriptor()->FindFieldByNumber(FieldRules::kEnumFieldNumber));
243243
ctx.violations.emplace_back(
244244
std::move(violation),
245245
ProtoField{&message, field_},
@@ -280,7 +280,7 @@ absl::Status RepeatedConstraintRules::Validate(
280280
ctx.appendFieldPathElement(element, pos);
281281
ctx.appendRulePathElement({
282282
fieldPathElement(RepeatedRules::descriptor()->FindFieldByNumber(RepeatedRules::kItemsFieldNumber)),
283-
fieldPathElement(FieldConstraints::descriptor()->FindFieldByNumber(FieldConstraints::kRepeatedFieldNumber)),
283+
fieldPathElement(FieldRules::descriptor()->FindFieldByNumber(FieldRules::kRepeatedFieldNumber)),
284284
}, pos);
285285
ctx.setFieldValue(ProtoField{&message, field_, i}, pos);
286286
}
@@ -320,7 +320,7 @@ absl::Status MapConstraintRules::Validate(
320320
if (ctx.violations.size() > pos) {
321321
ctx.appendRulePathElement({
322322
fieldPathElement(MapRules::descriptor()->FindFieldByNumber(MapRules::kKeysFieldNumber)),
323-
fieldPathElement(FieldConstraints::descriptor()->FindFieldByNumber(FieldConstraints::kMapFieldNumber)),
323+
fieldPathElement(FieldRules::descriptor()->FindFieldByNumber(FieldRules::kMapFieldNumber)),
324324
}, pos);
325325
ctx.setFieldValue(ProtoField{&elemMsg, keyField}, pos);
326326
ctx.setForKey(pos);
@@ -340,7 +340,7 @@ absl::Status MapConstraintRules::Validate(
340340
if (ctx.violations.size() > valuePos) {
341341
ctx.appendRulePathElement({
342342
fieldPathElement(MapRules::descriptor()->FindFieldByNumber(MapRules::kValuesFieldNumber)),
343-
fieldPathElement(FieldConstraints::descriptor()->FindFieldByNumber(FieldConstraints::kMapFieldNumber)),
343+
fieldPathElement(FieldRules::descriptor()->FindFieldByNumber(FieldRules::kMapFieldNumber)),
344344
}, valuePos);
345345
ctx.setFieldValue(ProtoField{&elemMsg, valueField}, pos);
346346
}
@@ -389,15 +389,15 @@ absl::Status FieldConstraintRules::ValidateAny(
389389
}
390390
if (!found) {
391391
Violation violation;
392-
*violation.mutable_constraint_id() = "any.in";
392+
*violation.mutable_rule_id() = "any.in";
393393
*violation.mutable_message() = "type URL must be in the allow list";
394394
if (field.index() == -1) {
395395
*violation.mutable_field()->mutable_elements()->Add() = fieldPathElement(field.descriptor());
396396
}
397397
*violation.mutable_rule()->mutable_elements()->Add() =
398398
staticFieldPathElement<AnyRules, AnyRules::kInFieldNumber>();
399399
*violation.mutable_rule()->mutable_elements()->Add() =
400-
staticFieldPathElement<FieldConstraints, FieldConstraints::kAnyFieldNumber>();
400+
staticFieldPathElement<FieldRules, FieldRules::kAnyFieldNumber>();
401401
ctx.violations.emplace_back(
402402
std::move(violation),
403403
field,
@@ -407,15 +407,15 @@ absl::Status FieldConstraintRules::ValidateAny(
407407
for (const auto& block : anyRules_->not_in()) {
408408
if (block == typeUri) {
409409
Violation violation;
410-
*violation.mutable_constraint_id() = "any.not_in";
410+
*violation.mutable_rule_id() = "any.not_in";
411411
*violation.mutable_message() = "type URL must not be in the block list";
412412
if (field.index() == -1) {
413413
*violation.mutable_field()->mutable_elements()->Add() = fieldPathElement(field.descriptor());
414414
}
415415
*violation.mutable_rule()->mutable_elements()->Add() =
416416
staticFieldPathElement<AnyRules, AnyRules::kNotInFieldNumber>();
417417
*violation.mutable_rule()->mutable_elements()->Add() =
418-
staticFieldPathElement<FieldConstraints, FieldConstraints::kAnyFieldNumber>();
418+
staticFieldPathElement<FieldRules, FieldRules::kAnyFieldNumber>();
419419
ctx.violations.emplace_back(
420420
std::move(violation),
421421
field,
@@ -432,7 +432,7 @@ absl::Status OneofConstraintRules::Validate(
432432
if (required_) {
433433
if (!message.GetReflection()->HasOneof(message, oneof_)) {
434434
Violation violation;
435-
*violation.mutable_constraint_id() = "required";
435+
*violation.mutable_rule_id() = "required";
436436
*violation.mutable_message() = "exactly one field is required in oneof";
437437
*violation.mutable_field()->mutable_elements()->Add() = oneofPathElement(*oneof_);
438438
ctx.violations.emplace_back(std::move(violation), absl::nullopt, absl::nullopt);

0 commit comments

Comments
 (0)