From 0ca50bd0a2d867bbe49f08134bedcf39a76bf521 Mon Sep 17 00:00:00 2001 From: Sri Krishna Date: Fri, 13 Jun 2025 10:57:22 +0530 Subject: [PATCH 1/3] Add implicit `IGNORE_IF_UNPOPULATED` for `MessageOneofRule` fields Signed-off-by: Sri Krishna --- gradle.properties | 2 +- .../java/build/buf/protovalidate/EvaluatorBuilder.java | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index a99c6707..a1c6310b 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.2 # 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); } From 6029a8c2d1627d49a810b5a4eb7a1b7543dcecc3 Mon Sep 17 00:00:00 2001 From: Sri Krishna Date: Fri, 13 Jun 2025 12:31:31 +0530 Subject: [PATCH 2/3] gen Signed-off-by: Sri Krishna --- src/main/resources/buf/validate/validate.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/resources/buf/validate/validate.proto b/src/main/resources/buf/validate/validate.proto index a4377c5b..86915279 100644 --- a/src/main/resources/buf/validate/validate.proto +++ b/src/main/resources/buf/validate/validate.proto @@ -156,6 +156,8 @@ 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 os set will be validated and the unset fields are not validated according to the field rules. // // ```proto // message MyMessage { From deea1d0bc884548b5773cd3e83f6789a3f5557cd Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Fri, 13 Jun 2025 13:05:06 +0200 Subject: [PATCH 3/3] Update to protovalidate v0.13.3 --- gradle.properties | 2 +- src/main/resources/buf/validate/validate.proto | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index a1c6310b..2d53922b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Version of buf.build/bufbuild/protovalidate to use. -protovalidate.version = v0.13.2 +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/resources/buf/validate/validate.proto b/src/main/resources/buf/validate/validate.proto index 86915279..8a0e0b44 100644 --- a/src/main/resources/buf/validate/validate.proto +++ b/src/main/resources/buf/validate/validate.proto @@ -157,7 +157,8 @@ message MessageRules { // 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 os set will be validated and the unset fields are not validated according to the field rules. + // 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 {