diff --git a/gradle.properties b/gradle.properties index a99c6707..2d53922b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Version of buf.build/bufbuild/protovalidate to use. -protovalidate.version = v0.13.1 +protovalidate.version = v0.13.3 # Arguments to the protovalidate-conformance CLI protovalidate.conformance.args = --strict_message --strict_error --expected_failures=expected-failures.yaml diff --git a/src/main/java/build/buf/protovalidate/EvaluatorBuilder.java b/src/main/java/build/buf/protovalidate/EvaluatorBuilder.java index 5e266f93..2e62e062 100644 --- a/src/main/java/build/buf/protovalidate/EvaluatorBuilder.java +++ b/src/main/java/build/buf/protovalidate/EvaluatorBuilder.java @@ -180,7 +180,7 @@ private void buildMessage(Descriptor desc, MessageEvaluator msgEval) processMessageExpressions(descriptor, msgRules, msgEval, defaultInstance); processMessageOneofRules(descriptor, msgRules, msgEval); processOneofRules(descriptor, msgEval); - processFields(descriptor, msgEval); + processFields(descriptor, msgRules, msgEval); } catch (InvalidProtocolBufferException e) { throw new CompilationException( "failed to parse proto definition: " + desc.getFullName(), e); @@ -243,12 +243,17 @@ private void processOneofRules(Descriptor desc, MessageEvaluator msgEval) } } - private void processFields(Descriptor desc, MessageEvaluator msgEval) + private void processFields(Descriptor desc, MessageRules msgRules, MessageEvaluator msgEval) throws CompilationException, InvalidProtocolBufferException { List fields = desc.getFields(); for (FieldDescriptor fieldDescriptor : fields) { FieldDescriptor descriptor = desc.findFieldByName(fieldDescriptor.getName()); FieldRules fieldRules = resolver.resolveFieldRules(descriptor); + if (!fieldRules.hasIgnore() + && msgRules.getOneofList().stream() + .anyMatch(oneof -> oneof.getFieldsList().contains(fieldDescriptor.getName()))) { + fieldRules = fieldRules.toBuilder().setIgnore(Ignore.IGNORE_IF_UNPOPULATED).build(); + } FieldEvaluator fldEval = buildField(descriptor, fieldRules); msgEval.append(fldEval); } diff --git a/src/main/resources/buf/validate/validate.proto b/src/main/resources/buf/validate/validate.proto index a4377c5b..8a0e0b44 100644 --- a/src/main/resources/buf/validate/validate.proto +++ b/src/main/resources/buf/validate/validate.proto @@ -156,6 +156,9 @@ message MessageRules { // silently ignored when unmarshalling, with only the last field being set when // unmarshalling completes. // + // Note that adding a field to a `oneof` will also set the IGNORE_IF_UNPOPULATED on the fields. This means + // only the field that is set will be validated and the unset fields are not validated according to the field rules. + // This behavior can be overridden by setting `ignore` against a field. // // ```proto // message MyMessage {