Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Version of buf.build/bufbuild/protovalidate to use.
protovalidate.version = v0.13.3
protovalidate.version = v0.14.0

# Arguments to the protovalidate-conformance CLI
protovalidate.conformance.args = --strict_message --strict_error --expected_failures=expected-failures.yaml
Expand Down
20 changes: 3 additions & 17 deletions src/main/java/build/buf/protovalidate/EvaluatorBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,6 @@ private void buildMessage(Descriptor desc, MessageEvaluator msgEval)
DynamicMessage defaultInstance = DynamicMessage.newBuilder(desc).buildPartial();
Descriptor descriptor = defaultInstance.getDescriptorForType();
MessageRules msgRules = resolver.resolveMessageRules(descriptor);
if (msgRules.getDisabled()) {
return;
}
processMessageExpressions(descriptor, msgRules, msgEval, defaultInstance);
processMessageOneofRules(descriptor, msgRules, msgEval);
processOneofRules(descriptor, msgEval);
Expand Down Expand Up @@ -252,7 +249,7 @@ private void processFields(Descriptor desc, MessageRules msgRules, MessageEvalua
if (!fieldRules.hasIgnore()
&& msgRules.getOneofList().stream()
.anyMatch(oneof -> oneof.getFieldsList().contains(fieldDescriptor.getName()))) {
fieldRules = fieldRules.toBuilder().setIgnore(Ignore.IGNORE_IF_UNPOPULATED).build();
fieldRules = fieldRules.toBuilder().setIgnore(Ignore.IGNORE_IF_ZERO_VALUE).build();
}
FieldEvaluator fldEval = buildField(descriptor, fieldRules);
msgEval.append(fldEval);
Expand All @@ -262,30 +259,19 @@ private void processFields(Descriptor desc, MessageRules msgRules, MessageEvalua
private FieldEvaluator buildField(FieldDescriptor fieldDescriptor, FieldRules fieldRules)
throws CompilationException {
ValueEvaluator valueEvaluatorEval = new ValueEvaluator(fieldDescriptor, null);
boolean ignoreDefault = fieldDescriptor.hasPresence() && shouldIgnoreDefault(fieldRules);
Object zero = null;
if (ignoreDefault) {
zero = zeroValue(fieldDescriptor, false);
}
FieldEvaluator fieldEvaluator =
new FieldEvaluator(
valueEvaluatorEval,
fieldDescriptor,
fieldRules.getRequired(),
fieldDescriptor.hasPresence(),
fieldRules.getIgnore(),
zero);
fieldRules.getIgnore());
buildValue(fieldDescriptor, fieldRules, fieldEvaluator.valueEvaluator);
return fieldEvaluator;
}

private static boolean shouldIgnoreEmpty(FieldRules rules) {
return rules.getIgnore() == Ignore.IGNORE_IF_UNPOPULATED
|| rules.getIgnore() == Ignore.IGNORE_IF_DEFAULT_VALUE;
}

private static boolean shouldIgnoreDefault(FieldRules rules) {
return rules.getIgnore() == Ignore.IGNORE_IF_DEFAULT_VALUE;
return rules.getIgnore() == Ignore.IGNORE_IF_ZERO_VALUE;
}

private void buildValue(
Expand Down
28 changes: 4 additions & 24 deletions src/main/java/build/buf/protovalidate/FieldEvaluator.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
import com.google.protobuf.Message;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import org.jspecify.annotations.Nullable;

/** Performs validation on a single message field, defined by its descriptor. */
final class FieldEvaluator implements Evaluator {
Expand Down Expand Up @@ -52,23 +50,19 @@ final class FieldEvaluator implements Evaluator {
/** Whether the field distinguishes between unpopulated and default values. */
private final boolean hasPresence;

@Nullable private final Object zero;

/** Constructs a new {@link FieldEvaluator} */
FieldEvaluator(
ValueEvaluator valueEvaluator,
FieldDescriptor descriptor,
boolean required,
boolean hasPresence,
Ignore ignore,
@Nullable Object zero) {
Ignore ignore) {
this.helper = new RuleViolationHelper(valueEvaluator);
this.valueEvaluator = valueEvaluator;
this.descriptor = descriptor;
this.required = required;
this.hasPresence = hasPresence;
this.ignore = ignore;
this.zero = zero;
}

@Override
Expand All @@ -92,17 +86,7 @@ private boolean shouldIgnoreAlways() {
* set.
*/
private boolean shouldIgnoreEmpty() {
return this.hasPresence
|| this.ignore == Ignore.IGNORE_IF_UNPOPULATED
|| this.ignore == Ignore.IGNORE_IF_DEFAULT_VALUE;
}

/**
* Returns whether a field should skip validation on its zero value, including for fields which
* have field presence and are set to the zero value.
*/
private boolean shouldIgnoreDefault() {
return this.hasPresence && this.ignore == Ignore.IGNORE_IF_DEFAULT_VALUE;
return this.hasPresence || this.ignore == Ignore.IGNORE_IF_ZERO_VALUE;
}

@Override
Expand Down Expand Up @@ -134,11 +118,7 @@ public List<RuleViolation.Builder> evaluate(Value val, boolean failFast)
if (this.shouldIgnoreEmpty() && !hasField) {
return RuleViolation.NO_VIOLATIONS;
}
Object fieldValue = message.getField(descriptor);
if (this.shouldIgnoreDefault()
&& Objects.equals(zero, ProtoAdapter.toCel(descriptor, fieldValue))) {
return RuleViolation.NO_VIOLATIONS;
}
return valueEvaluator.evaluate(new ObjectValue(descriptor, fieldValue), failFast);
return valueEvaluator.evaluate(
new ObjectValue(descriptor, message.getField(descriptor)), failFast);
}
}
Loading