violations = new ArrayList<>();
for (CompiledProgram program : programs) {
- ConstraintViolation.Builder violation = program.eval(val, activation);
+ RuleViolation.Builder violation = program.eval(val, activation);
if (violation != null) {
violations.add(violation);
if (failFast) {
diff --git a/src/main/java/build/buf/protovalidate/CompiledProgram.java b/src/main/java/build/buf/protovalidate/CompiledProgram.java
index d9343ccc..3fac0d33 100644
--- a/src/main/java/build/buf/protovalidate/CompiledProgram.java
+++ b/src/main/java/build/buf/protovalidate/CompiledProgram.java
@@ -32,7 +32,7 @@ class CompiledProgram {
/** The original expression that was compiled into the program from the proto file. */
private final Expression source;
- /** The field path from FieldConstraints to the constraint rule value. */
+ /** The field path from FieldRules to the rule value. */
@Nullable private final FieldPath rulePath;
/** The rule value. */
@@ -43,7 +43,7 @@ class CompiledProgram {
*
* @param program The compiled CEL program.
* @param source The original expression that was compiled into the program.
- * @param rulePath The field path from the FieldConstraints to the rule value.
+ * @param rulePath The field path from the FieldRules to the rule value.
* @param ruleValue The rule value.
*/
public CompiledProgram(
@@ -63,7 +63,7 @@ public CompiledProgram(
* violations.
* @throws ExecutionException If the evaluation of the CEL program fails with an error.
*/
- public ConstraintViolation.@Nullable Builder eval(Value fieldValue, Variable bindings)
+ public RuleViolation.@Nullable Builder eval(Value fieldValue, Variable bindings)
throws ExecutionException {
Program.EvalResult evalResult = program.eval(bindings);
Val val = evalResult.getVal();
@@ -75,33 +75,29 @@ public CompiledProgram(
if ("".equals(value)) {
return null;
}
- ConstraintViolation.Builder builder =
- ConstraintViolation.newBuilder()
- .setConstraintId(this.source.id)
- .setMessage(value.toString());
+ RuleViolation.Builder builder =
+ RuleViolation.newBuilder().setRuleId(this.source.id).setMessage(value.toString());
if (fieldValue.fieldDescriptor() != null) {
- builder.setFieldValue(new ConstraintViolation.FieldValue(fieldValue));
+ builder.setFieldValue(new RuleViolation.FieldValue(fieldValue));
}
if (rulePath != null) {
builder.addAllRulePathElements(rulePath.getElementsList());
}
if (ruleValue != null && ruleValue.fieldDescriptor() != null) {
- builder.setRuleValue(new ConstraintViolation.FieldValue(ruleValue));
+ builder.setRuleValue(new RuleViolation.FieldValue(ruleValue));
}
return builder;
} else if (value instanceof Boolean) {
if (val.booleanValue()) {
return null;
}
- ConstraintViolation.Builder builder =
- ConstraintViolation.newBuilder()
- .setConstraintId(this.source.id)
- .setMessage(this.source.message);
+ RuleViolation.Builder builder =
+ RuleViolation.newBuilder().setRuleId(this.source.id).setMessage(this.source.message);
if (rulePath != null) {
builder.addAllRulePathElements(rulePath.getElementsList());
}
if (ruleValue != null && ruleValue.fieldDescriptor() != null) {
- builder.setRuleValue(new ConstraintViolation.FieldValue(ruleValue));
+ builder.setRuleValue(new RuleViolation.FieldValue(ruleValue));
}
return builder;
} else {
diff --git a/src/main/java/build/buf/protovalidate/Config.java b/src/main/java/build/buf/protovalidate/Config.java
index 559b5b80..7c9f3ea7 100644
--- a/src/main/java/build/buf/protovalidate/Config.java
+++ b/src/main/java/build/buf/protovalidate/Config.java
@@ -88,9 +88,9 @@ public ExtensionRegistry getExtensionRegistry() {
}
/**
- * Checks if the configuration for allowing unknown constraint fields is enabled.
+ * Checks if the configuration for allowing unknown rule fields is enabled.
*
- * @return if allowing unknown constraint fields is enabled
+ * @return if allowing unknown rule fields is enabled
*/
public boolean isAllowingUnknownFields() {
return allowUnknownFields;
@@ -132,8 +132,8 @@ public Builder setDisableLazy(boolean disableLazy) {
* Set the type registry for reparsing protobuf messages. This option should be set alongside
* setExtensionRegistry to allow dynamic resolution of predefined rule extensions. It should be
* set to a TypeRegistry with all the message types from your file descriptor set registered. By
- * default, if any unknown field constraints are found, compilation of the constraints will
- * fail; use setAllowUnknownFields to control this behavior.
+ * default, if any unknown field rules are found, compilation of the rules will fail; use
+ * setAllowUnknownFields to control this behavior.
*
* Note that the message types for any extensions in setExtensionRegistry must be present in
* the typeRegistry, and have an exactly-equal Descriptor. If the type registry is not set, the
@@ -154,8 +154,8 @@ public Builder setTypeRegistry(TypeRegistry typeRegistry) {
* Set the extension registry for resolving unknown extensions. This option should be set
* alongside setTypeRegistry to allow dynamic resolution of predefined rule extensions. It
* should be set to an ExtensionRegistry with all the extension types from your file descriptor
- * set registered. By default, if any unknown field constraints are found, compilation of the
- * constraints will fail; use setAllowUnknownFields to control this behavior.
+ * set registered. By default, if any unknown field rules are found, compilation of the rules
+ * will fail; use setAllowUnknownFields to control this behavior.
*
* @param extensionRegistry the extension registry to use
* @return this builder
@@ -166,13 +166,12 @@ public Builder setExtensionRegistry(ExtensionRegistry extensionRegistry) {
}
/**
- * Set whether unknown constraint fields are allowed. If this setting is set to true, unknown
- * standard predefined field constraints and predefined field constraint extensions will be
- * ignored. This setting defaults to false, which will result in a CompilationException being
- * thrown whenever an unknown field constraint is encountered. Setting this to true will cause
- * some field constraints to be ignored; if the descriptor is dynamic, you can instead use
- * setExtensionRegistry to provide dynamic type information that protovalidate can use to
- * resolve the unknown fields.
+ * Set whether unknown rule fields are allowed. If this setting is set to true, unknown standard
+ * predefined field rules and predefined field rule extensions will be ignored. This setting
+ * defaults to false, which will result in a CompilationException being thrown whenever an
+ * unknown field rule is encountered. Setting this to true will cause some field rules to be
+ * ignored; if the descriptor is dynamic, you can instead use setExtensionRegistry to provide
+ * dynamic type information that protovalidate can use to resolve the unknown fields.
*
* @param allowUnknownFields setting to apply
* @return this builder
diff --git a/src/main/java/build/buf/protovalidate/DescriptorMappings.java b/src/main/java/build/buf/protovalidate/DescriptorMappings.java
index 20dd9490..24345811 100644
--- a/src/main/java/build/buf/protovalidate/DescriptorMappings.java
+++ b/src/main/java/build/buf/protovalidate/DescriptorMappings.java
@@ -14,7 +14,7 @@
package build.buf.protovalidate;
-import build.buf.validate.FieldConstraints;
+import build.buf.validate.FieldRules;
import com.google.api.expr.v1alpha1.Type;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
@@ -28,104 +28,98 @@
* DescriptorMappings provides mappings between protocol buffer descriptors and CEL declarations.
*/
final class DescriptorMappings {
- /** Provides a {@link Descriptor} for {@link FieldConstraints}. */
- static final Descriptor FIELD_CONSTRAINTS_DESC = FieldConstraints.getDescriptor();
+ /** Provides a {@link Descriptor} for {@link FieldRules}. */
+ static final Descriptor FIELD_RULES_DESC = FieldRules.getDescriptor();
- /** Provides the {@link OneofDescriptor} for the type union in {@link FieldConstraints}. */
- static final OneofDescriptor FIELD_CONSTRAINTS_ONEOF_DESC =
- FIELD_CONSTRAINTS_DESC.getOneofs().get(0);
+ /** Provides the {@link OneofDescriptor} for the type union in {@link FieldRules}. */
+ static final OneofDescriptor FIELD_RULES_ONEOF_DESC = FIELD_RULES_DESC.getOneofs().get(0);
- /** Provides the {@link FieldDescriptor} for the map standard constraints. */
- static final FieldDescriptor MAP_FIELD_CONSTRAINTS_DESC =
- FIELD_CONSTRAINTS_DESC.findFieldByName("map");
+ /** Provides the {@link FieldDescriptor} for the map standard rules. */
+ static final FieldDescriptor MAP_FIELD_RULES_DESC = FIELD_RULES_DESC.findFieldByName("map");
- /** Provides the {@link FieldDescriptor} for the repeated standard constraints. */
- static final FieldDescriptor REPEATED_FIELD_CONSTRAINTS_DESC =
- FIELD_CONSTRAINTS_DESC.findFieldByName("repeated");
+ /** Provides the {@link FieldDescriptor} for the repeated standard rules. */
+ static final FieldDescriptor REPEATED_FIELD_RULES_DESC =
+ FIELD_RULES_DESC.findFieldByName("repeated");
- /** Maps protocol buffer field kinds to their expected field constraints. */
- static final Map EXPECTED_STANDARD_CONSTRAINTS =
- new HashMap<>();
+ /** Maps protocol buffer field kinds to their expected field rules. */
+ static final Map EXPECTED_STANDARD_RULES = new HashMap<>();
/**
- * Returns the {@link build.buf.validate.FieldConstraints} field that is expected for the given
- * wrapper well-known type's full name. If ok is false, no standard constraints exist for that
- * type.
+ * Returns the {@link build.buf.validate.FieldRules} field that is expected for the given wrapper
+ * well-known type's full name. If ok is false, no standard rules exist for that type.
*/
- static final Map EXPECTED_WKT_CONSTRAINTS = new HashMap<>();
+ static final Map EXPECTED_WKT_RULES = new HashMap<>();
static {
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.FLOAT, FIELD_CONSTRAINTS_DESC.findFieldByName("float"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.DOUBLE, FIELD_CONSTRAINTS_DESC.findFieldByName("double"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.INT32, FIELD_CONSTRAINTS_DESC.findFieldByName("int32"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.INT64, FIELD_CONSTRAINTS_DESC.findFieldByName("int64"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.UINT32, FIELD_CONSTRAINTS_DESC.findFieldByName("uint32"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.UINT64, FIELD_CONSTRAINTS_DESC.findFieldByName("uint64"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.SINT32, FIELD_CONSTRAINTS_DESC.findFieldByName("sint32"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.SINT64, FIELD_CONSTRAINTS_DESC.findFieldByName("sint64"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.FIXED32, FIELD_CONSTRAINTS_DESC.findFieldByName("fixed32"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.FIXED64, FIELD_CONSTRAINTS_DESC.findFieldByName("fixed64"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.SFIXED32, FIELD_CONSTRAINTS_DESC.findFieldByName("sfixed32"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.SFIXED64, FIELD_CONSTRAINTS_DESC.findFieldByName("sfixed64"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.BOOL, FIELD_CONSTRAINTS_DESC.findFieldByName("bool"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.STRING, FIELD_CONSTRAINTS_DESC.findFieldByName("string"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.BYTES, FIELD_CONSTRAINTS_DESC.findFieldByName("bytes"));
- EXPECTED_STANDARD_CONSTRAINTS.put(
- FieldDescriptor.Type.ENUM, FIELD_CONSTRAINTS_DESC.findFieldByName("enum"));
-
- EXPECTED_WKT_CONSTRAINTS.put(
- "google.protobuf.Any", FIELD_CONSTRAINTS_DESC.findFieldByName("any"));
- EXPECTED_WKT_CONSTRAINTS.put(
- "google.protobuf.Duration", FIELD_CONSTRAINTS_DESC.findFieldByName("duration"));
- EXPECTED_WKT_CONSTRAINTS.put(
- "google.protobuf.Timestamp", FIELD_CONSTRAINTS_DESC.findFieldByName("timestamp"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.FLOAT, FIELD_RULES_DESC.findFieldByName("float"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.DOUBLE, FIELD_RULES_DESC.findFieldByName("double"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.INT32, FIELD_RULES_DESC.findFieldByName("int32"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.INT64, FIELD_RULES_DESC.findFieldByName("int64"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.UINT32, FIELD_RULES_DESC.findFieldByName("uint32"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.UINT64, FIELD_RULES_DESC.findFieldByName("uint64"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.SINT32, FIELD_RULES_DESC.findFieldByName("sint32"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.SINT64, FIELD_RULES_DESC.findFieldByName("sint64"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.FIXED32, FIELD_RULES_DESC.findFieldByName("fixed32"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.FIXED64, FIELD_RULES_DESC.findFieldByName("fixed64"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.SFIXED32, FIELD_RULES_DESC.findFieldByName("sfixed32"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.SFIXED64, FIELD_RULES_DESC.findFieldByName("sfixed64"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.BOOL, FIELD_RULES_DESC.findFieldByName("bool"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.STRING, FIELD_RULES_DESC.findFieldByName("string"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.BYTES, FIELD_RULES_DESC.findFieldByName("bytes"));
+ EXPECTED_STANDARD_RULES.put(
+ FieldDescriptor.Type.ENUM, FIELD_RULES_DESC.findFieldByName("enum"));
+
+ EXPECTED_WKT_RULES.put("google.protobuf.Any", FIELD_RULES_DESC.findFieldByName("any"));
+ EXPECTED_WKT_RULES.put(
+ "google.protobuf.Duration", FIELD_RULES_DESC.findFieldByName("duration"));
+ EXPECTED_WKT_RULES.put(
+ "google.protobuf.Timestamp", FIELD_RULES_DESC.findFieldByName("timestamp"));
}
private DescriptorMappings() {}
/**
- * Returns the {@link FieldConstraints} field that is expected for the given protocol buffer field
- * kind.
+ * Returns the {@link FieldRules} field that is expected for the given protocol buffer field kind.
*
* @param fqn Fully qualified name of protobuf value wrapper.
- * @return The constraints field descriptor for the specified wrapper fully qualified name.
+ * @return The rules field descriptor for the specified wrapper fully qualified name.
*/
@Nullable
- public static FieldDescriptor expectedWrapperConstraints(String fqn) {
+ public static FieldDescriptor expectedWrapperRules(String fqn) {
switch (fqn) {
case "google.protobuf.BoolValue":
- return EXPECTED_STANDARD_CONSTRAINTS.get(FieldDescriptor.Type.BOOL);
+ return EXPECTED_STANDARD_RULES.get(FieldDescriptor.Type.BOOL);
case "google.protobuf.BytesValue":
- return EXPECTED_STANDARD_CONSTRAINTS.get(FieldDescriptor.Type.BYTES);
+ return EXPECTED_STANDARD_RULES.get(FieldDescriptor.Type.BYTES);
case "google.protobuf.DoubleValue":
- return EXPECTED_STANDARD_CONSTRAINTS.get(FieldDescriptor.Type.DOUBLE);
+ return EXPECTED_STANDARD_RULES.get(FieldDescriptor.Type.DOUBLE);
case "google.protobuf.FloatValue":
- return EXPECTED_STANDARD_CONSTRAINTS.get(FieldDescriptor.Type.FLOAT);
+ return EXPECTED_STANDARD_RULES.get(FieldDescriptor.Type.FLOAT);
case "google.protobuf.Int32Value":
- return EXPECTED_STANDARD_CONSTRAINTS.get(FieldDescriptor.Type.INT32);
+ return EXPECTED_STANDARD_RULES.get(FieldDescriptor.Type.INT32);
case "google.protobuf.Int64Value":
- return EXPECTED_STANDARD_CONSTRAINTS.get(FieldDescriptor.Type.INT64);
+ return EXPECTED_STANDARD_RULES.get(FieldDescriptor.Type.INT64);
case "google.protobuf.StringValue":
- return EXPECTED_STANDARD_CONSTRAINTS.get(FieldDescriptor.Type.STRING);
+ return EXPECTED_STANDARD_RULES.get(FieldDescriptor.Type.STRING);
case "google.protobuf.UInt32Value":
- return EXPECTED_STANDARD_CONSTRAINTS.get(FieldDescriptor.Type.UINT32);
+ return EXPECTED_STANDARD_RULES.get(FieldDescriptor.Type.UINT32);
case "google.protobuf.UInt64Value":
- return EXPECTED_STANDARD_CONSTRAINTS.get(FieldDescriptor.Type.UINT64);
+ return EXPECTED_STANDARD_RULES.get(FieldDescriptor.Type.UINT64);
default:
return null;
}
@@ -172,22 +166,22 @@ public static Type protoKindToCELType(FieldDescriptor.Type kind) {
}
/**
- * Produces the field descriptor from the {@link FieldConstraints} 'type' oneof that matches the
+ * Produces the field descriptor from the {@link FieldRules} 'type' oneof that matches the
* provided target field descriptor. If the returned value is null, the field does not expect any
- * standard constraints.
+ * standard rules.
*/
@Nullable
- static FieldDescriptor getExpectedConstraintDescriptor(
+ static FieldDescriptor getExpectedRuleDescriptor(
FieldDescriptor fieldDescriptor, boolean forItems) {
if (fieldDescriptor.isMapField()) {
- return DescriptorMappings.MAP_FIELD_CONSTRAINTS_DESC;
+ return DescriptorMappings.MAP_FIELD_RULES_DESC;
} else if (fieldDescriptor.isRepeated() && !forItems) {
- return DescriptorMappings.REPEATED_FIELD_CONSTRAINTS_DESC;
+ return DescriptorMappings.REPEATED_FIELD_RULES_DESC;
} else if (fieldDescriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
- return DescriptorMappings.EXPECTED_WKT_CONSTRAINTS.get(
+ return DescriptorMappings.EXPECTED_WKT_RULES.get(
fieldDescriptor.getMessageType().getFullName());
} else {
- return DescriptorMappings.EXPECTED_STANDARD_CONSTRAINTS.get(fieldDescriptor.getType());
+ return DescriptorMappings.EXPECTED_STANDARD_RULES.get(fieldDescriptor.getType());
}
}
diff --git a/src/main/java/build/buf/protovalidate/EmbeddedMessageEvaluator.java b/src/main/java/build/buf/protovalidate/EmbeddedMessageEvaluator.java
index 297688e8..35b005a7 100644
--- a/src/main/java/build/buf/protovalidate/EmbeddedMessageEvaluator.java
+++ b/src/main/java/build/buf/protovalidate/EmbeddedMessageEvaluator.java
@@ -19,11 +19,11 @@
import java.util.List;
class EmbeddedMessageEvaluator implements Evaluator {
- private final ConstraintViolationHelper helper;
+ private final RuleViolationHelper helper;
private final MessageEvaluator messageEvaluator;
EmbeddedMessageEvaluator(ValueEvaluator valueEvaluator, MessageEvaluator messageEvaluator) {
- this.helper = new ConstraintViolationHelper(valueEvaluator);
+ this.helper = new RuleViolationHelper(valueEvaluator);
this.messageEvaluator = messageEvaluator;
}
@@ -33,7 +33,7 @@ public boolean tautology() {
}
@Override
- public List evaluate(Value val, boolean failFast)
+ public List evaluate(Value val, boolean failFast)
throws ExecutionException {
return FieldPathUtils.updatePaths(
messageEvaluator.evaluate(val, failFast),
diff --git a/src/main/java/build/buf/protovalidate/EnumEvaluator.java b/src/main/java/build/buf/protovalidate/EnumEvaluator.java
index ec588d82..e2484983 100644
--- a/src/main/java/build/buf/protovalidate/EnumEvaluator.java
+++ b/src/main/java/build/buf/protovalidate/EnumEvaluator.java
@@ -16,8 +16,8 @@
import build.buf.protovalidate.exceptions.ExecutionException;
import build.buf.validate.EnumRules;
-import build.buf.validate.FieldConstraints;
import build.buf.validate.FieldPath;
+import build.buf.validate.FieldRules;
import com.google.protobuf.Descriptors;
import java.util.Collections;
import java.util.List;
@@ -29,7 +29,7 @@
* check is handled outside CEL as enums are completely type erased to integers.
*/
class EnumEvaluator implements Evaluator {
- private final ConstraintViolationHelper helper;
+ private final RuleViolationHelper helper;
/** Captures all the defined values for this enum */
private final Set values;
@@ -41,8 +41,7 @@ class EnumEvaluator implements Evaluator {
FieldPath.newBuilder()
.addElements(
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor()
- .findFieldByNumber(FieldConstraints.ENUM_FIELD_NUMBER)))
+ FieldRules.getDescriptor().findFieldByNumber(FieldRules.ENUM_FIELD_NUMBER)))
.addElements(FieldPathUtils.fieldPathElement(DEFINED_ONLY_DESCRIPTOR))
.build();
@@ -53,7 +52,7 @@ class EnumEvaluator implements Evaluator {
*/
EnumEvaluator(
ValueEvaluator valueEvaluator, List valueDescriptors) {
- this.helper = new ConstraintViolationHelper(valueEvaluator);
+ this.helper = new RuleViolationHelper(valueEvaluator);
if (valueDescriptors.isEmpty()) {
this.values = Collections.emptySet();
} else {
@@ -78,23 +77,23 @@ public boolean tautology() {
* @throws ExecutionException if an error occurs during the evaluation.
*/
@Override
- public List evaluate(Value val, boolean failFast)
+ public List evaluate(Value val, boolean failFast)
throws ExecutionException {
Descriptors.EnumValueDescriptor enumValue = val.value(Descriptors.EnumValueDescriptor.class);
if (enumValue == null) {
- return ConstraintViolation.NO_VIOLATIONS;
+ return RuleViolation.NO_VIOLATIONS;
}
if (!values.contains(enumValue.getNumber())) {
return Collections.singletonList(
- ConstraintViolation.newBuilder()
+ RuleViolation.newBuilder()
.addAllRulePathElements(helper.getRulePrefixElements())
.addAllRulePathElements(DEFINED_ONLY_RULE_PATH.getElementsList())
.addFirstFieldPathElement(helper.getFieldPathElement())
- .setConstraintId("enum.defined_only")
+ .setRuleId("enum.defined_only")
.setMessage("value must be one of the defined enum values")
- .setFieldValue(new ConstraintViolation.FieldValue(val))
- .setRuleValue(new ConstraintViolation.FieldValue(true, DEFINED_ONLY_DESCRIPTOR)));
+ .setFieldValue(new RuleViolation.FieldValue(val))
+ .setRuleValue(new RuleViolation.FieldValue(true, DEFINED_ONLY_DESCRIPTOR)));
}
- return ConstraintViolation.NO_VIOLATIONS;
+ return RuleViolation.NO_VIOLATIONS;
}
}
diff --git a/src/main/java/build/buf/protovalidate/Evaluator.java b/src/main/java/build/buf/protovalidate/Evaluator.java
index bb30a83c..a12e6c89 100644
--- a/src/main/java/build/buf/protovalidate/Evaluator.java
+++ b/src/main/java/build/buf/protovalidate/Evaluator.java
@@ -31,13 +31,12 @@ interface Evaluator {
/**
* Checks that the provided val is valid. Unless failFast is true, evaluation attempts to find all
- * {@link ConstraintViolation} present in val instead of returning only the first {@link
- * ConstraintViolation}.
+ * {@link RuleViolation} present in val instead of returning only the first {@link RuleViolation}.
*
* @param val The value to validate.
* @param failFast If true, validation stops after the first failure.
* @return The result of validation on the specified value.
* @throws ExecutionException If evaluation fails to complete.
*/
- List evaluate(Value val, boolean failFast) throws ExecutionException;
+ List evaluate(Value val, boolean failFast) throws ExecutionException;
}
diff --git a/src/main/java/build/buf/protovalidate/EvaluatorBuilder.java b/src/main/java/build/buf/protovalidate/EvaluatorBuilder.java
index 0d7040a8..7ec99a58 100644
--- a/src/main/java/build/buf/protovalidate/EvaluatorBuilder.java
+++ b/src/main/java/build/buf/protovalidate/EvaluatorBuilder.java
@@ -15,13 +15,13 @@
package build.buf.protovalidate;
import build.buf.protovalidate.exceptions.CompilationException;
-import build.buf.validate.Constraint;
-import build.buf.validate.FieldConstraints;
import build.buf.validate.FieldPath;
import build.buf.validate.FieldPathElement;
+import build.buf.validate.FieldRules;
import build.buf.validate.Ignore;
-import build.buf.validate.MessageConstraints;
-import build.buf.validate.OneofConstraints;
+import build.buf.validate.MessageRules;
+import build.buf.validate.OneofRules;
+import build.buf.validate.Rule;
import com.google.protobuf.ByteString;
import com.google.protobuf.Descriptors;
import com.google.protobuf.Descriptors.Descriptor;
@@ -45,13 +45,13 @@
class EvaluatorBuilder {
private static final FieldPathElement CEL_FIELD_PATH_ELEMENT =
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor().findFieldByNumber(FieldConstraints.CEL_FIELD_NUMBER));
+ FieldRules.getDescriptor().findFieldByNumber(FieldRules.CEL_FIELD_NUMBER));
private volatile Map evaluatorCache = Collections.emptyMap();
private final Env env;
private final boolean disableLazy;
- private final ConstraintCache constraints;
+ private final RuleCache rules;
/**
* Constructs a new {@link EvaluatorBuilder}.
@@ -62,7 +62,7 @@ class EvaluatorBuilder {
public EvaluatorBuilder(Env env, Config config) {
this.env = env;
this.disableLazy = config.isDisableLazy();
- this.constraints = new ConstraintCache(env, config);
+ this.rules = new RuleCache(env, config);
}
/**
@@ -99,7 +99,7 @@ private Evaluator build(Descriptor desc) throws CompilationException {
}
// Rebuild cache with this descriptor (and any of its dependencies).
Map updatedCache =
- new DescriptorCacheBuilder(env, constraints, evaluatorCache).build(desc);
+ new DescriptorCacheBuilder(env, rules, evaluatorCache).build(desc);
evaluatorCache = updatedCache;
eval = updatedCache.get(desc);
if (eval == null) {
@@ -111,15 +111,15 @@ private Evaluator build(Descriptor desc) throws CompilationException {
}
private static class DescriptorCacheBuilder {
- private final ConstraintResolver resolver = new ConstraintResolver();
+ private final RuleResolver resolver = new RuleResolver();
private final Env env;
- private final ConstraintCache constraintCache;
+ private final RuleCache ruleCache;
private final HashMap cache;
private DescriptorCacheBuilder(
- Env env, ConstraintCache constraintCache, Map previousCache) {
+ Env env, RuleCache ruleCache, Map previousCache) {
this.env = Objects.requireNonNull(env, "env");
- this.constraintCache = Objects.requireNonNull(constraintCache, "constraintCache");
+ this.ruleCache = Objects.requireNonNull(ruleCache, "ruleCache");
this.cache = new HashMap<>(previousCache);
}
@@ -129,7 +129,7 @@ private DescriptorCacheBuilder(
*
* @param descriptor Descriptor used to build the cache.
* @return Unmodifiable map of descriptors to evaluators.
- * @throws CompilationException If an error occurs compiling a constraint on the cache.
+ * @throws CompilationException If an error occurs compiling a rule on the cache.
*/
public Map build(Descriptor descriptor)
throws CompilationException {
@@ -153,12 +153,12 @@ private void buildMessage(Descriptor desc, MessageEvaluator msgEval)
try {
DynamicMessage defaultInstance = DynamicMessage.newBuilder(desc).buildPartial();
Descriptor descriptor = defaultInstance.getDescriptorForType();
- MessageConstraints msgConstraints = resolver.resolveMessageConstraints(descriptor);
- if (msgConstraints.getDisabled()) {
+ MessageRules msgRules = resolver.resolveMessageRules(descriptor);
+ if (msgRules.getDisabled()) {
return;
}
- processMessageExpressions(descriptor, msgConstraints, msgEval, defaultInstance);
- processOneofConstraints(descriptor, msgEval);
+ processMessageExpressions(descriptor, msgRules, msgEval, defaultInstance);
+ processOneofRules(descriptor, msgEval);
processFields(descriptor, msgEval);
} catch (InvalidProtocolBufferException e) {
throw new CompilationException(
@@ -167,12 +167,9 @@ private void buildMessage(Descriptor desc, MessageEvaluator msgEval)
}
private void processMessageExpressions(
- Descriptor desc,
- MessageConstraints msgConstraints,
- MessageEvaluator msgEval,
- DynamicMessage message)
+ Descriptor desc, MessageRules msgRules, MessageEvaluator msgEval, DynamicMessage message)
throws CompilationException {
- List celList = msgConstraints.getCelList();
+ List celList = msgRules.getCelList();
if (celList.isEmpty()) {
return;
}
@@ -181,20 +178,19 @@ private void processMessageExpressions(
EnvOption.types(message),
EnvOption.declarations(
Decls.newVar(Variable.THIS_NAME, Decls.newObjectType(desc.getFullName()))));
- List compiledPrograms = compileConstraints(celList, finalEnv, false);
+ List compiledPrograms = compileRules(celList, finalEnv, false);
if (compiledPrograms.isEmpty()) {
throw new CompilationException("compile returned null");
}
msgEval.append(new CelPrograms(null, compiledPrograms));
}
- private void processOneofConstraints(Descriptor desc, MessageEvaluator msgEval)
+ private void processOneofRules(Descriptor desc, MessageEvaluator msgEval)
throws InvalidProtocolBufferException, CompilationException {
List oneofs = desc.getOneofs();
for (Descriptors.OneofDescriptor oneofDesc : oneofs) {
- OneofConstraints oneofConstraints = resolver.resolveOneofConstraints(oneofDesc);
- OneofEvaluator oneofEvaluatorEval =
- new OneofEvaluator(oneofDesc, oneofConstraints.getRequired());
+ OneofRules oneofRules = resolver.resolveOneofRules(oneofDesc);
+ OneofEvaluator oneofEvaluatorEval = new OneofEvaluator(oneofDesc, oneofRules.getRequired());
msgEval.append(oneofEvaluatorEval);
}
}
@@ -204,18 +200,16 @@ private void processFields(Descriptor desc, MessageEvaluator msgEval)
List fields = desc.getFields();
for (FieldDescriptor fieldDescriptor : fields) {
FieldDescriptor descriptor = desc.findFieldByName(fieldDescriptor.getName());
- FieldConstraints fieldConstraints = resolver.resolveFieldConstraints(descriptor);
- FieldEvaluator fldEval = buildField(descriptor, fieldConstraints);
+ FieldRules fieldRules = resolver.resolveFieldRules(descriptor);
+ FieldEvaluator fldEval = buildField(descriptor, fieldRules);
msgEval.append(fldEval);
}
}
- private FieldEvaluator buildField(
- FieldDescriptor fieldDescriptor, FieldConstraints fieldConstraints)
+ private FieldEvaluator buildField(FieldDescriptor fieldDescriptor, FieldRules fieldRules)
throws CompilationException {
ValueEvaluator valueEvaluatorEval = new ValueEvaluator(fieldDescriptor, null);
- boolean ignoreDefault =
- fieldDescriptor.hasPresence() && shouldIgnoreDefault(fieldConstraints);
+ boolean ignoreDefault = fieldDescriptor.hasPresence() && shouldIgnoreDefault(fieldRules);
Object zero = null;
if (ignoreDefault) {
zero = zeroValue(fieldDescriptor, false);
@@ -224,50 +218,45 @@ private FieldEvaluator buildField(
new FieldEvaluator(
valueEvaluatorEval,
fieldDescriptor,
- fieldConstraints.getRequired(),
+ fieldRules.getRequired(),
fieldDescriptor.hasPresence(),
- fieldConstraints.getIgnore(),
+ fieldRules.getIgnore(),
zero);
- buildValue(fieldDescriptor, fieldConstraints, fieldEvaluator.valueEvaluator);
+ buildValue(fieldDescriptor, fieldRules, fieldEvaluator.valueEvaluator);
return fieldEvaluator;
}
- private static boolean shouldIgnoreEmpty(FieldConstraints constraints) {
- return constraints.getIgnore() == Ignore.IGNORE_IF_UNPOPULATED
- || constraints.getIgnore() == Ignore.IGNORE_IF_DEFAULT_VALUE;
+ private static boolean shouldIgnoreEmpty(FieldRules rules) {
+ return rules.getIgnore() == Ignore.IGNORE_IF_UNPOPULATED
+ || rules.getIgnore() == Ignore.IGNORE_IF_DEFAULT_VALUE;
}
- private static boolean shouldIgnoreDefault(FieldConstraints constraints) {
- return constraints.getIgnore() == Ignore.IGNORE_IF_DEFAULT_VALUE;
+ private static boolean shouldIgnoreDefault(FieldRules rules) {
+ return rules.getIgnore() == Ignore.IGNORE_IF_DEFAULT_VALUE;
}
private void buildValue(
- FieldDescriptor fieldDescriptor,
- FieldConstraints fieldConstraints,
- ValueEvaluator valueEvaluator)
+ FieldDescriptor fieldDescriptor, FieldRules fieldRules, ValueEvaluator valueEvaluator)
throws CompilationException {
-
- if (fieldConstraints.getIgnore() == Ignore.IGNORE_ALWAYS) {
+ if (fieldRules.getIgnore() == Ignore.IGNORE_ALWAYS) {
return;
}
- processIgnoreEmpty(fieldDescriptor, fieldConstraints, valueEvaluator);
- processFieldExpressions(fieldDescriptor, fieldConstraints, valueEvaluator);
- processEmbeddedMessage(fieldDescriptor, fieldConstraints, valueEvaluator);
- processWrapperConstraints(fieldDescriptor, fieldConstraints, valueEvaluator);
- processStandardConstraints(fieldDescriptor, fieldConstraints, valueEvaluator);
- processAnyConstraints(fieldDescriptor, fieldConstraints, valueEvaluator);
- processEnumConstraints(fieldDescriptor, fieldConstraints, valueEvaluator);
- processMapConstraints(fieldDescriptor, fieldConstraints, valueEvaluator);
- processRepeatedConstraints(fieldDescriptor, fieldConstraints, valueEvaluator);
+ processIgnoreEmpty(fieldDescriptor, fieldRules, valueEvaluator);
+ processFieldExpressions(fieldDescriptor, fieldRules, valueEvaluator);
+ processEmbeddedMessage(fieldDescriptor, valueEvaluator);
+ processWrapperRules(fieldDescriptor, fieldRules, valueEvaluator);
+ processStandardRules(fieldDescriptor, fieldRules, valueEvaluator);
+ processAnyRules(fieldDescriptor, fieldRules, valueEvaluator);
+ processEnumRules(fieldDescriptor, fieldRules, valueEvaluator);
+ processMapRules(fieldDescriptor, fieldRules, valueEvaluator);
+ processRepeatedRules(fieldDescriptor, fieldRules, valueEvaluator);
}
private void processIgnoreEmpty(
- FieldDescriptor fieldDescriptor,
- FieldConstraints fieldConstraints,
- ValueEvaluator valueEvaluatorEval)
+ FieldDescriptor fieldDescriptor, FieldRules fieldRules, ValueEvaluator valueEvaluatorEval)
throws CompilationException {
- if (valueEvaluatorEval.hasNestedRule() && shouldIgnoreEmpty(fieldConstraints)) {
+ if (valueEvaluatorEval.hasNestedRule() && shouldIgnoreEmpty(fieldRules)) {
valueEvaluatorEval.setIgnoreEmpty(zeroValue(fieldDescriptor, true));
}
}
@@ -326,12 +315,10 @@ private Message createMessageForType(Descriptor messageType) throws CompilationE
}
private void processFieldExpressions(
- FieldDescriptor fieldDescriptor,
- FieldConstraints fieldConstraints,
- ValueEvaluator valueEvaluatorEval)
+ FieldDescriptor fieldDescriptor, FieldRules fieldRules, ValueEvaluator valueEvaluatorEval)
throws CompilationException {
- List constraintsCelList = fieldConstraints.getCelList();
- if (constraintsCelList.isEmpty()) {
+ List rulesCelList = fieldRules.getCelList();
+ if (rulesCelList.isEmpty()) {
return;
}
List opts;
@@ -359,17 +346,14 @@ private void processFieldExpressions(
DescriptorMappings.protoKindToCELType(fieldDescriptor.getType()))));
}
Env finalEnv = env.extend(opts.toArray(new EnvOption[0]));
- List compiledPrograms =
- compileConstraints(constraintsCelList, finalEnv, true);
+ List compiledPrograms = compileRules(rulesCelList, finalEnv, true);
if (!compiledPrograms.isEmpty()) {
valueEvaluatorEval.append(new CelPrograms(valueEvaluatorEval, compiledPrograms));
}
}
private void processEmbeddedMessage(
- FieldDescriptor fieldDescriptor,
- FieldConstraints fieldConstraints,
- ValueEvaluator valueEvaluatorEval)
+ FieldDescriptor fieldDescriptor, ValueEvaluator valueEvaluatorEval)
throws CompilationException {
if (fieldDescriptor.getJavaType() != FieldDescriptor.JavaType.MESSAGE
|| fieldDescriptor.isMapField()
@@ -382,10 +366,8 @@ private void processEmbeddedMessage(
valueEvaluatorEval.append(embedEval);
}
- private void processWrapperConstraints(
- FieldDescriptor fieldDescriptor,
- FieldConstraints fieldConstraints,
- ValueEvaluator valueEvaluatorEval)
+ private void processWrapperRules(
+ FieldDescriptor fieldDescriptor, FieldRules fieldRules, ValueEvaluator valueEvaluatorEval)
throws CompilationException {
if (fieldDescriptor.getJavaType() != FieldDescriptor.JavaType.MESSAGE
|| fieldDescriptor.isMapField()
@@ -393,38 +375,30 @@ private void processWrapperConstraints(
return;
}
FieldDescriptor expectedWrapperDescriptor =
- DescriptorMappings.expectedWrapperConstraints(
- fieldDescriptor.getMessageType().getFullName());
- if (expectedWrapperDescriptor == null
- || !fieldConstraints.hasField(expectedWrapperDescriptor)) {
+ DescriptorMappings.expectedWrapperRules(fieldDescriptor.getMessageType().getFullName());
+ if (expectedWrapperDescriptor == null || !fieldRules.hasField(expectedWrapperDescriptor)) {
return;
}
ValueEvaluator unwrapped =
new ValueEvaluator(
valueEvaluatorEval.getDescriptor(), valueEvaluatorEval.getNestedRule());
- buildValue(
- fieldDescriptor.getMessageType().findFieldByName("value"), fieldConstraints, unwrapped);
+ buildValue(fieldDescriptor.getMessageType().findFieldByName("value"), fieldRules, unwrapped);
valueEvaluatorEval.append(unwrapped);
}
- private void processStandardConstraints(
- FieldDescriptor fieldDescriptor,
- FieldConstraints fieldConstraints,
- ValueEvaluator valueEvaluatorEval)
+ private void processStandardRules(
+ FieldDescriptor fieldDescriptor, FieldRules fieldRules, ValueEvaluator valueEvaluatorEval)
throws CompilationException {
List compile =
- constraintCache.compile(
- fieldDescriptor, fieldConstraints, valueEvaluatorEval.hasNestedRule());
+ ruleCache.compile(fieldDescriptor, fieldRules, valueEvaluatorEval.hasNestedRule());
if (compile.isEmpty()) {
return;
}
valueEvaluatorEval.append(new CelPrograms(valueEvaluatorEval, compile));
}
- private void processAnyConstraints(
- FieldDescriptor fieldDescriptor,
- FieldConstraints fieldConstraints,
- ValueEvaluator valueEvaluatorEval) {
+ private void processAnyRules(
+ FieldDescriptor fieldDescriptor, FieldRules fieldRules, ValueEvaluator valueEvaluatorEval) {
if ((fieldDescriptor.isRepeated() && !valueEvaluatorEval.hasNestedRule())
|| fieldDescriptor.getJavaType() != FieldDescriptor.JavaType.MESSAGE
|| !fieldDescriptor.getMessageType().getFullName().equals("google.protobuf.Any")) {
@@ -435,28 +409,24 @@ private void processAnyConstraints(
new AnyEvaluator(
valueEvaluatorEval,
typeURLDesc,
- fieldConstraints.getAny().getInList(),
- fieldConstraints.getAny().getNotInList()));
+ fieldRules.getAny().getInList(),
+ fieldRules.getAny().getNotInList()));
}
- private void processEnumConstraints(
- FieldDescriptor fieldDescriptor,
- FieldConstraints fieldConstraints,
- ValueEvaluator valueEvaluatorEval) {
+ private void processEnumRules(
+ FieldDescriptor fieldDescriptor, FieldRules fieldRules, ValueEvaluator valueEvaluatorEval) {
if (fieldDescriptor.getJavaType() != FieldDescriptor.JavaType.ENUM) {
return;
}
- if (fieldConstraints.getEnum().getDefinedOnly()) {
+ if (fieldRules.getEnum().getDefinedOnly()) {
Descriptors.EnumDescriptor enumDescriptor = fieldDescriptor.getEnumType();
valueEvaluatorEval.append(
new EnumEvaluator(valueEvaluatorEval, enumDescriptor.getValues()));
}
}
- private void processMapConstraints(
- FieldDescriptor fieldDescriptor,
- FieldConstraints fieldConstraints,
- ValueEvaluator valueEvaluatorEval)
+ private void processMapRules(
+ FieldDescriptor fieldDescriptor, FieldRules fieldRules, ValueEvaluator valueEvaluatorEval)
throws CompilationException {
if (!fieldDescriptor.isMapField()) {
return;
@@ -464,19 +434,17 @@ private void processMapConstraints(
MapEvaluator mapEval = new MapEvaluator(valueEvaluatorEval, fieldDescriptor);
buildValue(
fieldDescriptor.getMessageType().findFieldByNumber(1),
- fieldConstraints.getMap().getKeys(),
+ fieldRules.getMap().getKeys(),
mapEval.getKeyEvaluator());
buildValue(
fieldDescriptor.getMessageType().findFieldByNumber(2),
- fieldConstraints.getMap().getValues(),
+ fieldRules.getMap().getValues(),
mapEval.getValueEvaluator());
valueEvaluatorEval.append(mapEval);
}
- private void processRepeatedConstraints(
- FieldDescriptor fieldDescriptor,
- FieldConstraints fieldConstraints,
- ValueEvaluator valueEvaluatorEval)
+ private void processRepeatedRules(
+ FieldDescriptor fieldDescriptor, FieldRules fieldRules, ValueEvaluator valueEvaluatorEval)
throws CompilationException {
if (fieldDescriptor.isMapField()
|| !fieldDescriptor.isRepeated()
@@ -484,14 +452,13 @@ private void processRepeatedConstraints(
return;
}
ListEvaluator listEval = new ListEvaluator(valueEvaluatorEval);
- buildValue(
- fieldDescriptor, fieldConstraints.getRepeated().getItems(), listEval.itemConstraints);
+ buildValue(fieldDescriptor, fieldRules.getRepeated().getItems(), listEval.itemRules);
valueEvaluatorEval.append(listEval);
}
- private static List compileConstraints(
- List constraints, Env env, boolean isField) throws CompilationException {
- List expressions = Expression.fromConstraints(constraints);
+ private static List compileRules(List rules, Env env, boolean isField)
+ throws CompilationException {
+ List expressions = Expression.fromRules(rules);
List compiledPrograms = new ArrayList<>();
for (int i = 0; i < expressions.size(); i++) {
Expression expression = expressions.get(i);
@@ -508,7 +475,7 @@ private static List compileConstraints(
env.program(astExpression.ast),
astExpression.source,
rulePath,
- new MessageValue(constraints.get(i))));
+ new MessageValue(rules.get(i))));
}
return compiledPrograms;
}
diff --git a/src/main/java/build/buf/protovalidate/Expression.java b/src/main/java/build/buf/protovalidate/Expression.java
index 9c4c0820..ce5a33ad 100644
--- a/src/main/java/build/buf/protovalidate/Expression.java
+++ b/src/main/java/build/buf/protovalidate/Expression.java
@@ -14,27 +14,27 @@
package build.buf.protovalidate;
-import build.buf.validate.Constraint;
+import build.buf.validate.Rule;
import java.util.ArrayList;
import java.util.List;
/** Expression represents a single CEL expression. */
class Expression {
- /** The id of the constraint. */
+ /** The id of the rule. */
public final String id;
- /** The message of the constraint. */
+ /** The message of the rule. */
public final String message;
- /** The expression of the constraint. */
+ /** The expression of the rule. */
public final String expression;
/**
* Constructs a new Expression.
*
- * @param id The ID of the constraint.
- * @param message The message of the constraint.
- * @param expression The expression of the constraint.
+ * @param id The ID of the rule.
+ * @param message The message of the rule.
+ * @param expression The expression of the rule.
*/
private Expression(String id, String message, String expression) {
this.id = id;
@@ -43,24 +43,24 @@ private Expression(String id, String message, String expression) {
}
/**
- * Constructs a new Expression from the given constraint.
+ * Constructs a new Expression from the given rule.
*
- * @param constraint The constraint to create the expression from.
+ * @param rule The rule to create the expression from.
*/
- private Expression(Constraint constraint) {
- this(constraint.getId(), constraint.getMessage(), constraint.getExpression());
+ private Expression(Rule rule) {
+ this(rule.getId(), rule.getMessage(), rule.getExpression());
}
/**
- * Constructs a new list of {@link Expression} from the given list of constraints.
+ * Constructs a new list of {@link Expression} from the given list of rules.
*
- * @param constraints The list of constraints.
+ * @param rules The list of rules.
* @return The list of expressions.
*/
- public static List fromConstraints(List constraints) {
+ public static List fromRules(List rules) {
List expressions = new ArrayList<>();
- for (build.buf.validate.Constraint constraint : constraints) {
- expressions.add(new Expression(constraint));
+ for (build.buf.validate.Rule rule : rules) {
+ expressions.add(new Expression(rule));
}
return expressions;
}
diff --git a/src/main/java/build/buf/protovalidate/FieldEvaluator.java b/src/main/java/build/buf/protovalidate/FieldEvaluator.java
index 2f00ca7f..5721da57 100644
--- a/src/main/java/build/buf/protovalidate/FieldEvaluator.java
+++ b/src/main/java/build/buf/protovalidate/FieldEvaluator.java
@@ -15,8 +15,8 @@
package build.buf.protovalidate;
import build.buf.protovalidate.exceptions.ExecutionException;
-import build.buf.validate.FieldConstraints;
import build.buf.validate.FieldPath;
+import build.buf.validate.FieldRules;
import build.buf.validate.Ignore;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Message;
@@ -28,14 +28,14 @@
/** Performs validation on a single message field, defined by its descriptor. */
class FieldEvaluator implements Evaluator {
private static final FieldDescriptor REQUIRED_DESCRIPTOR =
- FieldConstraints.getDescriptor().findFieldByNumber(FieldConstraints.REQUIRED_FIELD_NUMBER);
+ FieldRules.getDescriptor().findFieldByNumber(FieldRules.REQUIRED_FIELD_NUMBER);
private static final FieldPath REQUIRED_RULE_PATH =
FieldPath.newBuilder()
.addElements(FieldPathUtils.fieldPathElement(REQUIRED_DESCRIPTOR))
.build();
- private final ConstraintViolationHelper helper;
+ private final RuleViolationHelper helper;
/** The {@link ValueEvaluator} to apply to the field's value */
public final ValueEvaluator valueEvaluator;
@@ -62,7 +62,7 @@ class FieldEvaluator implements Evaluator {
boolean hasPresence,
Ignore ignore,
@Nullable Object zero) {
- this.helper = new ConstraintViolationHelper(valueEvaluator);
+ this.helper = new RuleViolationHelper(valueEvaluator);
this.valueEvaluator = valueEvaluator;
this.descriptor = descriptor;
this.required = required;
@@ -88,8 +88,8 @@ private boolean shouldIgnoreAlways() {
/**
* Returns whether a field should skip validation on its zero value.
*
- * This is generally true for nullable fields or fields with the ignore_empty constraint
- * explicitly set.
+ *
This is generally true for nullable fields or fields with the ignore_empty rule explicitly
+ * set.
*/
private boolean shouldIgnoreEmpty() {
return this.hasPresence
@@ -106,14 +106,14 @@ private boolean shouldIgnoreDefault() {
}
@Override
- public List evaluate(Value val, boolean failFast)
+ public List evaluate(Value val, boolean failFast)
throws ExecutionException {
if (this.shouldIgnoreAlways()) {
- return ConstraintViolation.NO_VIOLATIONS;
+ return RuleViolation.NO_VIOLATIONS;
}
Message message = val.messageValue();
if (message == null) {
- return ConstraintViolation.NO_VIOLATIONS;
+ return RuleViolation.NO_VIOLATIONS;
}
boolean hasField;
if (descriptor.isRepeated()) {
@@ -123,20 +123,20 @@ public List evaluate(Value val, boolean failFast)
}
if (required && !hasField) {
return Collections.singletonList(
- ConstraintViolation.newBuilder()
+ RuleViolation.newBuilder()
.addFirstFieldPathElement(FieldPathUtils.fieldPathElement(descriptor))
.addAllRulePathElements(helper.getRulePrefixElements())
.addAllRulePathElements(REQUIRED_RULE_PATH.getElementsList())
- .setConstraintId("required")
+ .setRuleId("required")
.setMessage("value is required")
- .setRuleValue(new ConstraintViolation.FieldValue(true, REQUIRED_DESCRIPTOR)));
+ .setRuleValue(new RuleViolation.FieldValue(true, REQUIRED_DESCRIPTOR)));
}
if (this.shouldIgnoreEmpty() && !hasField) {
- return ConstraintViolation.NO_VIOLATIONS;
+ return RuleViolation.NO_VIOLATIONS;
}
Object fieldValue = message.getField(descriptor);
if (this.shouldIgnoreDefault() && Objects.equals(zero, fieldValue)) {
- return ConstraintViolation.NO_VIOLATIONS;
+ return RuleViolation.NO_VIOLATIONS;
}
return valueEvaluator.evaluate(new ObjectValue(descriptor, fieldValue), failFast);
}
diff --git a/src/main/java/build/buf/protovalidate/FieldPathUtils.java b/src/main/java/build/buf/protovalidate/FieldPathUtils.java
index b07664e8..4706cc5c 100644
--- a/src/main/java/build/buf/protovalidate/FieldPathUtils.java
+++ b/src/main/java/build/buf/protovalidate/FieldPathUtils.java
@@ -100,12 +100,12 @@ public static FieldPathElement fieldPathElement(Descriptors.FieldDescriptor fiel
* @param rulePathElements Rule path elements to prepend.
* @return For convenience, the list of violations passed into the violations parameter.
*/
- public static List updatePaths(
- List violations,
+ public static List updatePaths(
+ List violations,
@Nullable FieldPathElement fieldPathElement,
List rulePathElements) {
if (fieldPathElement != null || !rulePathElements.isEmpty()) {
- for (ConstraintViolation.Builder violation : violations) {
+ for (RuleViolation.Builder violation : violations) {
for (int i = rulePathElements.size() - 1; i >= 0; i--) {
violation.addFirstRulePathElement(rulePathElements.get(i));
}
diff --git a/src/main/java/build/buf/protovalidate/ListEvaluator.java b/src/main/java/build/buf/protovalidate/ListEvaluator.java
index 6b77d229..52bc3e21 100644
--- a/src/main/java/build/buf/protovalidate/ListEvaluator.java
+++ b/src/main/java/build/buf/protovalidate/ListEvaluator.java
@@ -15,9 +15,9 @@
package build.buf.protovalidate;
import build.buf.protovalidate.exceptions.ExecutionException;
-import build.buf.validate.FieldConstraints;
import build.buf.validate.FieldPath;
import build.buf.validate.FieldPathElement;
+import build.buf.validate.FieldRules;
import build.buf.validate.RepeatedRules;
import java.util.ArrayList;
import java.util.List;
@@ -30,38 +30,36 @@ class ListEvaluator implements Evaluator {
FieldPath.newBuilder()
.addElements(
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor()
- .findFieldByNumber(FieldConstraints.REPEATED_FIELD_NUMBER)))
+ FieldRules.getDescriptor().findFieldByNumber(FieldRules.REPEATED_FIELD_NUMBER)))
.addElements(
FieldPathUtils.fieldPathElement(
RepeatedRules.getDescriptor()
.findFieldByNumber(RepeatedRules.ITEMS_FIELD_NUMBER)))
.build();
- private final ConstraintViolationHelper helper;
+ private final RuleViolationHelper helper;
- /** Constraints are checked on every item of the list. */
- final ValueEvaluator itemConstraints;
+ /** Rules are checked on every item of the list. */
+ final ValueEvaluator itemRules;
/** Constructs a {@link ListEvaluator}. */
ListEvaluator(ValueEvaluator valueEvaluator) {
- this.helper = new ConstraintViolationHelper(valueEvaluator);
- this.itemConstraints = new ValueEvaluator(null, REPEATED_ITEMS_RULE_PATH);
+ this.helper = new RuleViolationHelper(valueEvaluator);
+ this.itemRules = new ValueEvaluator(null, REPEATED_ITEMS_RULE_PATH);
}
@Override
public boolean tautology() {
- return itemConstraints.tautology();
+ return itemRules.tautology();
}
@Override
- public List evaluate(Value val, boolean failFast)
+ public List evaluate(Value val, boolean failFast)
throws ExecutionException {
- List allViolations = new ArrayList<>();
+ List allViolations = new ArrayList<>();
List repeatedValues = val.repeatedValue();
for (int i = 0; i < repeatedValues.size(); i++) {
- List violations =
- itemConstraints.evaluate(repeatedValues.get(i), failFast);
+ List violations = itemRules.evaluate(repeatedValues.get(i), failFast);
if (violations.isEmpty()) {
continue;
}
diff --git a/src/main/java/build/buf/protovalidate/MapEvaluator.java b/src/main/java/build/buf/protovalidate/MapEvaluator.java
index 1e92accd..8bc7ea66 100644
--- a/src/main/java/build/buf/protovalidate/MapEvaluator.java
+++ b/src/main/java/build/buf/protovalidate/MapEvaluator.java
@@ -15,9 +15,9 @@
package build.buf.protovalidate;
import build.buf.protovalidate.exceptions.ExecutionException;
-import build.buf.validate.FieldConstraints;
import build.buf.validate.FieldPath;
import build.buf.validate.FieldPathElement;
+import build.buf.validate.FieldRules;
import build.buf.validate.MapRules;
import com.google.protobuf.Descriptors;
import java.util.ArrayList;
@@ -34,8 +34,7 @@ class MapEvaluator implements Evaluator {
FieldPath.newBuilder()
.addElements(
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor()
- .findFieldByNumber(FieldConstraints.MAP_FIELD_NUMBER)))
+ FieldRules.getDescriptor().findFieldByNumber(FieldRules.MAP_FIELD_NUMBER)))
.addElements(
FieldPathUtils.fieldPathElement(
MapRules.getDescriptor().findFieldByNumber(MapRules.KEYS_FIELD_NUMBER)))
@@ -46,19 +45,18 @@ class MapEvaluator implements Evaluator {
FieldPath.newBuilder()
.addElements(
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor()
- .findFieldByNumber(FieldConstraints.MAP_FIELD_NUMBER)))
+ FieldRules.getDescriptor().findFieldByNumber(FieldRules.MAP_FIELD_NUMBER)))
.addElements(
FieldPathUtils.fieldPathElement(
MapRules.getDescriptor().findFieldByNumber(MapRules.VALUES_FIELD_NUMBER)))
.build();
- private final ConstraintViolationHelper helper;
+ private final RuleViolationHelper helper;
- /** Constraint for checking the map keys */
+ /** Rule for checking the map keys */
private final ValueEvaluator keyEvaluator;
- /** Constraint for checking the map values */
+ /** Rule for checking the map values */
private final ValueEvaluator valueEvaluator;
/** Field descriptor of the map field */
@@ -73,10 +71,10 @@ class MapEvaluator implements Evaluator {
/**
* Constructs a {@link MapEvaluator}.
*
- * @param valueEvaluator The value evaluator this constraint exists under.
+ * @param valueEvaluator The value evaluator this rule exists under.
*/
MapEvaluator(ValueEvaluator valueEvaluator, Descriptors.FieldDescriptor fieldDescriptor) {
- this.helper = new ConstraintViolationHelper(valueEvaluator);
+ this.helper = new RuleViolationHelper(valueEvaluator);
this.keyEvaluator = new ValueEvaluator(null, MAP_KEYS_RULE_PATH);
this.valueEvaluator = new ValueEvaluator(null, MAP_VALUES_RULE_PATH);
this.fieldDescriptor = fieldDescriptor;
@@ -108,9 +106,9 @@ public boolean tautology() {
}
@Override
- public List evaluate(Value val, boolean failFast)
+ public List evaluate(Value val, boolean failFast)
throws ExecutionException {
- List violations = new ArrayList<>();
+ List violations = new ArrayList<>();
Map mapValue = val.mapValue();
for (Map.Entry entry : mapValue.entrySet()) {
violations.addAll(evalPairs(entry.getKey(), entry.getValue(), failFast));
@@ -119,29 +117,29 @@ public List evaluate(Value val, boolean failFast)
}
}
if (violations.isEmpty()) {
- return ConstraintViolation.NO_VIOLATIONS;
+ return RuleViolation.NO_VIOLATIONS;
}
return violations;
}
- private List evalPairs(Value key, Value value, boolean failFast)
+ private List evalPairs(Value key, Value value, boolean failFast)
throws ExecutionException {
- List keyViolations =
+ List keyViolations =
keyEvaluator.evaluate(key, failFast).stream()
.map(violation -> violation.setForKey(true))
.collect(Collectors.toList());
- final List valueViolations;
+ final List valueViolations;
if (failFast && !keyViolations.isEmpty()) {
- // Don't evaluate value constraints if failFast is enabled and keys failed validation.
+ // Don't evaluate value rules if failFast is enabled and keys failed validation.
// We still need to continue execution to the end to properly prefix violation field paths.
- valueViolations = ConstraintViolation.NO_VIOLATIONS;
+ valueViolations = RuleViolation.NO_VIOLATIONS;
} else {
valueViolations = valueEvaluator.evaluate(value, failFast);
}
if (keyViolations.isEmpty() && valueViolations.isEmpty()) {
return Collections.emptyList();
}
- List violations =
+ List violations =
new ArrayList<>(keyViolations.size() + valueViolations.size());
violations.addAll(keyViolations);
violations.addAll(valueViolations);
diff --git a/src/main/java/build/buf/protovalidate/MessageEvaluator.java b/src/main/java/build/buf/protovalidate/MessageEvaluator.java
index f5523720..fc496c2d 100644
--- a/src/main/java/build/buf/protovalidate/MessageEvaluator.java
+++ b/src/main/java/build/buf/protovalidate/MessageEvaluator.java
@@ -34,18 +34,18 @@ public boolean tautology() {
}
@Override
- public List evaluate(Value val, boolean failFast)
+ public List evaluate(Value val, boolean failFast)
throws ExecutionException {
- List allViolations = new ArrayList<>();
+ List allViolations = new ArrayList<>();
for (Evaluator evaluator : evaluators) {
- List violations = evaluator.evaluate(val, failFast);
+ List violations = evaluator.evaluate(val, failFast);
if (failFast && !violations.isEmpty()) {
return violations;
}
allViolations.addAll(violations);
}
if (allViolations.isEmpty()) {
- return ConstraintViolation.NO_VIOLATIONS;
+ return RuleViolation.NO_VIOLATIONS;
}
return allViolations;
}
diff --git a/src/main/java/build/buf/protovalidate/OneofEvaluator.java b/src/main/java/build/buf/protovalidate/OneofEvaluator.java
index b2f59f26..2b6a10c9 100644
--- a/src/main/java/build/buf/protovalidate/OneofEvaluator.java
+++ b/src/main/java/build/buf/protovalidate/OneofEvaluator.java
@@ -46,17 +46,17 @@ public boolean tautology() {
}
@Override
- public List evaluate(Value val, boolean failFast)
+ public List evaluate(Value val, boolean failFast)
throws ExecutionException {
Message message = val.messageValue();
if (message == null || !required || (message.getOneofFieldDescriptor(descriptor) != null)) {
- return ConstraintViolation.NO_VIOLATIONS;
+ return RuleViolation.NO_VIOLATIONS;
}
return Collections.singletonList(
- ConstraintViolation.newBuilder()
+ RuleViolation.newBuilder()
.addFirstFieldPathElement(
FieldPathElement.newBuilder().setFieldName(descriptor.getName()).build())
- .setConstraintId("required")
+ .setRuleId("required")
.setMessage("exactly one field is required in oneof"));
}
}
diff --git a/src/main/java/build/buf/protovalidate/ConstraintCache.java b/src/main/java/build/buf/protovalidate/RuleCache.java
similarity index 63%
rename from src/main/java/build/buf/protovalidate/ConstraintCache.java
rename to src/main/java/build/buf/protovalidate/RuleCache.java
index 740b25a3..25d37b18 100644
--- a/src/main/java/build/buf/protovalidate/ConstraintCache.java
+++ b/src/main/java/build/buf/protovalidate/RuleCache.java
@@ -15,8 +15,8 @@
package build.buf.protovalidate;
import build.buf.protovalidate.exceptions.CompilationException;
-import build.buf.validate.FieldConstraints;
import build.buf.validate.FieldPath;
+import build.buf.validate.FieldRules;
import build.buf.validate.ValidateProto;
import com.google.protobuf.DescriptorProtos;
import com.google.protobuf.Descriptors;
@@ -43,8 +43,8 @@
import org.projectnessie.cel.common.types.ref.Val;
import org.projectnessie.cel.interpreter.Activation;
-/** A build-through cache for computed standard constraints. */
-class ConstraintCache {
+/** A build-through cache for computed standard rules. */
+class RuleCache {
private static class CelRule {
public final AstExpression astExpression;
public final FieldDescriptor field;
@@ -63,7 +63,7 @@ public CelRule(AstExpression astExpression, FieldDescriptor field, FieldPath rul
EXTENSION_REGISTRY.add(ValidateProto.predefined);
}
- /** Partial eval options for evaluating the constraint's expression. */
+ /** Partial eval options for evaluating the rule's expression. */
private static final ProgramOption PARTIAL_EVAL_OPTIONS =
ProgramOption.evalOptions(
EvalOption.OptTrackState,
@@ -87,17 +87,17 @@ public CelRule(AstExpression astExpression, FieldDescriptor field, FieldPath rul
/** Registry used to resolve dynamic extensions. */
private final ExtensionRegistry extensionRegistry;
- /** Whether to allow unknown constraint fields or not. */
+ /** Whether to allow unknown rule fields or not. */
private final boolean allowUnknownFields;
/**
- * Constructs a new build-through cache for the standard constraints, with a provided registry to
+ * Constructs a new build-through cache for the standard rules, with a provided registry to
* resolve dynamic extensions.
*
* @param env The CEL environment for evaluation.
- * @param config The configuration to use for the constraint cache.
+ * @param config The configuration to use for the rule cache.
*/
- public ConstraintCache(Env env, Config config) {
+ public RuleCache(Env env, Config config) {
this.env = env;
this.typeRegistry = config.getTypeRegistry();
this.extensionRegistry = config.getExtensionRegistry();
@@ -105,29 +105,29 @@ public ConstraintCache(Env env, Config config) {
}
/**
- * Creates the standard constraints for the given field. If forItems is true, the constraints for
- * repeated list items is built instead of the constraints on the list itself.
+ * Creates the standard rules for the given field. If forItems is true, the rules for repeated
+ * list items is built instead of the rules on the list itself.
*
* @param fieldDescriptor The field descriptor to be validated.
- * @param fieldConstraints The field constraint that is used for validation.
+ * @param fieldRules The field rule that is used for validation.
* @param forItems The field is an item list type.
* @return The list of compiled programs.
- * @throws CompilationException If the constraints fail to compile.
+ * @throws CompilationException If the rules fail to compile.
*/
public List compile(
- FieldDescriptor fieldDescriptor, FieldConstraints fieldConstraints, boolean forItems)
+ FieldDescriptor fieldDescriptor, FieldRules fieldRules, boolean forItems)
throws CompilationException {
- ResolvedConstraint resolved = resolveConstraints(fieldDescriptor, fieldConstraints, forItems);
+ ResolvedRule resolved = resolveRules(fieldDescriptor, fieldRules, forItems);
if (resolved == null) {
- // Message null means there were no constraints resolved.
+ // Message null means there were no rules resolved.
return Collections.emptyList();
}
Message message = resolved.message;
List completeProgramList = new ArrayList<>();
for (Map.Entry entry : message.getAllFields().entrySet()) {
- FieldDescriptor constraintFieldDesc = entry.getKey();
+ FieldDescriptor ruleFieldDesc = entry.getKey();
List programList =
- compileRule(fieldDescriptor, forItems, resolved.setOneof, constraintFieldDesc, message);
+ compileRule(fieldDescriptor, forItems, resolved.setOneof, ruleFieldDesc, message);
if (programList == null) continue;
completeProgramList.addAll(programList);
}
@@ -173,35 +173,35 @@ public List compile(
FieldDescriptor fieldDescriptor,
boolean forItems,
FieldDescriptor setOneof,
- FieldDescriptor constraintFieldDesc,
+ FieldDescriptor ruleFieldDesc,
Message message)
throws CompilationException {
List celRules = descriptorMap.get(fieldDescriptor);
if (celRules != null) {
return celRules;
}
- build.buf.validate.PredefinedConstraints constraints = getFieldConstraints(constraintFieldDesc);
- if (constraints == null) return null;
- List expressions = Expression.fromConstraints(constraints.getCelList());
+ build.buf.validate.PredefinedRules rules = getFieldRules(ruleFieldDesc);
+ if (rules == null) return null;
+ List expressions = Expression.fromRules(rules.getCelList());
celRules = new ArrayList<>(expressions.size());
- Env ruleEnv = getRuleEnv(fieldDescriptor, message, constraintFieldDesc, forItems);
+ Env ruleEnv = getRuleEnv(fieldDescriptor, message, ruleFieldDesc, forItems);
for (Expression expression : expressions) {
FieldPath rulePath =
FieldPath.newBuilder()
.addElements(FieldPathUtils.fieldPathElement(setOneof))
- .addElements(FieldPathUtils.fieldPathElement(constraintFieldDesc))
+ .addElements(FieldPathUtils.fieldPathElement(ruleFieldDesc))
.build();
celRules.add(
new CelRule(
- AstExpression.newAstExpression(ruleEnv, expression), constraintFieldDesc, rulePath));
+ AstExpression.newAstExpression(ruleEnv, expression), ruleFieldDesc, rulePath));
}
- descriptorMap.put(constraintFieldDesc, celRules);
+ descriptorMap.put(ruleFieldDesc, celRules);
return celRules;
}
- private build.buf.validate.@Nullable PredefinedConstraints getFieldConstraints(
- FieldDescriptor constraintFieldDesc) throws CompilationException {
- DescriptorProtos.FieldOptions options = constraintFieldDesc.getOptions();
+ private build.buf.validate.@Nullable PredefinedRules getFieldRules(FieldDescriptor ruleFieldDesc)
+ throws CompilationException {
+ DescriptorProtos.FieldOptions options = ruleFieldDesc.getOptions();
// If the protovalidate field option is unknown, reparse options using our extension registry.
if (options.getUnknownFields().hasField(ValidateProto.predefined.getNumber())) {
try {
@@ -215,128 +215,125 @@ public List compile(
return null;
}
Object extensionValue = options.getField(ValidateProto.predefined.getDescriptor());
- build.buf.validate.PredefinedConstraints constraints;
- if (extensionValue instanceof build.buf.validate.PredefinedConstraints) {
- constraints = (build.buf.validate.PredefinedConstraints) extensionValue;
+ build.buf.validate.PredefinedRules rules;
+ if (extensionValue instanceof build.buf.validate.PredefinedRules) {
+ rules = (build.buf.validate.PredefinedRules) extensionValue;
} else if (extensionValue instanceof MessageLite) {
// Extension is parsed but with different gencode. We need to reparse it.
try {
- constraints =
- build.buf.validate.PredefinedConstraints.parseFrom(
+ rules =
+ build.buf.validate.PredefinedRules.parseFrom(
((MessageLite) extensionValue).toByteString());
} catch (InvalidProtocolBufferException e) {
- throw new CompilationException("Failed to parse field constraints", e);
+ throw new CompilationException("Failed to parse field rules", e);
}
} else {
// Extension was not a message, just discard it.
return null;
}
- return constraints;
+ return rules;
}
/**
* Calculates the environment for a specific rule invocation.
*
- * @param fieldDescriptor The field descriptor of the field with the constraint.
- * @param constraintMessage The message of the standard constraints.
- * @param constraintFieldDesc The field descriptor of the constraint.
+ * @param fieldDescriptor The field descriptor of the field with the rule.
+ * @param ruleMessage The message of the standard rules.
+ * @param ruleFieldDesc The field descriptor of the rule.
* @param forItems Whether the field is a list type or not.
* @return An environment with requisite declarations and types added.
*/
private Env getRuleEnv(
FieldDescriptor fieldDescriptor,
- Message constraintMessage,
- FieldDescriptor constraintFieldDesc,
+ Message ruleMessage,
+ FieldDescriptor ruleFieldDesc,
boolean forItems) {
return env.extend(
- EnvOption.types(constraintMessage.getDefaultInstanceForType()),
+ EnvOption.types(ruleMessage.getDefaultInstanceForType()),
EnvOption.declarations(
Decls.newVar(
Variable.THIS_NAME, DescriptorMappings.getCELType(fieldDescriptor, forItems)),
Decls.newVar(
Variable.RULES_NAME,
- Decls.newObjectType(constraintMessage.getDescriptorForType().getFullName())),
- Decls.newVar(
- Variable.RULE_NAME, DescriptorMappings.getCELType(constraintFieldDesc, false))));
+ Decls.newObjectType(ruleMessage.getDescriptorForType().getFullName())),
+ Decls.newVar(Variable.RULE_NAME, DescriptorMappings.getCELType(ruleFieldDesc, false))));
}
- private static class ResolvedConstraint {
+ private static class ResolvedRule {
final Message message;
final FieldDescriptor setOneof;
- ResolvedConstraint(Message message, FieldDescriptor setOneof) {
+ ResolvedRule(Message message, FieldDescriptor setOneof) {
this.message = message;
this.setOneof = setOneof;
}
}
/**
- * Extracts the standard constraints for the specified field. An exception is thrown if the wrong
- * constraints are applied to a field (typically if there is a type-mismatch). Null is returned if
- * there are no standard constraints to apply to this field.
+ * Extracts the standard rules for the specified field. An exception is thrown if the wrong rules
+ * are applied to a field (typically if there is a type-mismatch). Null is returned if there are
+ * no standard rules to apply to this field.
*/
@Nullable
- private ResolvedConstraint resolveConstraints(
- FieldDescriptor fieldDescriptor, FieldConstraints fieldConstraints, boolean forItems)
+ private ResolvedRule resolveRules(
+ FieldDescriptor fieldDescriptor, FieldRules fieldRules, boolean forItems)
throws CompilationException {
- // Get the oneof field descriptor from the field constraints.
+ // Get the oneof field descriptor from the field rules.
FieldDescriptor oneofFieldDescriptor =
- fieldConstraints.getOneofFieldDescriptor(DescriptorMappings.FIELD_CONSTRAINTS_ONEOF_DESC);
+ fieldRules.getOneofFieldDescriptor(DescriptorMappings.FIELD_RULES_ONEOF_DESC);
if (oneofFieldDescriptor == null) {
- // If the oneof field descriptor is null there are no constraints to resolve.
+ // If the oneof field descriptor is null there are no rules to resolve.
return null;
}
- // Get the expected constraint descriptor based on the provided field descriptor and the flag
+ // Get the expected rule descriptor based on the provided field descriptor and the flag
// indicating whether it is for items.
- FieldDescriptor expectedConstraintDescriptor =
- DescriptorMappings.getExpectedConstraintDescriptor(fieldDescriptor, forItems);
- if (expectedConstraintDescriptor != null
- && !oneofFieldDescriptor.getFullName().equals(expectedConstraintDescriptor.getFullName())) {
- // If the expected constraint does not match the actual oneof constraint, throw a
+ FieldDescriptor expectedRuleDescriptor =
+ DescriptorMappings.getExpectedRuleDescriptor(fieldDescriptor, forItems);
+ if (expectedRuleDescriptor != null
+ && !oneofFieldDescriptor.getFullName().equals(expectedRuleDescriptor.getFullName())) {
+ // If the expected rule does not match the actual oneof rule, throw a
// CompilationError.
throw new CompilationException(
String.format(
- "expected constraint %s, got %s on field %s",
- expectedConstraintDescriptor.getName(),
+ "expected rule %s, got %s on field %s",
+ expectedRuleDescriptor.getName(),
oneofFieldDescriptor.getName(),
fieldDescriptor.getName()));
}
- // If the expected constraint descriptor is null or if the field constraints do not have the
+ // If the expected rule descriptor is null or if the field rules do not have the
// oneof field descriptor
- // there are no constraints to resolve, so return null.
- if (expectedConstraintDescriptor == null || !fieldConstraints.hasField(oneofFieldDescriptor)) {
+ // there are no rules to resolve, so return null.
+ if (expectedRuleDescriptor == null || !fieldRules.hasField(oneofFieldDescriptor)) {
return null;
}
- // Get the field from the field constraints identified by the oneof field descriptor, casted
+ // Get the field from the field rules identified by the oneof field descriptor, casted
// as a Message.
- Message typeConstraints = (Message) fieldConstraints.getField(oneofFieldDescriptor);
- if (!typeConstraints.getUnknownFields().isEmpty()) {
+ Message typeRules = (Message) fieldRules.getField(oneofFieldDescriptor);
+ if (!typeRules.getUnknownFields().isEmpty()) {
// If there are unknown fields, try to resolve them using the provided registries. Note that
// we use the type registry to resolve the message descriptor. This is because Java protobuf
// extension resolution relies on descriptor identity. The user's provided type registry can
// provide matching message descriptors for the user's provided extension registry. See the
// documentation for Options.setTypeRegistry for more information.
- Descriptors.Descriptor expectedConstraintMessageDescriptor =
- typeRegistry.find(expectedConstraintDescriptor.getMessageType().getFullName());
- if (expectedConstraintMessageDescriptor == null) {
- expectedConstraintMessageDescriptor = expectedConstraintDescriptor.getMessageType();
+ Descriptors.Descriptor expectedRuleMessageDescriptor =
+ typeRegistry.find(expectedRuleDescriptor.getMessageType().getFullName());
+ if (expectedRuleMessageDescriptor == null) {
+ expectedRuleMessageDescriptor = expectedRuleDescriptor.getMessageType();
}
try {
- typeConstraints =
+ typeRules =
DynamicMessage.parseFrom(
- expectedConstraintMessageDescriptor,
- typeConstraints.toByteString(),
- extensionRegistry);
+ expectedRuleMessageDescriptor, typeRules.toByteString(), extensionRegistry);
} catch (InvalidProtocolBufferException e) {
throw new RuntimeException(e);
}
}
- if (!allowUnknownFields && !typeConstraints.getUnknownFields().isEmpty()) {
- throw new CompilationException("unrecognized field constraints");
+ if (!allowUnknownFields && !typeRules.getUnknownFields().isEmpty()) {
+ throw new CompilationException("unrecognized field rules");
}
- return new ResolvedConstraint(typeConstraints, oneofFieldDescriptor);
+ return new ResolvedRule(typeRules, oneofFieldDescriptor);
}
}
diff --git a/src/main/java/build/buf/protovalidate/ConstraintResolver.java b/src/main/java/build/buf/protovalidate/RuleResolver.java
similarity index 66%
rename from src/main/java/build/buf/protovalidate/ConstraintResolver.java
rename to src/main/java/build/buf/protovalidate/RuleResolver.java
index ffe6bf0e..17091fc6 100644
--- a/src/main/java/build/buf/protovalidate/ConstraintResolver.java
+++ b/src/main/java/build/buf/protovalidate/RuleResolver.java
@@ -15,9 +15,9 @@
package build.buf.protovalidate;
import build.buf.protovalidate.exceptions.CompilationException;
-import build.buf.validate.FieldConstraints;
-import build.buf.validate.MessageConstraints;
-import build.buf.validate.OneofConstraints;
+import build.buf.validate.FieldRules;
+import build.buf.validate.MessageRules;
+import build.buf.validate.OneofRules;
import build.buf.validate.ValidateProto;
import com.google.protobuf.DescriptorProtos;
import com.google.protobuf.Descriptors.Descriptor;
@@ -27,8 +27,8 @@
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageLite;
-/** Manages the resolution of protovalidate constraints. */
-class ConstraintResolver {
+/** Manages the resolution of protovalidate rules. */
+class RuleResolver {
private static final ExtensionRegistry EXTENSION_REGISTRY = ExtensionRegistry.newInstance();
static {
@@ -38,12 +38,12 @@ class ConstraintResolver {
}
/**
- * Resolves the constraints for a message descriptor.
+ * Resolves the rules for a message descriptor.
*
* @param desc the message descriptor.
- * @return the resolved {@link MessageConstraints}.
+ * @return the resolved {@link MessageRules}.
*/
- MessageConstraints resolveMessageConstraints(Descriptor desc)
+ MessageRules resolveMessageRules(Descriptor desc)
throws InvalidProtocolBufferException, CompilationException {
DescriptorProtos.MessageOptions options = desc.getOptions();
// If the protovalidate message extension is unknown, reparse using extension registry.
@@ -52,29 +52,29 @@ MessageConstraints resolveMessageConstraints(Descriptor desc)
DescriptorProtos.MessageOptions.parseFrom(options.toByteString(), EXTENSION_REGISTRY);
}
if (!options.hasExtension(ValidateProto.message)) {
- return MessageConstraints.getDefaultInstance();
+ return MessageRules.getDefaultInstance();
}
// Don't use getExtension here to avoid exception if descriptor types don't match.
// This can occur if the extension is generated to a different Java package.
Object value = options.getField(ValidateProto.message.getDescriptor());
- if (value instanceof MessageConstraints) {
- return ((MessageConstraints) value);
+ if (value instanceof MessageRules) {
+ return ((MessageRules) value);
}
if (value instanceof MessageLite) {
- // Possible that this represents the same constraint type, just generated to a different
+ // Possible that this represents the same rule type, just generated to a different
// java_package.
- return MessageConstraints.parseFrom(((MessageLite) value).toByteString());
+ return MessageRules.parseFrom(((MessageLite) value).toByteString());
}
- throw new CompilationException("unexpected message constraint option type: " + value);
+ throw new CompilationException("unexpected message rule option type: " + value);
}
/**
- * Resolves the constraints for a oneof descriptor.
+ * Resolves the rules for a oneof descriptor.
*
* @param desc the oneof descriptor.
- * @return the resolved {@link OneofConstraints}.
+ * @return the resolved {@link OneofRules}.
*/
- OneofConstraints resolveOneofConstraints(OneofDescriptor desc)
+ OneofRules resolveOneofRules(OneofDescriptor desc)
throws InvalidProtocolBufferException, CompilationException {
DescriptorProtos.OneofOptions options = desc.getOptions();
// If the protovalidate oneof extension is unknown, reparse using extension registry.
@@ -82,29 +82,29 @@ OneofConstraints resolveOneofConstraints(OneofDescriptor desc)
options = DescriptorProtos.OneofOptions.parseFrom(options.toByteString(), EXTENSION_REGISTRY);
}
if (!options.hasExtension(ValidateProto.oneof)) {
- return OneofConstraints.getDefaultInstance();
+ return OneofRules.getDefaultInstance();
}
// Don't use getExtension here to avoid exception if descriptor types don't match.
// This can occur if the extension is generated to a different Java package.
Object value = options.getField(ValidateProto.oneof.getDescriptor());
- if (value instanceof OneofConstraints) {
- return ((OneofConstraints) value);
+ if (value instanceof OneofRules) {
+ return ((OneofRules) value);
}
if (value instanceof MessageLite) {
- // Possible that this represents the same constraint type, just generated to a different
+ // Possible that this represents the same rule type, just generated to a different
// java_package.
- return OneofConstraints.parseFrom(((MessageLite) value).toByteString());
+ return OneofRules.parseFrom(((MessageLite) value).toByteString());
}
- throw new CompilationException("unexpected oneof constraint option type: " + value);
+ throw new CompilationException("unexpected oneof rule option type: " + value);
}
/**
- * Resolves the constraints for a field descriptor.
+ * Resolves the rules for a field descriptor.
*
* @param desc the field descriptor.
- * @return the resolved {@link FieldConstraints}.
+ * @return the resolved {@link FieldRules}.
*/
- FieldConstraints resolveFieldConstraints(FieldDescriptor desc)
+ FieldRules resolveFieldRules(FieldDescriptor desc)
throws InvalidProtocolBufferException, CompilationException {
DescriptorProtos.FieldOptions options = desc.getOptions();
// If the protovalidate field option is unknown, reparse using extension registry.
@@ -112,19 +112,19 @@ FieldConstraints resolveFieldConstraints(FieldDescriptor desc)
options = DescriptorProtos.FieldOptions.parseFrom(options.toByteString(), EXTENSION_REGISTRY);
}
if (!options.hasExtension(ValidateProto.field)) {
- return FieldConstraints.getDefaultInstance();
+ return FieldRules.getDefaultInstance();
}
// Don't use getExtension here to avoid exception if descriptor types don't match.
// This can occur if the extension is generated to a different Java package.
Object value = options.getField(ValidateProto.field.getDescriptor());
- if (value instanceof FieldConstraints) {
- return ((FieldConstraints) value);
+ if (value instanceof FieldRules) {
+ return ((FieldRules) value);
}
if (value instanceof MessageLite) {
- // Possible that this represents the same constraint type, just generated to a different
+ // Possible that this represents the same rule type, just generated to a different
// java_package.
- return FieldConstraints.parseFrom(((MessageLite) value).toByteString());
+ return FieldRules.parseFrom(((MessageLite) value).toByteString());
}
- throw new CompilationException("unexpected field constraint option type: " + value);
+ throw new CompilationException("unexpected field rule option type: " + value);
}
}
diff --git a/src/main/java/build/buf/protovalidate/ConstraintViolation.java b/src/main/java/build/buf/protovalidate/RuleViolation.java
similarity index 89%
rename from src/main/java/build/buf/protovalidate/ConstraintViolation.java
rename to src/main/java/build/buf/protovalidate/RuleViolation.java
index c141d1ff..67be135b 100644
--- a/src/main/java/build/buf/protovalidate/ConstraintViolation.java
+++ b/src/main/java/build/buf/protovalidate/RuleViolation.java
@@ -26,10 +26,10 @@
import org.jspecify.annotations.Nullable;
/**
- * {@link ConstraintViolation} contains all of the collected information about an individual
- * constraint violation.
+ * {@link RuleViolation} contains all of the collected information about an individual rule
+ * violation.
*/
-class ConstraintViolation implements Violation {
+class RuleViolation implements Violation {
/** Static value to return when there are no violations. */
public static final List NO_VIOLATIONS = new ArrayList<>();
@@ -77,7 +77,7 @@ public Descriptors.FieldDescriptor getDescriptor() {
/** Builds a Violation instance. */
public static class Builder {
- private @Nullable String constraintId;
+ private @Nullable String ruleId;
private @Nullable String message;
private boolean forKey = false;
private final Deque fieldPath = new ArrayDeque<>();
@@ -86,13 +86,13 @@ public static class Builder {
private @Nullable FieldValue ruleValue;
/**
- * Sets the constraint ID field of the resulting violation.
+ * Sets the rule ID field of the resulting violation.
*
- * @param constraintId Constraint ID value to use.
+ * @param ruleId Rule ID value to use.
* @return The builder.
*/
- public Builder setConstraintId(String constraintId) {
- this.constraintId = constraintId;
+ public Builder setRuleId(String ruleId) {
+ this.ruleId = ruleId;
return this;
}
@@ -192,10 +192,10 @@ public Builder setRuleValue(@Nullable FieldValue ruleValue) {
*
* @return A Violation instance.
*/
- public ConstraintViolation build() {
+ public RuleViolation build() {
build.buf.validate.Violation.Builder protoBuilder = build.buf.validate.Violation.newBuilder();
- if (constraintId != null) {
- protoBuilder.setConstraintId(constraintId);
+ if (ruleId != null) {
+ protoBuilder.setRuleId(ruleId);
}
if (message != null) {
protoBuilder.setMessage(message);
@@ -209,14 +209,14 @@ public ConstraintViolation build() {
if (!rulePath.isEmpty()) {
protoBuilder.setRule(FieldPath.newBuilder().addAllElements(rulePath));
}
- return new ConstraintViolation(protoBuilder.build(), fieldValue, ruleValue);
+ return new RuleViolation(protoBuilder.build(), fieldValue, ruleValue);
}
private Builder() {}
}
/**
- * Creates a new empty builder for building a {@link ConstraintViolation}.
+ * Creates a new empty builder for building a {@link RuleViolation}.
*
* @return A new, empty {@link Builder}.
*/
@@ -224,7 +224,7 @@ public static Builder newBuilder() {
return new Builder();
}
- private ConstraintViolation(
+ private RuleViolation(
build.buf.validate.Violation proto,
@Nullable FieldValue fieldValue,
@Nullable FieldValue ruleValue) {
@@ -234,7 +234,7 @@ private ConstraintViolation(
}
/**
- * Gets the protobuf data that corresponds to this constraint violation.
+ * Gets the protobuf data that corresponds to this rule violation.
*
* @return The protobuf violation data.
*/
diff --git a/src/main/java/build/buf/protovalidate/ConstraintViolationHelper.java b/src/main/java/build/buf/protovalidate/RuleViolationHelper.java
similarity index 91%
rename from src/main/java/build/buf/protovalidate/ConstraintViolationHelper.java
rename to src/main/java/build/buf/protovalidate/RuleViolationHelper.java
index 05e7ae28..6425fda9 100644
--- a/src/main/java/build/buf/protovalidate/ConstraintViolationHelper.java
+++ b/src/main/java/build/buf/protovalidate/RuleViolationHelper.java
@@ -20,14 +20,14 @@
import java.util.List;
import org.jspecify.annotations.Nullable;
-class ConstraintViolationHelper {
+class RuleViolationHelper {
private static final List EMPTY_PREFIX = new ArrayList<>();
private final @Nullable FieldPath rulePrefix;
private final @Nullable FieldPathElement fieldPathElement;
- ConstraintViolationHelper(@Nullable ValueEvaluator evaluator) {
+ RuleViolationHelper(@Nullable ValueEvaluator evaluator) {
if (evaluator != null) {
this.rulePrefix = evaluator.getNestedRule();
if (evaluator.getDescriptor() != null) {
@@ -41,7 +41,7 @@ class ConstraintViolationHelper {
}
}
- ConstraintViolationHelper(@Nullable FieldPath rulePrefix) {
+ RuleViolationHelper(@Nullable FieldPath rulePrefix) {
this.rulePrefix = rulePrefix;
this.fieldPathElement = null;
}
diff --git a/src/main/java/build/buf/protovalidate/UnknownDescriptorEvaluator.java b/src/main/java/build/buf/protovalidate/UnknownDescriptorEvaluator.java
index 380d457d..b8652d93 100644
--- a/src/main/java/build/buf/protovalidate/UnknownDescriptorEvaluator.java
+++ b/src/main/java/build/buf/protovalidate/UnknownDescriptorEvaluator.java
@@ -38,10 +38,9 @@ public boolean tautology() {
}
@Override
- public List evaluate(Value val, boolean failFast)
+ public List evaluate(Value val, boolean failFast)
throws ExecutionException {
return Collections.singletonList(
- ConstraintViolation.newBuilder()
- .setMessage("No evaluator available for " + desc.getFullName()));
+ RuleViolation.newBuilder().setMessage("No evaluator available for " + desc.getFullName()));
}
}
diff --git a/src/main/java/build/buf/protovalidate/ValidationResult.java b/src/main/java/build/buf/protovalidate/ValidationResult.java
index 39e793ce..eb060f44 100644
--- a/src/main/java/build/buf/protovalidate/ValidationResult.java
+++ b/src/main/java/build/buf/protovalidate/ValidationResult.java
@@ -20,9 +20,8 @@
import java.util.List;
/**
- * {@link ValidationResult} is returned when a constraint is executed. It contains a list of
- * violations. This is non-fatal. If there are no violations, the constraint is considered to have
- * passed.
+ * {@link ValidationResult} is returned when a rule is executed. It contains a list of violations.
+ * This is non-fatal. If there are no violations, the rule is considered to have passed.
*/
public class ValidationResult {
@@ -78,7 +77,7 @@ public String toString() {
}
builder.append(
String.format(
- "%s [%s]", violation.toProto().getMessage(), violation.toProto().getConstraintId()));
+ "%s [%s]", violation.toProto().getMessage(), violation.toProto().getRuleId()));
}
return builder.toString();
}
diff --git a/src/main/java/build/buf/protovalidate/Validator.java b/src/main/java/build/buf/protovalidate/Validator.java
index cb575f00..bc6880dc 100644
--- a/src/main/java/build/buf/protovalidate/Validator.java
+++ b/src/main/java/build/buf/protovalidate/Validator.java
@@ -30,7 +30,7 @@ public class Validator {
private final EvaluatorBuilder evaluatorBuilder;
/**
- * failFast indicates whether the validator should stop evaluating constraints after the first
+ * failFast indicates whether the validator should stop evaluating rules after the first
* violation.
*/
private final boolean failFast;
@@ -55,12 +55,12 @@ public Validator() {
}
/**
- * Checks that message satisfies its constraints. Constraints are defined within the Protobuf file
- * as options from the buf.validate package. A {@link ValidationResult} is returned which contains
- * a list of violations. If the list is empty, the message is valid. If the list is non-empty, the
- * message is invalid. An exception is thrown if the message cannot be validated because the
- * evaluation logic for the message cannot be built ({@link CompilationException}), or there is a
- * type error when attempting to evaluate a CEL expression associated with the message ({@link
+ * Checks that message satisfies its rules. Rules are defined within the Protobuf file as options
+ * from the buf.validate package. A {@link ValidationResult} is returned which contains a list of
+ * violations. If the list is empty, the message is valid. If the list is non-empty, the message
+ * is invalid. An exception is thrown if the message cannot be validated because the evaluation
+ * logic for the message cannot be built ({@link CompilationException}), or there is a type error
+ * when attempting to evaluate a CEL expression associated with the message ({@link
* ExecutionException}).
*
* @param msg the {@link Message} to be validated.
@@ -73,12 +73,12 @@ public ValidationResult validate(Message msg) throws ValidationException {
}
Descriptor descriptor = msg.getDescriptorForType();
Evaluator evaluator = evaluatorBuilder.load(descriptor);
- List result = evaluator.evaluate(new MessageValue(msg), failFast);
+ List result = evaluator.evaluate(new MessageValue(msg), failFast);
if (result.isEmpty()) {
return ValidationResult.EMPTY;
}
List violations = new ArrayList<>(result.size());
- for (ConstraintViolation.Builder builder : result) {
+ for (RuleViolation.Builder builder : result) {
violations.add(builder.build());
}
return new ValidationResult(violations);
diff --git a/src/main/java/build/buf/protovalidate/ValueEvaluator.java b/src/main/java/build/buf/protovalidate/ValueEvaluator.java
index 44af2d91..a967073e 100644
--- a/src/main/java/build/buf/protovalidate/ValueEvaluator.java
+++ b/src/main/java/build/buf/protovalidate/ValueEvaluator.java
@@ -40,8 +40,8 @@ class ValueEvaluator implements Evaluator {
private final List evaluators = new ArrayList<>();
/**
- * Indicates that the Constraints should not be applied if the field is unset or the default
- * (typically zero) value.
+ * Indicates that the Rules should not be applied if the field is unset or the default (typically
+ * zero) value.
*/
private boolean ignoreEmpty;
@@ -69,21 +69,21 @@ public boolean tautology() {
}
@Override
- public List evaluate(Value val, boolean failFast)
+ public List evaluate(Value val, boolean failFast)
throws ExecutionException {
if (this.shouldIgnore(val.value(Object.class))) {
- return ConstraintViolation.NO_VIOLATIONS;
+ return RuleViolation.NO_VIOLATIONS;
}
- List allViolations = new ArrayList<>();
+ List allViolations = new ArrayList<>();
for (Evaluator evaluator : evaluators) {
- List violations = evaluator.evaluate(val, failFast);
+ List violations = evaluator.evaluate(val, failFast);
if (failFast && !violations.isEmpty()) {
return violations;
}
allViolations.addAll(violations);
}
if (allViolations.isEmpty()) {
- return ConstraintViolation.NO_VIOLATIONS;
+ return RuleViolation.NO_VIOLATIONS;
}
return allViolations;
}
diff --git a/src/main/java/build/buf/protovalidate/Violation.java b/src/main/java/build/buf/protovalidate/Violation.java
index ab91edaa..d9666c52 100644
--- a/src/main/java/build/buf/protovalidate/Violation.java
+++ b/src/main/java/build/buf/protovalidate/Violation.java
@@ -18,8 +18,7 @@
import org.jspecify.annotations.Nullable;
/**
- * {@link Violation} provides all of the collected information about an individual constraint
- * violation.
+ * {@link Violation} provides all of the collected information about an individual rule violation.
*/
public interface Violation {
/** {@link FieldValue} represents a Protobuf field value inside a Protobuf message. */
diff --git a/src/main/java/build/buf/protovalidate/exceptions/CompilationException.java b/src/main/java/build/buf/protovalidate/exceptions/CompilationException.java
index 863b1889..3760e942 100644
--- a/src/main/java/build/buf/protovalidate/exceptions/CompilationException.java
+++ b/src/main/java/build/buf/protovalidate/exceptions/CompilationException.java
@@ -14,7 +14,7 @@
package build.buf.protovalidate.exceptions;
-/** CompilationException is returned when a constraint fails to compile. This is a fatal error. */
+/** CompilationException is returned when a rule fails to compile. This is a fatal error. */
public class CompilationException extends ValidationException {
/**
* Creates a CompilationException with the specified message.
diff --git a/src/main/java/build/buf/protovalidate/exceptions/ExecutionException.java b/src/main/java/build/buf/protovalidate/exceptions/ExecutionException.java
index 6342029a..6cd6e856 100644
--- a/src/main/java/build/buf/protovalidate/exceptions/ExecutionException.java
+++ b/src/main/java/build/buf/protovalidate/exceptions/ExecutionException.java
@@ -14,7 +14,7 @@
package build.buf.protovalidate.exceptions;
-/** ExecutionException is returned when a constraint fails to execute. This is a fatal error. */
+/** ExecutionException is returned when a rule fails to execute. This is a fatal error. */
public class ExecutionException extends ValidationException {
/**
* Creates an ExecutionException with the specified message.
diff --git a/src/main/resources/buf/validate/validate.proto b/src/main/resources/buf/validate/validate.proto
index 7d324160..84bd36b8 100644
--- a/src/main/resources/buf/validate/validate.proto
+++ b/src/main/resources/buf/validate/validate.proto
@@ -32,7 +32,7 @@ option java_package = "build.buf.validate";
extend google.protobuf.MessageOptions {
// Rules specify the validations to be performed on this message. By default,
// no validation is performed against a message.
- optional MessageConstraints message = 1159;
+ optional MessageRules message = 1159;
}
// OneofOptions is an extension to google.protobuf.OneofOptions. It allows
@@ -42,7 +42,7 @@ extend google.protobuf.MessageOptions {
extend google.protobuf.OneofOptions {
// Rules specify the validations to be performed on this oneof. By default,
// no validation is performed against a oneof.
- optional OneofConstraints oneof = 1159;
+ optional OneofRules oneof = 1159;
}
// FieldOptions is an extension to google.protobuf.FieldOptions. It allows
@@ -52,9 +52,9 @@ extend google.protobuf.OneofOptions {
extend google.protobuf.FieldOptions {
// Rules specify the validations to be performed on this field. By default,
// no validation is performed against a field.
- optional FieldConstraints field = 1159;
+ optional FieldRules field = 1159;
- // Specifies predefined rules. When extending a standard constraint message,
+ // Specifies predefined rules. When extending a standard rule message,
// this adds additional CEL expressions that apply when the extension is used.
//
// ```proto
@@ -70,11 +70,11 @@ extend google.protobuf.FieldOptions {
// int32 reserved = 1 [(buf.validate.field).int32.(is_zero) = true];
// }
// ```
- optional PredefinedConstraints predefined = 1160;
+ optional PredefinedRules predefined = 1160;
}
-// `Constraint` represents a validation rule written in the Common Expression
-// Language (CEL) syntax. Each Constraint includes a unique identifier, an
+// `Rule` represents a validation rule written in the Common Expression
+// Language (CEL) syntax. Each Rule includes a unique identifier, an
// optional error message, and the CEL expression to evaluate. For more
// information on CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
//
@@ -88,13 +88,13 @@ extend google.protobuf.FieldOptions {
// int32 bar = 1;
// }
// ```
-message Constraint {
- // `id` is a string that serves as a machine-readable name for this Constraint.
+message Rule {
+ // `id` is a string that serves as a machine-readable name for this Rule.
// It should be unique within its scope, which could be either a message or a field.
optional string id = 1;
// `message` is an optional field that provides a human-readable error message
- // for this Constraint when the CEL expression evaluates to false. If a
+ // for this Rule when the CEL expression evaluates to false. If a
// non-empty message is provided, any strings resulting from the CEL
// expression evaluation are ignored.
optional string message = 2;
@@ -106,9 +106,9 @@ message Constraint {
optional string expression = 3;
}
-// MessageConstraints represents validation rules that are applied to the entire message.
-// It includes disabling options and a list of Constraint messages representing Common Expression Language (CEL) validation rules.
-message MessageConstraints {
+// MessageRules represents validation rules that are applied to the entire message.
+// It includes disabling options and a list of Rule messages representing Common Expression Language (CEL) validation rules.
+message MessageRules {
// `disabled` is a boolean flag that, when set to true, nullifies any validation rules for this message.
// This includes any fields within the message that would otherwise support validation.
//
@@ -120,8 +120,8 @@ message MessageConstraints {
// ```
optional bool disabled = 1;
- // `cel` is a repeated field of type Constraint. Each Constraint specifies a validation rule to be applied to this message.
- // These constraints are written in Common Expression Language (CEL) syntax. For more information on
+ // `cel` is a repeated field of type Rule. Each Rule specifies a validation rule to be applied to this message.
+ // These rules are written in Common Expression Language (CEL) syntax. For more information on
// CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
//
//
@@ -136,15 +136,15 @@ message MessageConstraints {
// optional int32 foo = 1;
// }
// ```
- repeated Constraint cel = 3;
+ repeated Rule cel = 3;
}
-// The `OneofConstraints` message type enables you to manage constraints for
+// The `OneofRules` message type enables you to manage rules for
// oneof fields in your protobuf messages.
-message OneofConstraints {
+message OneofRules {
// If `required` is true, exactly one field of the oneof must be present. A
// validation error is returned if no fields in the oneof are present. The
- // field itself may still be a default value; further constraints
+ // field itself may still be a default value; further rules
// should be placed on the fields themselves to ensure they are valid values,
// such as `min_len` or `gt`.
//
@@ -162,9 +162,9 @@ message OneofConstraints {
optional bool required = 1;
}
-// FieldConstraints encapsulates the rules for each type of field. Depending on
+// FieldRules encapsulates the rules for each type of field. Depending on
// the field, the correct set should be used to ensure proper validations.
-message FieldConstraints {
+message FieldRules {
// `cel` is a repeated field used to represent a textual expression
// in the Common Expression Language (CEL) syntax. For more information on
// CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
@@ -179,7 +179,7 @@ message FieldConstraints {
// }];
// }
// ```
- repeated Constraint cel = 23;
+ repeated Rule cel = 23;
// If `required` is true, the field must be populated. A populated field can be
// described as "serialized in the wire format," which includes:
//
@@ -246,9 +246,9 @@ message FieldConstraints {
reserved "skipped", "ignore_empty";
}
-// PredefinedConstraints are custom constraints that can be re-used with
+// PredefinedRules are custom rules that can be re-used with
// multiple fields.
-message PredefinedConstraints {
+message PredefinedRules {
// `cel` is a repeated field used to represent a textual expression
// in the Common Expression Language (CEL) syntax. For more information on
// CEL, [see our documentation](https://github.com/bufbuild/protovalidate/blob/main/docs/cel.md).
@@ -263,7 +263,7 @@ message PredefinedConstraints {
// }];
// }
// ```
- repeated Constraint cel = 1;
+ repeated Rule cel = 1;
reserved 24, 26;
reserved
@@ -272,8 +272,8 @@ message PredefinedConstraints {
;
}
-// Specifies how FieldConstraints.ignore behaves. See the documentation for
-// FieldConstraints.required for definitions of "populated" and "nullable".
+// Specifies how FieldRules.ignore behaves. See the documentation for
+// FieldRules.required for definitions of "populated" and "nullable".
enum Ignore {
// Validation is only skipped if it's an unpopulated nullable fields.
//
@@ -405,7 +405,7 @@ enum Ignore {
// The validation rules of this field will be skipped and not evaluated. This
// is useful for situations that necessitate turning off the rules of a field
// containing a message that may not make sense in the current context, or to
- // temporarily disable constraints during development.
+ // temporarily disable rules during development.
//
// ```proto
// message MyMessage {
@@ -423,7 +423,7 @@ enum Ignore {
;
}
-// FloatRules describes the constraints applied to `float` values. These
+// FloatRules describes the rules applied to `float` values. These
// rules may also be applied to the `google.protobuf.FloatValue` Well-Known-Type.
message FloatRules {
// `const` requires the field value to exactly match the specified value. If
@@ -437,7 +437,7 @@ message FloatRules {
// ```
optional float const = 1 [(predefined).cel = {
id: "float.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
@@ -592,7 +592,7 @@ message FloatRules {
// ```
repeated float in = 6 [(predefined).cel = {
id: "float.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `in` requires the field value to not be equal to any of the specified
@@ -618,7 +618,7 @@ message FloatRules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -635,8 +635,8 @@ message FloatRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -647,7 +647,7 @@ message FloatRules {
extensions 1000 to max;
}
-// DoubleRules describes the constraints applied to `double` values. These
+// DoubleRules describes the rules applied to `double` values. These
// rules may also be applied to the `google.protobuf.DoubleValue` Well-Known-Type.
message DoubleRules {
// `const` requires the field value to exactly match the specified value. If
@@ -661,7 +661,7 @@ message DoubleRules {
// ```
optional double const = 1 [(predefined).cel = {
id: "double.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -813,7 +813,7 @@ message DoubleRules {
// ```
repeated double in = 6 [(predefined).cel = {
id: "double.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -839,7 +839,7 @@ message DoubleRules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -856,8 +856,8 @@ message DoubleRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -868,7 +868,7 @@ message DoubleRules {
extensions 1000 to max;
}
-// Int32Rules describes the constraints applied to `int32` values. These
+// Int32Rules describes the rules applied to `int32` values. These
// rules may also be applied to the `google.protobuf.Int32Value` Well-Known-Type.
message Int32Rules {
// `const` requires the field value to exactly match the specified value. If
@@ -882,7 +882,7 @@ message Int32Rules {
// ```
optional int32 const = 1 [(predefined).cel = {
id: "int32.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field
@@ -1035,7 +1035,7 @@ message Int32Rules {
// ```
repeated int32 in = 6 [(predefined).cel = {
id: "int32.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -1054,7 +1054,7 @@ message Int32Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -1071,8 +1071,8 @@ message Int32Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -1083,7 +1083,7 @@ message Int32Rules {
extensions 1000 to max;
}
-// Int64Rules describes the constraints applied to `int64` values. These
+// Int64Rules describes the rules applied to `int64` values. These
// rules may also be applied to the `google.protobuf.Int64Value` Well-Known-Type.
message Int64Rules {
// `const` requires the field value to exactly match the specified value. If
@@ -1097,7 +1097,7 @@ message Int64Rules {
// ```
optional int64 const = 1 [(predefined).cel = {
id: "int64.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -1250,7 +1250,7 @@ message Int64Rules {
// ```
repeated int64 in = 6 [(predefined).cel = {
id: "int64.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -1269,7 +1269,7 @@ message Int64Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -1286,8 +1286,8 @@ message Int64Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -1298,7 +1298,7 @@ message Int64Rules {
extensions 1000 to max;
}
-// UInt32Rules describes the constraints applied to `uint32` values. These
+// UInt32Rules describes the rules applied to `uint32` values. These
// rules may also be applied to the `google.protobuf.UInt32Value` Well-Known-Type.
message UInt32Rules {
// `const` requires the field value to exactly match the specified value. If
@@ -1312,7 +1312,7 @@ message UInt32Rules {
// ```
optional uint32 const = 1 [(predefined).cel = {
id: "uint32.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -1465,7 +1465,7 @@ message UInt32Rules {
// ```
repeated uint32 in = 6 [(predefined).cel = {
id: "uint32.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -1484,7 +1484,7 @@ message UInt32Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -1501,8 +1501,8 @@ message UInt32Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -1513,7 +1513,7 @@ message UInt32Rules {
extensions 1000 to max;
}
-// UInt64Rules describes the constraints applied to `uint64` values. These
+// UInt64Rules describes the rules applied to `uint64` values. These
// rules may also be applied to the `google.protobuf.UInt64Value` Well-Known-Type.
message UInt64Rules {
// `const` requires the field value to exactly match the specified value. If
@@ -1527,7 +1527,7 @@ message UInt64Rules {
// ```
optional uint64 const = 1 [(predefined).cel = {
id: "uint64.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -1679,7 +1679,7 @@ message UInt64Rules {
// ```
repeated uint64 in = 6 [(predefined).cel = {
id: "uint64.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -1698,7 +1698,7 @@ message UInt64Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -1715,8 +1715,8 @@ message UInt64Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -1727,7 +1727,7 @@ message UInt64Rules {
extensions 1000 to max;
}
-// SInt32Rules describes the constraints applied to `sint32` values.
+// SInt32Rules describes the rules applied to `sint32` values.
message SInt32Rules {
// `const` requires the field value to exactly match the specified value. If
// the field value doesn't match, an error message is generated.
@@ -1740,7 +1740,7 @@ message SInt32Rules {
// ```
optional sint32 const = 1 [(predefined).cel = {
id: "sint32.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field
@@ -1893,7 +1893,7 @@ message SInt32Rules {
// ```
repeated sint32 in = 6 [(predefined).cel = {
id: "sint32.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -1912,7 +1912,7 @@ message SInt32Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -1929,8 +1929,8 @@ message SInt32Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -1941,7 +1941,7 @@ message SInt32Rules {
extensions 1000 to max;
}
-// SInt64Rules describes the constraints applied to `sint64` values.
+// SInt64Rules describes the rules applied to `sint64` values.
message SInt64Rules {
// `const` requires the field value to exactly match the specified value. If
// the field value doesn't match, an error message is generated.
@@ -1954,7 +1954,7 @@ message SInt64Rules {
// ```
optional sint64 const = 1 [(predefined).cel = {
id: "sint64.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field
@@ -2107,7 +2107,7 @@ message SInt64Rules {
// ```
repeated sint64 in = 6 [(predefined).cel = {
id: "sint64.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -2126,7 +2126,7 @@ message SInt64Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -2143,8 +2143,8 @@ message SInt64Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -2155,7 +2155,7 @@ message SInt64Rules {
extensions 1000 to max;
}
-// Fixed32Rules describes the constraints applied to `fixed32` values.
+// Fixed32Rules describes the rules applied to `fixed32` values.
message Fixed32Rules {
// `const` requires the field value to exactly match the specified value.
// If the field value doesn't match, an error message is generated.
@@ -2168,7 +2168,7 @@ message Fixed32Rules {
// ```
optional fixed32 const = 1 [(predefined).cel = {
id: "fixed32.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -2321,7 +2321,7 @@ message Fixed32Rules {
// ```
repeated fixed32 in = 6 [(predefined).cel = {
id: "fixed32.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -2340,7 +2340,7 @@ message Fixed32Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -2357,8 +2357,8 @@ message Fixed32Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -2369,7 +2369,7 @@ message Fixed32Rules {
extensions 1000 to max;
}
-// Fixed64Rules describes the constraints applied to `fixed64` values.
+// Fixed64Rules describes the rules applied to `fixed64` values.
message Fixed64Rules {
// `const` requires the field value to exactly match the specified value. If
// the field value doesn't match, an error message is generated.
@@ -2382,7 +2382,7 @@ message Fixed64Rules {
// ```
optional fixed64 const = 1 [(predefined).cel = {
id: "fixed64.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -2535,7 +2535,7 @@ message Fixed64Rules {
// ```
repeated fixed64 in = 6 [(predefined).cel = {
id: "fixed64.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -2554,7 +2554,7 @@ message Fixed64Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -2571,8 +2571,8 @@ message Fixed64Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -2583,7 +2583,7 @@ message Fixed64Rules {
extensions 1000 to max;
}
-// SFixed32Rules describes the constraints applied to `fixed32` values.
+// SFixed32Rules describes the rules applied to `fixed32` values.
message SFixed32Rules {
// `const` requires the field value to exactly match the specified value. If
// the field value doesn't match, an error message is generated.
@@ -2596,7 +2596,7 @@ message SFixed32Rules {
// ```
optional sfixed32 const = 1 [(predefined).cel = {
id: "sfixed32.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -2749,7 +2749,7 @@ message SFixed32Rules {
// ```
repeated sfixed32 in = 6 [(predefined).cel = {
id: "sfixed32.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -2768,7 +2768,7 @@ message SFixed32Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -2785,8 +2785,8 @@ message SFixed32Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -2797,7 +2797,7 @@ message SFixed32Rules {
extensions 1000 to max;
}
-// SFixed64Rules describes the constraints applied to `fixed64` values.
+// SFixed64Rules describes the rules applied to `fixed64` values.
message SFixed64Rules {
// `const` requires the field value to exactly match the specified value. If
// the field value doesn't match, an error message is generated.
@@ -2810,7 +2810,7 @@ message SFixed64Rules {
// ```
optional sfixed64 const = 1 [(predefined).cel = {
id: "sfixed64.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` requires the field value to be less than the specified value (field <
@@ -2963,7 +2963,7 @@ message SFixed64Rules {
// ```
repeated sfixed64 in = 6 [(predefined).cel = {
id: "sfixed64.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to not be equal to any of the specified
@@ -2982,7 +2982,7 @@ message SFixed64Rules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -2999,8 +2999,8 @@ message SFixed64Rules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -3011,7 +3011,7 @@ message SFixed64Rules {
extensions 1000 to max;
}
-// BoolRules describes the constraints applied to `bool` values. These rules
+// BoolRules describes the rules applied to `bool` values. These rules
// may also be applied to the `google.protobuf.BoolValue` Well-Known-Type.
message BoolRules {
// `const` requires the field value to exactly match the specified boolean value.
@@ -3025,11 +3025,11 @@ message BoolRules {
// ```
optional bool const = 1 [(predefined).cel = {
id: "bool.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -3046,8 +3046,8 @@ message BoolRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -3058,7 +3058,7 @@ message BoolRules {
extensions 1000 to max;
}
-// StringRules describes the constraints applied to `string` values These
+// StringRules describes the rules applied to `string` values These
// rules may also be applied to the `google.protobuf.StringValue` Well-Known-Type.
message StringRules {
// `const` requires the field value to exactly match the specified value. If
@@ -3072,7 +3072,7 @@ message StringRules {
// ```
optional string const = 1 [(predefined).cel = {
id: "string.const"
- expression: "this != rules.const ? 'value must equal `%s`'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal `%s`'.format([getField(rules, 'const')]) : ''"
}];
// `len` dictates that the field value must have the specified
@@ -3258,7 +3258,7 @@ message StringRules {
// ```
repeated string in = 10 [(predefined).cel = {
id: "string.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` specifies that the field value cannot be equal to any
@@ -3275,11 +3275,17 @@ message StringRules {
expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''"
}];
- // `WellKnown` rules provide advanced constraints against common string
- // patterns
+ // `WellKnown` rules provide advanced rules against common string
+ // patterns.
oneof well_known {
- // `email` specifies that the field value must be a valid email address
- // (addr-spec only) as defined by [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1).
+ // `email` specifies that the field value must be a valid email address, for
+ // example "foo@example.com".
+ //
+ // Conforms to the definition for a valid email address from the [HTML standard](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address).
+ // Note that this standard willfully deviates from [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322),
+ // which allows many unexpected forms of email addresses and will easily match
+ // a typographical error.
+ //
// If the field value isn't a valid email address, an error message will be generated.
//
// ```proto
@@ -3301,10 +3307,18 @@ message StringRules {
}
];
- // `hostname` specifies that the field value must be a valid
- // hostname as defined by [RFC 1034](https://datatracker.ietf.org/doc/html/rfc1034#section-3.5). This constraint doesn't support
- // internationalized domain names (IDNs). If the field value isn't a
- // valid hostname, an error message will be generated.
+ // `hostname` specifies that the field value must be a valid hostname, for
+ // example "foo.example.com".
+ //
+ // A valid hostname follows the rules below:
+ // - The name consists of one or more labels, separated by a dot (".").
+ // - Each label can be 1 to 63 alphanumeric characters.
+ // - A label can contain hyphens ("-"), but must not start or end with a hyphen.
+ // - The right-most label must not be digits only.
+ // - The name can have a trailing dot—for example, "foo.example.com.".
+ // - The name can be 253 characters at most, excluding the optional trailing dot.
+ //
+ // If the field value isn't a valid hostname, an error message will be generated.
//
// ```proto
// message MyString {
@@ -3325,8 +3339,15 @@ message StringRules {
}
];
- // `ip` specifies that the field value must be a valid IP
- // (v4 or v6) address, without surrounding square brackets for IPv6 addresses.
+ // `ip` specifies that the field value must be a valid IP (v4 or v6) address.
+ //
+ // IPv4 addresses are expected in the dotted decimal format—for example, "192.168.5.21".
+ // IPv6 addresses are expected in their text representation—for example, "::1",
+ // or "2001:0DB8:ABCD:0012::0".
+ //
+ // Both formats are well-defined in the internet standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986).
+ // Zone identifiers for IPv6 addresses (for example, "fe80::a%en1") are supported.
+ //
// If the field value isn't a valid IP address, an error message will be
// generated.
//
@@ -3349,9 +3370,9 @@ message StringRules {
}
];
- // `ipv4` specifies that the field value must be a valid IPv4
- // address. If the field value isn't a valid IPv4 address, an error message
- // will be generated.
+ // `ipv4` specifies that the field value must be a valid IPv4 address—for
+ // example "192.168.5.21". If the field value isn't a valid IPv4 address, an
+ // error message will be generated.
//
// ```proto
// message MyString {
@@ -3372,9 +3393,9 @@ message StringRules {
}
];
- // `ipv6` specifies that the field value must be a valid
- // IPv6 address, without surrounding square brackets. If the field value is
- // not a valid IPv6 address, an error message will be generated.
+ // `ipv6` specifies that the field value must be a valid IPv6 address—for
+ // example "::1", or "d7a:115c:a1e0:ab12:4843:cd96:626b:430b". If the field
+ // value is not a valid IPv6 address, an error message will be generated.
//
// ```proto
// message MyString {
@@ -3395,8 +3416,11 @@ message StringRules {
}
];
- // `uri` specifies that the field value must be a valid URI as defined by
- // [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-3).
+ // `uri` specifies that the field value must be a valid URI, for example
+ // "https://example.com/foo/bar?baz=quux#frag".
+ //
+ // URI is defined in the internet standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986).
+ // Zone Identifiers in IPv6 address literals are supported ([RFC 6874](https://datatracker.ietf.org/doc/html/rfc6874)).
//
// If the field value isn't a valid URI, an error message will be generated.
//
@@ -3419,11 +3443,13 @@ message StringRules {
}
];
- // `uri_ref` specifies that the field value must be a valid URI Reference as
- // defined by [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-4.1).
+ // `uri_ref` specifies that the field value must be a valid URI Reference—either
+ // a URI such as "https://example.com/foo/bar?baz=quux#frag", or a Relative
+ // Reference such as "./foo/bar?query".
//
- // A URI Reference is either a [URI](https://datatracker.ietf.org/doc/html/rfc3986#section-3),
- // or a [Relative Reference](https://datatracker.ietf.org/doc/html/rfc3986#section-4.2).
+ // URI, URI Reference, and Relative Reference are defined in the internet
+ // standard [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986). Zone
+ // Identifiers in IPv6 address literals are supported ([RFC 6874](https://datatracker.ietf.org/doc/html/rfc6874)).
//
// If the field value isn't a valid URI Reference, an error message will be
// generated.
@@ -3441,10 +3467,9 @@ message StringRules {
}];
// `address` specifies that the field value must be either a valid hostname
- // as defined by [RFC 1034](https://datatracker.ietf.org/doc/html/rfc1034#section-3.5)
- // (which doesn't support internationalized domain names or IDNs) or a valid
- // IP (v4 or v6). If the field value isn't a valid hostname or IP, an error
- // message will be generated.
+ // (for example, "example.com"), or a valid IP (v4 or v6) address (for example,
+ // "192.168.0.1", or "::1"). If the field value isn't a valid hostname or IP,
+ // an error message will be generated.
//
// ```proto
// message MyString {
@@ -3512,10 +3537,10 @@ message StringRules {
}
];
- // `ip_with_prefixlen` specifies that the field value must be a valid IP (v4 or v6)
- // address with prefix length. If the field value isn't a valid IP with prefix
- // length, an error message will be generated.
- //
+ // `ip_with_prefixlen` specifies that the field value must be a valid IP
+ // (v4 or v6) address with prefix length—for example, "192.168.5.21/16" or
+ // "2001:0DB8:ABCD:0012::F1/64". If the field value isn't a valid IP with
+ // prefix length, an error message will be generated.
//
// ```proto
// message MyString {
@@ -3537,9 +3562,9 @@ message StringRules {
];
// `ipv4_with_prefixlen` specifies that the field value must be a valid
- // IPv4 address with prefix.
- // If the field value isn't a valid IPv4 address with prefix length,
- // an error message will be generated.
+ // IPv4 address with prefix length—for example, "192.168.5.21/16". If the
+ // field value isn't a valid IPv4 address with prefix length, an error
+ // message will be generated.
//
// ```proto
// message MyString {
@@ -3561,7 +3586,7 @@ message StringRules {
];
// `ipv6_with_prefixlen` specifies that the field value must be a valid
- // IPv6 address with prefix length.
+ // IPv6 address with prefix length—for example, "2001:0DB8:ABCD:0012::F1/64".
// If the field value is not a valid IPv6 address with prefix length,
// an error message will be generated.
//
@@ -3584,10 +3609,15 @@ message StringRules {
}
];
- // `ip_prefix` specifies that the field value must be a valid IP (v4 or v6) prefix.
+ // `ip_prefix` specifies that the field value must be a valid IP (v4 or v6)
+ // prefix—for example, "192.168.0.0/16" or "2001:0DB8:ABCD:0012::0/64".
+ //
+ // The prefix must have all zeros for the unmasked bits. For example,
+ // "2001:0DB8:ABCD:0012::0/64" designates the left-most 64 bits for the
+ // prefix, and the remaining 64 bits must be zero.
+ //
// If the field value isn't a valid IP prefix, an error message will be
- // generated. The prefix must have all zeros for the masked bits of the prefix (e.g.,
- // `127.0.0.0/16`, not `127.0.0.1/16`).
+ // generated.
//
// ```proto
// message MyString {
@@ -3609,9 +3639,14 @@ message StringRules {
];
// `ipv4_prefix` specifies that the field value must be a valid IPv4
- // prefix. If the field value isn't a valid IPv4 prefix, an error message
- // will be generated. The prefix must have all zeros for the masked bits of
- // the prefix (e.g., `127.0.0.0/16`, not `127.0.0.1/16`).
+ // prefix, for example "192.168.0.0/16".
+ //
+ // The prefix must have all zeros for the unmasked bits. For example,
+ // "192.168.0.0/16" designates the left-most 16 bits for the prefix,
+ // and the remaining 16 bits must be zero.
+ //
+ // If the field value isn't a valid IPv4 prefix, an error message
+ // will be generated.
//
// ```proto
// message MyString {
@@ -3632,10 +3667,15 @@ message StringRules {
}
];
- // `ipv6_prefix` specifies that the field value must be a valid IPv6 prefix.
+ // `ipv6_prefix` specifies that the field value must be a valid IPv6 prefix—for
+ // example, "2001:0DB8:ABCD:0012::0/64".
+ //
+ // The prefix must have all zeros for the unmasked bits. For example,
+ // "2001:0DB8:ABCD:0012::0/64" designates the left-most 64 bits for the
+ // prefix, and the remaining 64 bits must be zero.
+ //
// If the field value is not a valid IPv6 prefix, an error message will be
- // generated. The prefix must have all zeros for the masked bits of the prefix
- // (e.g., `2001:db8::/48`, not `2001:db8::1/48`).
+ // generated.
//
// ```proto
// message MyString {
@@ -3656,10 +3696,16 @@ message StringRules {
}
];
- // `host_and_port` specifies the field value must be a valid host and port
- // pair. The host must be a valid hostname or IP address while the port
- // must be in the range of 0-65535, inclusive. IPv6 addresses must be delimited
- // with square brackets (e.g., `[::1]:1234`).
+ // `host_and_port` specifies that the field value must be valid host/port
+ // pair—for example, "example.com:8080".
+ //
+ // The host can be one of:
+ //- An IPv4 address in dotted decimal format—for example, "192.168.5.21".
+ //- An IPv6 address enclosed in square brackets—for example, "[2001:0DB8:ABCD:0012::F1]".
+ //- A hostname—for example, "example.com".
+ //
+ // The port is separated by a colon. It must be non-empty, with a decimal number
+ // in the range of 0-65535, inclusive.
bool host_and_port = 32 [
(predefined).cel = {
id: "string.host_and_port"
@@ -3733,7 +3779,7 @@ message StringRules {
optional bool strict = 25;
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -3750,8 +3796,8 @@ message StringRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -3773,7 +3819,7 @@ enum KnownRegex {
KNOWN_REGEX_HTTP_HEADER_VALUE = 2;
}
-// BytesRules describe the constraints applied to `bytes` values. These rules
+// BytesRules describe the rules applied to `bytes` values. These rules
// may also be applied to the `google.protobuf.BytesValue` Well-Known-Type.
message BytesRules {
// `const` requires the field value to exactly match the specified bytes
@@ -3787,7 +3833,7 @@ message BytesRules {
// ```
optional bytes const = 1 [(predefined).cel = {
id: "bytes.const"
- expression: "this != rules.const ? 'value must be %x'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must be %x'.format([getField(rules, 'const')]) : ''"
}];
// `len` requires the field value to have the specified length in bytes.
@@ -3908,7 +3954,7 @@ message BytesRules {
// ```
repeated bytes in = 8 [(predefined).cel = {
id: "bytes.in"
- expression: "dyn(rules)['in'].size() > 0 && !(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "getField(rules, 'in').size() > 0 && !(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to be not equal to any of the specified
@@ -3927,11 +3973,11 @@ message BytesRules {
expression: "this in rules.not_in ? 'value must not be in list %s'.format([rules.not_in]) : ''"
}];
- // WellKnown rules provide advanced constraints against common byte
+ // WellKnown rules provide advanced rules against common byte
// patterns
oneof well_known {
// `ip` ensures that the field `value` is a valid IP address (v4 or v6) in byte format.
- // If the field value doesn't meet this constraint, an error message is generated.
+ // If the field value doesn't meet this rule, an error message is generated.
//
// ```proto
// message MyBytes {
@@ -3953,7 +3999,7 @@ message BytesRules {
];
// `ipv4` ensures that the field `value` is a valid IPv4 address in byte format.
- // If the field value doesn't meet this constraint, an error message is generated.
+ // If the field value doesn't meet this rule, an error message is generated.
//
// ```proto
// message MyBytes {
@@ -3975,7 +4021,7 @@ message BytesRules {
];
// `ipv6` ensures that the field `value` is a valid IPv6 address in byte format.
- // If the field value doesn't meet this constraint, an error message is generated.
+ // If the field value doesn't meet this rule, an error message is generated.
// ```proto
// message MyBytes {
// // value must be a valid IPv6 address
@@ -3997,7 +4043,7 @@ message BytesRules {
}
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -4014,8 +4060,8 @@ message BytesRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4026,7 +4072,7 @@ message BytesRules {
extensions 1000 to max;
}
-// EnumRules describe the constraints applied to `enum` values.
+// EnumRules describe the rules applied to `enum` values.
message EnumRules {
// `const` requires the field value to exactly match the specified enum value.
// If the field value doesn't match, an error message is generated.
@@ -4045,7 +4091,7 @@ message EnumRules {
// ```
optional int32 const = 1 [(predefined).cel = {
id: "enum.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
// `defined_only` requires the field value to be one of the defined values for
@@ -4083,7 +4129,7 @@ message EnumRules {
// ```
repeated int32 in = 3 [(predefined).cel = {
id: "enum.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` requires the field value to be not equal to any of the
@@ -4108,7 +4154,7 @@ message EnumRules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -4129,8 +4175,8 @@ message EnumRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4141,7 +4187,7 @@ message EnumRules {
extensions 1000 to max;
}
-// RepeatedRules describe the constraints applied to `repeated` values.
+// RepeatedRules describe the rules applied to `repeated` values.
message RepeatedRules {
// `min_items` requires that this field must contain at least the specified
// minimum number of items.
@@ -4176,7 +4222,7 @@ message RepeatedRules {
}];
// `unique` indicates that all elements in this field must
- // be unique. This constraint is strictly applicable to scalar and enum
+ // be unique. This rule is strictly applicable to scalar and enum
// types, with message types not being supported.
//
// ```proto
@@ -4191,13 +4237,13 @@ message RepeatedRules {
expression: "!rules.unique || this.unique()"
}];
- // `items` details the constraints to be applied to each item
+ // `items` details the rules to be applied to each item
// in the field. Even for repeated message fields, validation is executed
// against each item unless skip is explicitly specified.
//
// ```proto
// message MyRepeated {
- // // The items in the field `value` must follow the specified constraints.
+ // // The items in the field `value` must follow the specified rules.
// repeated string value = 1 [(buf.validate.field).repeated.items = {
// string: {
// min_len: 3
@@ -4206,11 +4252,11 @@ message RepeatedRules {
// }];
// }
// ```
- optional FieldConstraints items = 4;
+ optional FieldRules items = 4;
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4221,7 +4267,7 @@ message RepeatedRules {
extensions 1000 to max;
}
-// MapRules describe the constraints applied to `map` values.
+// MapRules describe the rules applied to `map` values.
message MapRules {
//Specifies the minimum number of key-value pairs allowed. If the field has
// fewer key-value pairs than specified, an error message is generated.
@@ -4251,11 +4297,11 @@ message MapRules {
expression: "uint(this.size()) > rules.max_pairs ? 'map must be at most %d entries'.format([rules.max_pairs]) : ''"
}];
- //Specifies the constraints to be applied to each key in the field.
+ //Specifies the rules to be applied to each key in the field.
//
// ```proto
// message MyMap {
- // // The keys in the field `value` must follow the specified constraints.
+ // // The keys in the field `value` must follow the specified rules.
// map value = 1 [(buf.validate.field).map.keys = {
// string: {
// min_len: 3
@@ -4264,15 +4310,15 @@ message MapRules {
// }];
// }
// ```
- optional FieldConstraints keys = 4;
+ optional FieldRules keys = 4;
- //Specifies the constraints to be applied to the value of each key in the
+ //Specifies the rules to be applied to the value of each key in the
// field. Message values will still have their validations evaluated unless
//skip is specified here.
//
// ```proto
// message MyMap {
- // // The values in the field `value` must follow the specified constraints.
+ // // The values in the field `value` must follow the specified rules.
// map value = 1 [(buf.validate.field).map.values = {
// string: {
// min_len: 5
@@ -4281,11 +4327,11 @@ message MapRules {
// }];
// }
// ```
- optional FieldConstraints values = 5;
+ optional FieldRules values = 5;
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4296,7 +4342,7 @@ message MapRules {
extensions 1000 to max;
}
-// AnyRules describe constraints applied exclusively to the `google.protobuf.Any` well-known type.
+// AnyRules describe rules applied exclusively to the `google.protobuf.Any` well-known type.
message AnyRules {
// `in` requires the field's `type_url` to be equal to one of the
//specified values. If it doesn't match any of the specified values, an error
@@ -4321,7 +4367,7 @@ message AnyRules {
repeated string not_in = 3;
}
-// DurationRules describe the constraints applied exclusively to the `google.protobuf.Duration` well-known type.
+// DurationRules describe the rules applied exclusively to the `google.protobuf.Duration` well-known type.
message DurationRules {
// `const` dictates that the field must match the specified value of the `google.protobuf.Duration` type exactly.
// If the field's value deviates from the specified value, an error message
@@ -4335,7 +4381,7 @@ message DurationRules {
// ```
optional google.protobuf.Duration const = 2 [(predefined).cel = {
id: "duration.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// `lt` stipulates that the field must be less than the specified value of the `google.protobuf.Duration` type,
@@ -4488,7 +4534,7 @@ message DurationRules {
// ```
repeated google.protobuf.Duration in = 7 [(predefined).cel = {
id: "duration.in"
- expression: "!(this in dyn(rules)['in']) ? 'value must be in list %s'.format([dyn(rules)['in']]) : ''"
+ expression: "!(this in getField(rules, 'in')) ? 'value must be in list %s'.format([getField(rules, 'in')]) : ''"
}];
// `not_in` denotes that the field must not be equal to
@@ -4508,7 +4554,7 @@ message DurationRules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -4525,8 +4571,8 @@ message DurationRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4537,7 +4583,7 @@ message DurationRules {
extensions 1000 to max;
}
-// TimestampRules describe the constraints applied exclusively to the `google.protobuf.Timestamp` well-known type.
+// TimestampRules describe the rules applied exclusively to the `google.protobuf.Timestamp` well-known type.
message TimestampRules {
// `const` dictates that this field, of the `google.protobuf.Timestamp` type, must exactly match the specified value. If the field value doesn't correspond to the specified timestamp, an error message will be generated.
//
@@ -4549,7 +4595,7 @@ message TimestampRules {
// ```
optional google.protobuf.Timestamp const = 2 [(predefined).cel = {
id: "timestamp.const"
- expression: "this != rules.const ? 'value must equal %s'.format([rules.const]) : ''"
+ expression: "this != getField(rules, 'const') ? 'value must equal %s'.format([getField(rules, 'const')]) : ''"
}];
oneof less_than {
// requires the duration field value to be less than the specified value (field < value). If the field value doesn't meet the required conditions, an error message is generated.
@@ -4726,7 +4772,7 @@ message TimestampRules {
}];
// `example` specifies values that the field may have. These values SHOULD
- // conform to other constraints. `example` values will not impact validation
+ // conform to other rules. `example` values will not impact validation
// but may be used as helpful guidance on how to populate the given field.
//
// ```proto
@@ -4744,8 +4790,8 @@ message TimestampRules {
}];
// Extension fields in this range that have the (buf.validate.predefined)
- // option set will be treated as predefined field constraints that can then be
- // set on the field options of other fields to apply field constraints.
+ // option set will be treated as predefined field rules that can then be
+ // set on the field options of other fields to apply field rules.
// Extension numbers 1000 to 99999 are reserved for extension numbers that are
// defined in the [Protobuf Global Extension Registry][1]. Extension numbers
// above this range are reserved for extension numbers that are not explicitly
@@ -4757,7 +4803,7 @@ message TimestampRules {
}
// `Violations` is a collection of `Violation` messages. This message type is returned by
-// protovalidate when a proto message fails to meet the requirements set by the `Constraint` validation rules.
+// protovalidate when a proto message fails to meet the requirements set by the `Rule` validation rules.
// Each individual violation is represented by a `Violation` message.
message Violations {
// `violations` is a repeated field that contains all the `Violation` messages corresponding to the violations detected.
@@ -4765,14 +4811,14 @@ message Violations {
}
// `Violation` represents a single instance where a validation rule, expressed
-// as a `Constraint`, was not met. It provides information about the field that
-// caused the violation, the specific constraint that wasn't fulfilled, and a
+// as a `Rule`, was not met. It provides information about the field that
+// caused the violation, the specific rule that wasn't fulfilled, and a
// human-readable error message.
//
// ```json
// {
// "fieldPath": "bar",
-// "constraintId": "foo.bar",
+// "ruleId": "foo.bar",
// "message": "bar must be greater than 0"
// }
// ```
@@ -4798,9 +4844,9 @@ message Violation {
// ```
optional FieldPath field = 5;
- // `rule` is a machine-readable path that points to the specific constraint rule that failed validation.
- // This will be a nested field starting from the FieldConstraints of the field that failed validation.
- // For custom constraints, this will provide the path of the constraint, e.g. `cel[0]`.
+ // `rule` is a machine-readable path that points to the specific rule rule that failed validation.
+ // This will be a nested field starting from the FieldRules of the field that failed validation.
+ // For custom rules, this will provide the path of the rule, e.g. `cel[0]`.
//
// For example, consider the following message:
//
@@ -4808,7 +4854,7 @@ message Violation {
// message Message {
// bool a = 1 [(buf.validate.field).required = true];
// bool b = 2 [(buf.validate.field).cel = {
- // id: "custom_constraint",
+ // id: "custom_rule",
// expression: "!this ? 'b must be true': ''"
// }]
// }
@@ -4828,12 +4874,12 @@ message Violation {
// ```
optional FieldPath rule = 6;
- // `constraint_id` is the unique identifier of the `Constraint` that was not fulfilled.
- // This is the same `id` that was specified in the `Constraint` message, allowing easy tracing of which rule was violated.
- optional string constraint_id = 2;
+ // `rule_id` is the unique identifier of the `Rule` that was not fulfilled.
+ // This is the same `id` that was specified in the `Rule` message, allowing easy tracing of which rule was violated.
+ optional string rule_id = 2;
// `message` is a human-readable error message that describes the nature of the violation.
- // This can be the default error message from the violated `Constraint`, or it can be a custom message that gives more context about the violation.
+ // This can be the default error message from the violated `Rule`, or it can be a custom message that gives more context about the violation.
optional string message = 3;
// `for_key` indicates whether the violation was caused by a map key, rather than a value.
diff --git a/src/test/java/build/buf/protovalidate/ValidatorCelExpressionTest.java b/src/test/java/build/buf/protovalidate/ValidatorCelExpressionTest.java
index e613476f..b709a680 100644
--- a/src/test/java/build/buf/protovalidate/ValidatorCelExpressionTest.java
+++ b/src/test/java/build/buf/protovalidate/ValidatorCelExpressionTest.java
@@ -16,16 +16,14 @@
import static org.assertj.core.api.Assertions.assertThat;
-import build.buf.validate.FieldConstraints;
import build.buf.validate.FieldPath;
+import build.buf.validate.FieldRules;
import build.buf.validate.Violation;
import com.example.imports.buf.validate.RepeatedRules;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
-/**
- * This test verifies that custom (CEL-based) field and/or message constraints evaluate as expected.
- */
+/** This test verifies that custom (CEL-based) field and/or message rules evaluate as expected. */
public class ValidatorCelExpressionTest {
@Test
@@ -68,12 +66,12 @@ public void testFieldExpressionRepeatedMessage() throws Exception {
FieldPath.newBuilder()
.addElements(
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor()
- .findFieldByNumber(FieldConstraints.CEL_FIELD_NUMBER))
+ FieldRules.getDescriptor()
+ .findFieldByNumber(FieldRules.CEL_FIELD_NUMBER))
.toBuilder()
.setIndex(0)
.build()))
- .setConstraintId("field_expression.repeated.message")
+ .setRuleId("field_expression.repeated.message")
.setMessage("test message field_expression.repeated.message")
.build();
@@ -130,19 +128,19 @@ public void testFieldExpressionRepeatedMessageItems() throws Exception {
FieldPath.newBuilder()
.addElements(
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor()
- .findFieldByNumber(FieldConstraints.REPEATED_FIELD_NUMBER)))
+ FieldRules.getDescriptor()
+ .findFieldByNumber(FieldRules.REPEATED_FIELD_NUMBER)))
.addElements(
FieldPathUtils.fieldPathElement(
RepeatedRules.getDescriptor().findFieldByName("items")))
.addElements(
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor()
- .findFieldByNumber(FieldConstraints.CEL_FIELD_NUMBER))
+ FieldRules.getDescriptor()
+ .findFieldByNumber(FieldRules.CEL_FIELD_NUMBER))
.toBuilder()
.setIndex(0)
.build()))
- .setConstraintId("field_expression.repeated.message.items")
+ .setRuleId("field_expression.repeated.message.items")
.setMessage("test message field_expression.repeated.message.items")
.build();
diff --git a/src/test/java/build/buf/protovalidate/ValidatorDifferentJavaPackagesTest.java b/src/test/java/build/buf/protovalidate/ValidatorDifferentJavaPackagesTest.java
index 17940266..917f9c43 100644
--- a/src/test/java/build/buf/protovalidate/ValidatorDifferentJavaPackagesTest.java
+++ b/src/test/java/build/buf/protovalidate/ValidatorDifferentJavaPackagesTest.java
@@ -17,12 +17,12 @@
import static org.assertj.core.api.Assertions.assertThat;
import build.buf.protovalidate.exceptions.ValidationException;
-import build.buf.validate.FieldConstraints;
import build.buf.validate.FieldPath;
import build.buf.validate.FieldPathElement;
+import build.buf.validate.FieldRules;
import build.buf.validate.Violation;
import com.example.imports.buf.validate.StringRules;
-import com.example.imports.validationtest.ExampleFieldConstraints;
+import com.example.imports.validationtest.ExampleFieldRules;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import java.util.Collections;
@@ -60,23 +60,23 @@
*/
public class ValidatorDifferentJavaPackagesTest {
@Test
- public void testValidationFieldConstraints() throws Exception {
+ public void testValidationFieldRules() throws Exception {
// Valid message - matches regex
- com.example.imports.validationtest.ExampleFieldConstraints validMsgImports =
- com.example.imports.validationtest.ExampleFieldConstraints.newBuilder()
+ com.example.imports.validationtest.ExampleFieldRules validMsgImports =
+ com.example.imports.validationtest.ExampleFieldRules.newBuilder()
.setRegexStringField("abc123")
.build();
expectNoViolations(validMsgImports);
// Create same message under noimports package. Validation behavior should match.
- com.example.noimports.validationtest.ExampleFieldConstraints validMsgNoImports =
- com.example.noimports.validationtest.ExampleFieldConstraints.parseFrom(
+ com.example.noimports.validationtest.ExampleFieldRules validMsgNoImports =
+ com.example.noimports.validationtest.ExampleFieldRules.parseFrom(
validMsgImports.toByteString());
expectNoViolations(validMsgNoImports);
// 10 chars long - regex requires 1-9 chars
- com.example.imports.validationtest.ExampleFieldConstraints invalidMsgImports =
- com.example.imports.validationtest.ExampleFieldConstraints.newBuilder()
+ com.example.imports.validationtest.ExampleFieldRules invalidMsgImports =
+ com.example.imports.validationtest.ExampleFieldRules.newBuilder()
.setRegexStringField("0123456789")
.build();
Violation expectedViolation =
@@ -85,96 +85,94 @@ public void testValidationFieldConstraints() throws Exception {
FieldPath.newBuilder()
.addElements(
FieldPathUtils.fieldPathElement(
- com.example.imports.validationtest.ExampleFieldConstraints
- .getDescriptor()
+ com.example.imports.validationtest.ExampleFieldRules.getDescriptor()
.findFieldByNumber(
- ExampleFieldConstraints.REGEX_STRING_FIELD_FIELD_NUMBER))))
+ ExampleFieldRules.REGEX_STRING_FIELD_FIELD_NUMBER))))
.setRule(
FieldPath.newBuilder()
.addElements(
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor()
- .findFieldByNumber(FieldConstraints.STRING_FIELD_NUMBER)))
+ FieldRules.getDescriptor()
+ .findFieldByNumber(FieldRules.STRING_FIELD_NUMBER)))
.addElements(
FieldPathUtils.fieldPathElement(
StringRules.getDescriptor()
.findFieldByNumber(StringRules.PATTERN_FIELD_NUMBER))))
- .setConstraintId("string.pattern")
+ .setRuleId("string.pattern")
.setMessage("value does not match regex pattern `^[a-z0-9]{1,9}$`")
.build();
expectViolation(invalidMsgImports, expectedViolation);
// Create same message under noimports package. Validation behavior should match.
- com.example.noimports.validationtest.ExampleFieldConstraints invalidMsgNoImports =
- com.example.noimports.validationtest.ExampleFieldConstraints.newBuilder()
+ com.example.noimports.validationtest.ExampleFieldRules invalidMsgNoImports =
+ com.example.noimports.validationtest.ExampleFieldRules.newBuilder()
.setRegexStringField("0123456789")
.build();
expectViolation(invalidMsgNoImports, expectedViolation);
}
@Test
- public void testValidationOneofConstraints()
+ public void testValidationOneofRules()
throws ValidationException, InvalidProtocolBufferException {
- // Valid message - matches oneof constraint
- com.example.imports.validationtest.ExampleOneofConstraints validMsgImports =
- com.example.imports.validationtest.ExampleOneofConstraints.newBuilder()
+ // Valid message - matches oneof rule
+ com.example.imports.validationtest.ExampleOneofRules validMsgImports =
+ com.example.imports.validationtest.ExampleOneofRules.newBuilder()
.setEmail("foo@bar.com")
.build();
expectNoViolations(validMsgImports);
// Create same message under noimports package. Validation behavior should match.
- com.example.noimports.validationtest.ExampleOneofConstraints validMsgNoImports =
- com.example.noimports.validationtest.ExampleOneofConstraints.parseFrom(
+ com.example.noimports.validationtest.ExampleOneofRules validMsgNoImports =
+ com.example.noimports.validationtest.ExampleOneofRules.parseFrom(
validMsgImports.toByteString());
expectNoViolations(validMsgNoImports);
- com.example.imports.validationtest.ExampleOneofConstraints invalidMsgImports =
- com.example.imports.validationtest.ExampleOneofConstraints.getDefaultInstance();
+ com.example.imports.validationtest.ExampleOneofRules invalidMsgImports =
+ com.example.imports.validationtest.ExampleOneofRules.getDefaultInstance();
Violation expectedViolation =
Violation.newBuilder()
.setField(
FieldPath.newBuilder()
.addElements(FieldPathElement.newBuilder().setFieldName("contact_info")))
- .setConstraintId("required")
+ .setRuleId("required")
.setMessage("exactly one field is required in oneof")
.build();
expectViolation(invalidMsgImports, expectedViolation);
// Create same message under noimports package. Validation behavior should match.
- com.example.noimports.validationtest.ExampleOneofConstraints invalidMsgNoImports =
- com.example.noimports.validationtest.ExampleOneofConstraints.parseFrom(
+ com.example.noimports.validationtest.ExampleOneofRules invalidMsgNoImports =
+ com.example.noimports.validationtest.ExampleOneofRules.parseFrom(
invalidMsgImports.toByteString());
expectViolation(invalidMsgNoImports, expectedViolation);
}
@Test
- public void testValidationMessageConstraintsDifferentJavaPackage() throws Exception {
- com.example.imports.validationtest.ExampleMessageConstraints validMsg =
- com.example.imports.validationtest.ExampleMessageConstraints.newBuilder()
+ public void testValidationMessageRulesDifferentJavaPackage() throws Exception {
+ com.example.imports.validationtest.ExampleMessageRules validMsg =
+ com.example.imports.validationtest.ExampleMessageRules.newBuilder()
.setPrimaryEmail("foo@bar.com")
.build();
expectNoViolations(validMsg);
// Create same message under noimports package. Validation behavior should match.
- com.example.noimports.validationtest.ExampleMessageConstraints validMsgNoImports =
- com.example.noimports.validationtest.ExampleMessageConstraints.parseFrom(
- validMsg.toByteString());
+ com.example.noimports.validationtest.ExampleMessageRules validMsgNoImports =
+ com.example.noimports.validationtest.ExampleMessageRules.parseFrom(validMsg.toByteString());
expectNoViolations(validMsgNoImports);
- com.example.imports.validationtest.ExampleMessageConstraints invalidMsgImports =
- com.example.imports.validationtest.ExampleMessageConstraints.newBuilder()
+ com.example.imports.validationtest.ExampleMessageRules invalidMsgImports =
+ com.example.imports.validationtest.ExampleMessageRules.newBuilder()
.setSecondaryEmail("foo@bar.com")
.build();
Violation expectedViolation =
Violation.newBuilder()
- .setConstraintId("secondary_email_depends_on_primary")
+ .setRuleId("secondary_email_depends_on_primary")
.setMessage("cannot set a secondary email without setting a primary one")
.build();
expectViolation(invalidMsgImports, expectedViolation);
// Create same message under noimports package. Validation behavior should match.
- com.example.noimports.validationtest.ExampleMessageConstraints invalidMsgNoImports =
- com.example.noimports.validationtest.ExampleMessageConstraints.parseFrom(
+ com.example.noimports.validationtest.ExampleMessageRules invalidMsgNoImports =
+ com.example.noimports.validationtest.ExampleMessageRules.parseFrom(
invalidMsgImports.toByteString());
expectViolation(invalidMsgNoImports, expectedViolation);
}
diff --git a/src/test/java/build/buf/protovalidate/ValidatorDynamicMessageTest.java b/src/test/java/build/buf/protovalidate/ValidatorDynamicMessageTest.java
index 685f7f75..1b0a542d 100644
--- a/src/test/java/build/buf/protovalidate/ValidatorDynamicMessageTest.java
+++ b/src/test/java/build/buf/protovalidate/ValidatorDynamicMessageTest.java
@@ -17,16 +17,16 @@
import static com.example.imports.validationtest.PredefinedProto.isIdent;
import static org.assertj.core.api.Assertions.assertThat;
-import build.buf.validate.FieldConstraints;
import build.buf.validate.FieldPath;
import build.buf.validate.FieldPathElement;
+import build.buf.validate.FieldRules;
import build.buf.validate.Violation;
import com.example.imports.buf.validate.StringRules;
-import com.example.imports.validationtest.ExamplePredefinedFieldConstraints;
-import com.example.noimports.validationtest.ExampleFieldConstraints;
-import com.example.noimports.validationtest.ExampleMessageConstraints;
-import com.example.noimports.validationtest.ExampleOneofConstraints;
-import com.example.noimports.validationtest.ExampleRequiredFieldConstraints;
+import com.example.imports.validationtest.ExamplePredefinedFieldRules;
+import com.example.noimports.validationtest.ExampleFieldRules;
+import com.example.noimports.validationtest.ExampleMessageRules;
+import com.example.noimports.validationtest.ExampleOneofRules;
+import com.example.noimports.validationtest.ExampleRequiredFieldRules;
import com.example.noimports.validationtest.PredefinedProto;
import com.google.protobuf.DescriptorProtos;
import com.google.protobuf.Descriptors;
@@ -46,14 +46,14 @@
* This test mimics the behavior when performing validation with protovalidate on a file descriptor
* set (as created by protoc --retain_options --descriptor_set_out=...
). These
* descriptor types have the protovalidate extensions as unknown fields and need to be parsed with
- * an extension registry for the constraints to be recognized and validated.
+ * an extension registry for the rules to be recognized and validated.
*/
public class ValidatorDynamicMessageTest {
@Test
- public void testFieldConstraintDynamicMessage() throws Exception {
+ public void testFieldRuleDynamicMessage() throws Exception {
DynamicMessage.Builder messageBuilder =
- createMessageWithUnknownOptions(ExampleFieldConstraints.getDefaultInstance());
+ createMessageWithUnknownOptions(ExampleFieldRules.getDefaultInstance());
messageBuilder.setField(
messageBuilder.getDescriptorForType().findFieldByName("regex_string_field"), "0123456789");
Violation expectedViolation =
@@ -69,13 +69,13 @@ public void testFieldConstraintDynamicMessage() throws Exception {
FieldPath.newBuilder()
.addElements(
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor()
- .findFieldByNumber(FieldConstraints.STRING_FIELD_NUMBER)))
+ FieldRules.getDescriptor()
+ .findFieldByNumber(FieldRules.STRING_FIELD_NUMBER)))
.addElements(
FieldPathUtils.fieldPathElement(
StringRules.getDescriptor()
.findFieldByNumber(StringRules.PATTERN_FIELD_NUMBER))))
- .setConstraintId("string.pattern")
+ .setRuleId("string.pattern")
.setMessage("value does not match regex pattern `^[a-z0-9]{1,9}$`")
.build();
ValidationResult result = new Validator().validate(messageBuilder.build());
@@ -86,15 +86,15 @@ public void testFieldConstraintDynamicMessage() throws Exception {
}
@Test
- public void testOneofConstraintDynamicMessage() throws Exception {
+ public void testOneofRuleDynamicMessage() throws Exception {
DynamicMessage.Builder messageBuilder =
- createMessageWithUnknownOptions(ExampleOneofConstraints.getDefaultInstance());
+ createMessageWithUnknownOptions(ExampleOneofRules.getDefaultInstance());
Violation expectedViolation =
Violation.newBuilder()
.setField(
FieldPath.newBuilder()
.addElements(FieldPathElement.newBuilder().setFieldName("contact_info")))
- .setConstraintId("required")
+ .setRuleId("required")
.setMessage("exactly one field is required in oneof")
.build();
assertThat(new Validator().validate(messageBuilder.build()).toProto().getViolationsList())
@@ -102,15 +102,15 @@ public void testOneofConstraintDynamicMessage() throws Exception {
}
@Test
- public void testMessageConstraintDynamicMessage() throws Exception {
+ public void testMessageRuleDynamicMessage() throws Exception {
DynamicMessage.Builder messageBuilder =
- createMessageWithUnknownOptions(ExampleMessageConstraints.getDefaultInstance());
+ createMessageWithUnknownOptions(ExampleMessageRules.getDefaultInstance());
messageBuilder.setField(
messageBuilder.getDescriptorForType().findFieldByName("secondary_email"),
"something@somewhere.com");
Violation expectedViolation =
Violation.newBuilder()
- .setConstraintId("secondary_email_depends_on_primary")
+ .setRuleId("secondary_email_depends_on_primary")
.setMessage("cannot set a secondary email without setting a primary one")
.build();
assertThat(new Validator().validate(messageBuilder.build()).toProto().getViolationsList())
@@ -118,18 +118,18 @@ public void testMessageConstraintDynamicMessage() throws Exception {
}
@Test
- public void testRequiredFieldConstraintDynamicMessage() throws Exception {
+ public void testRequiredFieldRuleDynamicMessage() throws Exception {
DynamicMessage.Builder messageBuilder =
- createMessageWithUnknownOptions(ExampleRequiredFieldConstraints.getDefaultInstance());
+ createMessageWithUnknownOptions(ExampleRequiredFieldRules.getDefaultInstance());
messageBuilder.setField(
messageBuilder.getDescriptorForType().findFieldByName("regex_string_field"), "abc123");
assertThat(new Validator().validate(messageBuilder.build()).getViolations()).isEmpty();
}
@Test
- public void testRequiredFieldConstraintDynamicMessageInvalid() throws Exception {
+ public void testRequiredFieldRuleDynamicMessageInvalid() throws Exception {
DynamicMessage.Builder messageBuilder =
- createMessageWithUnknownOptions(ExampleRequiredFieldConstraints.getDefaultInstance());
+ createMessageWithUnknownOptions(ExampleRequiredFieldRules.getDefaultInstance());
messageBuilder.setField(
messageBuilder.getDescriptorForType().findFieldByName("regex_string_field"), "0123456789");
Violation expectedViolation =
@@ -145,13 +145,13 @@ public void testRequiredFieldConstraintDynamicMessageInvalid() throws Exception
FieldPath.newBuilder()
.addElements(
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor()
- .findFieldByNumber(FieldConstraints.STRING_FIELD_NUMBER)))
+ FieldRules.getDescriptor()
+ .findFieldByNumber(FieldRules.STRING_FIELD_NUMBER)))
.addElements(
FieldPathUtils.fieldPathElement(
StringRules.getDescriptor()
.findFieldByNumber(StringRules.PATTERN_FIELD_NUMBER))))
- .setConstraintId("string.pattern")
+ .setRuleId("string.pattern")
.setMessage("value does not match regex pattern `^[a-z0-9]{1,9}$`")
.build();
assertThat(new Validator().validate(messageBuilder.build()).toProto().getViolationsList())
@@ -159,9 +159,9 @@ public void testRequiredFieldConstraintDynamicMessageInvalid() throws Exception
}
@Test
- public void testPredefinedFieldConstraintDynamicMessage() throws Exception {
+ public void testPredefinedFieldRuleDynamicMessage() throws Exception {
DynamicMessage.Builder messageBuilder =
- createMessageWithUnknownOptions(ExamplePredefinedFieldConstraints.getDefaultInstance());
+ createMessageWithUnknownOptions(ExamplePredefinedFieldRules.getDefaultInstance());
messageBuilder.setField(
messageBuilder.getDescriptorForType().findFieldByName("ident_field"), "abc123");
ExtensionRegistry registry = ExtensionRegistry.newInstance();
@@ -174,9 +174,9 @@ public void testPredefinedFieldConstraintDynamicMessage() throws Exception {
}
@Test
- public void testPredefinedFieldConstraintDynamicMessageInvalid() throws Exception {
+ public void testPredefinedFieldRuleDynamicMessageInvalid() throws Exception {
DynamicMessage.Builder messageBuilder =
- createMessageWithUnknownOptions(ExamplePredefinedFieldConstraints.getDefaultInstance());
+ createMessageWithUnknownOptions(ExamplePredefinedFieldRules.getDefaultInstance());
messageBuilder.setField(
messageBuilder.getDescriptorForType().findFieldByName("ident_field"), "0123456789");
Violation expectedViolation =
@@ -190,11 +190,11 @@ public void testPredefinedFieldConstraintDynamicMessageInvalid() throws Exceptio
FieldPath.newBuilder()
.addElements(
FieldPathUtils.fieldPathElement(
- FieldConstraints.getDescriptor()
- .findFieldByNumber(FieldConstraints.STRING_FIELD_NUMBER)))
+ FieldRules.getDescriptor()
+ .findFieldByNumber(FieldRules.STRING_FIELD_NUMBER)))
.addElements(
FieldPathUtils.fieldPathElement(PredefinedProto.isIdent.getDescriptor())))
- .setConstraintId("string.is_ident")
+ .setRuleId("string.is_ident")
.setMessage("invalid identifier")
.build();
ExtensionRegistry registry = ExtensionRegistry.newInstance();
diff --git a/src/test/resources/proto/validationtest/custom_constraints.proto b/src/test/resources/proto/validationtest/custom_rules.proto
similarity index 100%
rename from src/test/resources/proto/validationtest/custom_constraints.proto
rename to src/test/resources/proto/validationtest/custom_rules.proto
diff --git a/src/test/resources/proto/validationtest/predefined.proto b/src/test/resources/proto/validationtest/predefined.proto
index 74caab08..b5d4af70 100644
--- a/src/test/resources/proto/validationtest/predefined.proto
+++ b/src/test/resources/proto/validationtest/predefined.proto
@@ -27,6 +27,6 @@ extend buf.validate.StringRules {
];
}
-message ExamplePredefinedFieldConstraints {
+message ExamplePredefinedFieldRules {
optional string ident_field = 1 [(buf.validate.field).string.(is_ident) = true];
}
diff --git a/src/test/resources/proto/validationtest/required.proto b/src/test/resources/proto/validationtest/required.proto
index c664767e..570694f6 100644
--- a/src/test/resources/proto/validationtest/required.proto
+++ b/src/test/resources/proto/validationtest/required.proto
@@ -18,7 +18,7 @@ package validationtest;
import "buf/validate/validate.proto";
-message ExampleRequiredFieldConstraints {
+message ExampleRequiredFieldRules {
required string regex_string_field = 1 [(buf.validate.field).string.pattern = "^[a-z0-9]{1,9}$"];
optional string unconstrained = 2;
}
diff --git a/src/test/resources/proto/validationtest/validationtest.proto b/src/test/resources/proto/validationtest/validationtest.proto
index 8f68d600..68d5c0d4 100644
--- a/src/test/resources/proto/validationtest/validationtest.proto
+++ b/src/test/resources/proto/validationtest/validationtest.proto
@@ -18,12 +18,12 @@ package validationtest;
import "buf/validate/validate.proto";
-message ExampleFieldConstraints {
+message ExampleFieldRules {
string regex_string_field = 1 [(buf.validate.field).string.pattern = "^[a-z0-9]{1,9}$"];
string unconstrained = 2;
}
-message ExampleOneofConstraints {
+message ExampleOneofRules {
// contact_info is the user's contact information
oneof contact_info {
// required ensures that exactly one field in oneof is set. Without this
@@ -40,7 +40,7 @@ message ExampleOneofConstraints {
}
}
-message ExampleMessageConstraints {
+message ExampleMessageRules {
option (buf.validate.message).cel = {
id: "secondary_email_depends_on_primary",
expression: