Skip to content

Commit 7345e69

Browse files
Implement predefined field constraints (#178)
- Adds the ability to specify an `ExtensionRegistry` _and_ a `TypeRegistry` for resolving protobuf messages. Ordinarily, only a `TypeRegistry` would necessarily be needed. However, we need to be able to resolve extensions defined in file descriptor sets we don't control, which means we need to be able to reparse _to and from_ the user's descriptors in the worst case: _to_ the user's descriptors to get the extended rule message (whose message type descriptors may have a different hashcode and thus may not resolve using just an `ExtensionRegistry` alone) and back _from_ the user's descriptors in order to parse the `priv`/`shared` field. - Refactors some of the code around reparsing and extensions in general: - Reparsing options for protovalidate built-ins will always use a static extension registry. - Adds the `rule` variable. - Some refactoring is done around the individual rule compilation, since the code was getting a bit unwieldy. - Updates the conformance runner to generate an `ExtensionRegistry` and a `TypeRegistry`. This enables the conformance runner to pass both the old conformance test suite and the new one, regardless of whether the proto descriptors match up. TODO: - [x] Update to new version of protovalidate protos when they are merged. This will depend on bufbuild/protovalidate#246.
1 parent 3e92af1 commit 7345e69

File tree

304 files changed

+73825
-6680
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

304 files changed

+73825
-6680
lines changed

conformance/src/main/java/build/buf/protovalidate/conformance/FileDescriptorUtil.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
import com.google.protobuf.DescriptorProtos;
1818
import com.google.protobuf.Descriptors;
19+
import com.google.protobuf.DynamicMessage;
20+
import com.google.protobuf.ExtensionRegistry;
21+
import com.google.protobuf.TypeRegistry;
1922
import java.util.ArrayList;
2023
import java.util.HashMap;
2124
import java.util.List;
@@ -70,4 +73,50 @@ static Map<String, Descriptors.FileDescriptor> parseFileDescriptors(
7073
}
7174
return fileDescriptorMap;
7275
}
76+
77+
static TypeRegistry createTypeRegistry(
78+
Iterable<? extends Descriptors.FileDescriptor> fileDescriptors) {
79+
TypeRegistry.Builder registryBuilder = TypeRegistry.newBuilder();
80+
for (Descriptors.FileDescriptor fileDescriptor : fileDescriptors) {
81+
registryBuilder.add(fileDescriptor.getMessageTypes());
82+
}
83+
return registryBuilder.build();
84+
}
85+
86+
static ExtensionRegistry createExtensionRegistry(
87+
Iterable<? extends Descriptors.FileDescriptor> fileDescriptors) {
88+
ExtensionRegistry registry = ExtensionRegistry.newInstance();
89+
for (Descriptors.FileDescriptor fileDescriptor : fileDescriptors) {
90+
registerFileExtensions(registry, fileDescriptor);
91+
}
92+
return registry;
93+
}
94+
95+
private static void registerFileExtensions(
96+
ExtensionRegistry registry, Descriptors.FileDescriptor fileDescriptor) {
97+
registerExtensions(registry, fileDescriptor.getExtensions());
98+
for (Descriptors.Descriptor descriptor : fileDescriptor.getMessageTypes()) {
99+
registerMessageExtensions(registry, descriptor);
100+
}
101+
}
102+
103+
private static void registerMessageExtensions(
104+
ExtensionRegistry registry, Descriptors.Descriptor descriptor) {
105+
registerExtensions(registry, descriptor.getExtensions());
106+
for (Descriptors.Descriptor nestedDescriptor : descriptor.getNestedTypes()) {
107+
registerMessageExtensions(registry, nestedDescriptor);
108+
}
109+
}
110+
111+
private static void registerExtensions(
112+
ExtensionRegistry registry, List<Descriptors.FieldDescriptor> extensions) {
113+
for (Descriptors.FieldDescriptor fieldDescriptor : extensions) {
114+
if (fieldDescriptor.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
115+
registry.add(
116+
fieldDescriptor, DynamicMessage.getDefaultInstance(fieldDescriptor.getMessageType()));
117+
} else {
118+
registry.add(fieldDescriptor);
119+
}
120+
}
121+
}
73122
}

conformance/src/main/java/build/buf/protovalidate/conformance/Main.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.google.protobuf.DynamicMessage;
3434
import com.google.protobuf.ExtensionRegistry;
3535
import com.google.protobuf.InvalidProtocolBufferException;
36+
import com.google.protobuf.TypeRegistry;
3637
import java.util.HashMap;
3738
import java.util.List;
3839
import java.util.Map;
@@ -57,7 +58,17 @@ static TestConformanceResponse testConformance(TestConformanceRequest request) {
5758
try {
5859
Map<String, Descriptors.Descriptor> descriptorMap =
5960
FileDescriptorUtil.parse(request.getFdset());
60-
Validator validator = new Validator(Config.newBuilder().build());
61+
Map<String, Descriptors.FileDescriptor> fileDescriptorMap =
62+
FileDescriptorUtil.parseFileDescriptors(request.getFdset());
63+
TypeRegistry typeRegistry = FileDescriptorUtil.createTypeRegistry(fileDescriptorMap.values());
64+
ExtensionRegistry extensionRegistry =
65+
FileDescriptorUtil.createExtensionRegistry(fileDescriptorMap.values());
66+
Validator validator =
67+
new Validator(
68+
Config.newBuilder()
69+
.setTypeRegistry(typeRegistry)
70+
.setExtensionRegistry(extensionRegistry)
71+
.build());
6172
TestConformanceResponse.Builder responseBuilder = TestConformanceResponse.newBuilder();
6273
Map<String, TestResult> resultsMap = new HashMap<>();
6374
for (Map.Entry<String, Any> entry : request.getCasesMap().entrySet()) {

0 commit comments

Comments
 (0)