diff --git a/src/main/java/build/buf/protovalidate/internal/evaluator/EvaluatorBuilder.java b/src/main/java/build/buf/protovalidate/internal/evaluator/EvaluatorBuilder.java index 21f55325..b0b914b1 100644 --- a/src/main/java/build/buf/protovalidate/internal/evaluator/EvaluatorBuilder.java +++ b/src/main/java/build/buf/protovalidate/internal/evaluator/EvaluatorBuilder.java @@ -102,7 +102,7 @@ private Evaluator build(Descriptor desc) throws CompilationException { private void buildMessage(Descriptor desc, MessageEvaluator msgEval) throws CompilationException { try { DynamicMessage defaultInstance = - DynamicMessage.parseFrom(desc, new byte[0], EXTENSION_REGISTRY); + DynamicMessage.newBuilder(desc).mergeFrom(new byte[0], EXTENSION_REGISTRY).buildPartial(); Descriptor descriptor = defaultInstance.getDescriptorForType(); MessageConstraints msgConstraints = resolver.resolveMessageConstraints(descriptor, EXTENSION_REGISTRY); diff --git a/src/test/java/build/buf/protovalidate/ValidatorDynamicMessageTest.java b/src/test/java/build/buf/protovalidate/ValidatorDynamicMessageTest.java index be4131c5..78224066 100644 --- a/src/test/java/build/buf/protovalidate/ValidatorDynamicMessageTest.java +++ b/src/test/java/build/buf/protovalidate/ValidatorDynamicMessageTest.java @@ -20,6 +20,7 @@ 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.google.protobuf.DescriptorProtos; import com.google.protobuf.Descriptors; import com.google.protobuf.DynamicMessage; @@ -86,6 +87,31 @@ public void testMessageConstraintDynamicMessage() throws Exception { .containsExactly(expectedViolation); } + @Test + public void testRequiredFieldConstraintDynamicMessage() throws Exception { + DynamicMessage.Builder messageBuilder = + createMessageWithUnknownOptions(ExampleRequiredFieldConstraints.getDefaultInstance()); + messageBuilder.setField( + messageBuilder.getDescriptorForType().findFieldByName("regex_string_field"), "abc123"); + assertThat(new Validator().validate(messageBuilder.build()).getViolations()).isEmpty(); + } + + @Test + public void testRequiredFieldConstraintDynamicMessageInvalid() throws Exception { + DynamicMessage.Builder messageBuilder = + createMessageWithUnknownOptions(ExampleRequiredFieldConstraints.getDefaultInstance()); + messageBuilder.setField( + messageBuilder.getDescriptorForType().findFieldByName("regex_string_field"), "0123456789"); + Violation expectedViolation = + Violation.newBuilder() + .setConstraintId("string.pattern") + .setFieldPath("regex_string_field") + .setMessage("value does not match regex pattern `^[a-z0-9]{1,9}$`") + .build(); + assertThat(new Validator().validate(messageBuilder.build()).getViolations()) + .containsExactly(expectedViolation); + } + private static void gatherDependencies( Descriptors.FileDescriptor fd, Set dependencies) { dependencies.add(fd.toProto()); diff --git a/src/test/resources/proto/validationtest/required.proto b/src/test/resources/proto/validationtest/required.proto new file mode 100644 index 00000000..67376c7b --- /dev/null +++ b/src/test/resources/proto/validationtest/required.proto @@ -0,0 +1,24 @@ +// Copyright 2023 Buf Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto2"; + +package validationtest; + +import "buf/validate/validate.proto"; + +message ExampleRequiredFieldConstraints { + required string regex_string_field = 1 [(buf.validate.field).string.pattern = "^[a-z0-9]{1,9}$"]; + optional string unconstrained = 2; +}