Skip to content

Commit

Permalink
Implement predefined field constraints (#178)
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
jchadwick-buf authored Sep 26, 2024
1 parent 3e92af1 commit 7345e69
Show file tree
Hide file tree
Showing 304 changed files with 73,825 additions and 6,680 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

import com.google.protobuf.DescriptorProtos;
import com.google.protobuf.Descriptors;
import com.google.protobuf.DynamicMessage;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.TypeRegistry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -70,4 +73,50 @@ static Map<String, Descriptors.FileDescriptor> parseFileDescriptors(
}
return fileDescriptorMap;
}

static TypeRegistry createTypeRegistry(
Iterable<? extends Descriptors.FileDescriptor> fileDescriptors) {
TypeRegistry.Builder registryBuilder = TypeRegistry.newBuilder();
for (Descriptors.FileDescriptor fileDescriptor : fileDescriptors) {
registryBuilder.add(fileDescriptor.getMessageTypes());
}
return registryBuilder.build();
}

static ExtensionRegistry createExtensionRegistry(
Iterable<? extends Descriptors.FileDescriptor> fileDescriptors) {
ExtensionRegistry registry = ExtensionRegistry.newInstance();
for (Descriptors.FileDescriptor fileDescriptor : fileDescriptors) {
registerFileExtensions(registry, fileDescriptor);
}
return registry;
}

private static void registerFileExtensions(
ExtensionRegistry registry, Descriptors.FileDescriptor fileDescriptor) {
registerExtensions(registry, fileDescriptor.getExtensions());
for (Descriptors.Descriptor descriptor : fileDescriptor.getMessageTypes()) {
registerMessageExtensions(registry, descriptor);
}
}

private static void registerMessageExtensions(
ExtensionRegistry registry, Descriptors.Descriptor descriptor) {
registerExtensions(registry, descriptor.getExtensions());
for (Descriptors.Descriptor nestedDescriptor : descriptor.getNestedTypes()) {
registerMessageExtensions(registry, nestedDescriptor);
}
}

private static void registerExtensions(
ExtensionRegistry registry, List<Descriptors.FieldDescriptor> extensions) {
for (Descriptors.FieldDescriptor fieldDescriptor : extensions) {
if (fieldDescriptor.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
registry.add(
fieldDescriptor, DynamicMessage.getDefaultInstance(fieldDescriptor.getMessageType()));
} else {
registry.add(fieldDescriptor);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.google.protobuf.DynamicMessage;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.TypeRegistry;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -57,7 +58,17 @@ static TestConformanceResponse testConformance(TestConformanceRequest request) {
try {
Map<String, Descriptors.Descriptor> descriptorMap =
FileDescriptorUtil.parse(request.getFdset());
Validator validator = new Validator(Config.newBuilder().build());
Map<String, Descriptors.FileDescriptor> fileDescriptorMap =
FileDescriptorUtil.parseFileDescriptors(request.getFdset());
TypeRegistry typeRegistry = FileDescriptorUtil.createTypeRegistry(fileDescriptorMap.values());
ExtensionRegistry extensionRegistry =
FileDescriptorUtil.createExtensionRegistry(fileDescriptorMap.values());
Validator validator =
new Validator(
Config.newBuilder()
.setTypeRegistry(typeRegistry)
.setExtensionRegistry(extensionRegistry)
.build());
TestConformanceResponse.Builder responseBuilder = TestConformanceResponse.newBuilder();
Map<String, TestResult> resultsMap = new HashMap<>();
for (Map.Entry<String, Any> entry : request.getCasesMap().entrySet()) {
Expand Down
Loading

0 comments on commit 7345e69

Please sign in to comment.