下面列出了com.google.protobuf.DescriptorProtos#FileDescriptorProto ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static DescriptorProtos.FileDescriptorProto getFileDescProtoForMsgType(
String packageName,
String messageType,
DescriptorProtos.FileDescriptorSet set
) {
DescriptorProtos.FileDescriptorProto file = null;
for (DescriptorProtos.FileDescriptorProto fileDescriptorProto : set.getFileList()) {
if (!packageMatch(fileDescriptorProto, packageName)) {
continue;
}
file = containsMessageType(fileDescriptorProto, messageType);
if (file != null) {
break;
}
}
return file;
}
private List<ServiceContext> findServices(List<DescriptorProtos.FileDescriptorProto> protos, ProtoTypeMap typeMap) {
List<ServiceContext> contexts = new ArrayList<>();
protos.forEach(fileProto -> {
for (int serviceNumber = 0; serviceNumber < fileProto.getServiceCount(); serviceNumber++) {
ServiceContext serviceContext = buildServiceContext(
fileProto.getService(serviceNumber),
typeMap,
fileProto.getSourceCodeInfo().getLocationList(),
serviceNumber);
serviceContext.protoName = fileProto.getName();
serviceContext.packageName = extractPackageName(fileProto);
contexts.add(serviceContext);
}
});
return contexts;
}
/**
* Creates a default union descriptor for the given file descriptor if missing.
*
* <p>
* If the given file descriptor is missing a union message, this method will add one before updating the meta-data.
* The generated union descriptor is constructed by adding any non-{@code NESTED} types in the file descriptor to the
* union descriptor from the currently stored meta-data. A new field is not added if a field of the given type already
* exists, and the order of any existing fields is preserved. Note that types are identified by name, so renaming
* top-level message types may result in validation errors when trying to update the record descriptor.
* </p>
*
* @param fileDescriptor the file descriptor to create a union for
* @param baseUnionDescriptor the base union descriptor
* @return the builder for the union
*/
@Nonnull
public static Descriptors.FileDescriptor addDefaultUnionIfMissing(@Nonnull Descriptors.FileDescriptor fileDescriptor, @Nonnull Descriptors.Descriptor baseUnionDescriptor) {
if (MetaDataProtoEditor.hasUnion(fileDescriptor)) {
return fileDescriptor;
}
DescriptorProtos.FileDescriptorProto fileDescriptorProto = fileDescriptor.toProto();
DescriptorProtos.FileDescriptorProto.Builder fileBuilder = fileDescriptorProto.toBuilder();
DescriptorProtos.DescriptorProto.Builder unionDescriptorBuilder = createSyntheticUnion(fileDescriptor, baseUnionDescriptor);
for (DescriptorProtos.DescriptorProto.Builder messageType : fileBuilder.getMessageTypeBuilderList()) {
RecordMetaDataOptionsProto.RecordTypeOptions.Usage messageTypeUsage = getMessageTypeUsage(messageType);
if (messageTypeUsage != RecordMetaDataOptionsProto.RecordTypeOptions.Usage.NESTED
&& !hasField(fileBuilder, unionDescriptorBuilder, messageType)) {
addFieldToUnion(unionDescriptorBuilder, fileBuilder, messageType);
}
}
fileBuilder.addMessageType(unionDescriptorBuilder);
try {
return Descriptors.FileDescriptor.buildFrom(fileBuilder.build(), fileDescriptor.getDependencies().toArray(new Descriptors.FileDescriptor[0]));
} catch (Descriptors.DescriptorValidationException e) {
throw new MetaDataException("Failed to add a default union", e);
}
}
/**
* Deserializes the meta-data proto into the builder.
* @param metaDataProto the proto of the {@link RecordMetaData}
* @param processExtensionOptions whether to add primary keys and indexes based on extensions in the protobuf
* @return this builder
*/
@Nonnull
public RecordMetaDataBuilder setRecords(@Nonnull RecordMetaDataProto.MetaData metaDataProto,
boolean processExtensionOptions) {
if (recordsDescriptor != null) {
throw new MetaDataException("Records already set.");
}
// Build the recordDescriptor by de-serializing the metaData proto
Map<String, DescriptorProtos.FileDescriptorProto> protoDependencies = new TreeMap<>();
for (DescriptorProtos.FileDescriptorProto dependency : metaDataProto.getDependenciesList()) {
protoDependencies.put(dependency.getName(), dependency);
}
Map<String, Descriptors.FileDescriptor> generatedDependencies = initGeneratedDependencies(protoDependencies);
Descriptors.FileDescriptor[] dependencies = getDependencies(metaDataProto.getRecords(), generatedDependencies, protoDependencies);
loadFromProto(metaDataProto, dependencies, processExtensionOptions);
return this;
}
@Override
public List<PluginProtos.CodeGeneratorResponse.File> generateFiles(PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
final ProtoTypeMap protoTypeMap = ProtoTypeMap.of(request.getProtoFileList());
List<PluginProtos.CodeGeneratorResponse.File> files = new ArrayList<>();
for (DescriptorProtos.FileDescriptorProto protoFile : request.getProtoFileList()) {
if (request.getFileToGenerateList().contains(protoFile.getName())) {
for (ServiceContext ctx : extractContext(protoTypeMap, protoFile)) {
files.add(buildFile(ctx));
}
}
}
return files;
}
/**
* Loads a Protobuf file descriptor set into an ubermap of file descriptors.
*
* @param set FileDescriptorSet
* @param dependenciesMap FileDescriptor dependency map
* @param fileDescriptorMap The populated map of FileDescriptors
* @throws StageException
*/
public static void getAllFileDescriptors(
DescriptorProtos.FileDescriptorSet set,
Map<String, Set<Descriptors.FileDescriptor>> dependenciesMap,
Map<String, Descriptors.FileDescriptor> fileDescriptorMap
) throws StageException {
List<DescriptorProtos.FileDescriptorProto> fileList = set.getFileList();
try {
for (DescriptorProtos.FileDescriptorProto fdp : fileList) {
if (!fileDescriptorMap.containsKey(fdp.getName())) {
Set<Descriptors.FileDescriptor> dependencies = dependenciesMap.get(fdp.getName());
if (dependencies == null) {
dependencies = new LinkedHashSet<>();
dependenciesMap.put(fdp.getName(), dependencies);
dependencies.addAll(getDependencies(dependenciesMap, fileDescriptorMap, fdp, set));
}
Descriptors.FileDescriptor fileDescriptor = Descriptors.FileDescriptor.buildFrom(
fdp,
dependencies.toArray(new Descriptors.FileDescriptor[dependencies.size()])
);
fileDescriptorMap.put(fdp.getName(), fileDescriptor);
}
}
} catch (Descriptors.DescriptorValidationException e) {
throw new StageException(Errors.PROTOBUF_07, e.getDescription(), e);
}
}
public Builder mergeBinary(Collection<ByteString> updateBytes)
throws InvalidProtocolBufferException {
Collection<DescriptorProtos.FileDescriptorProto> updateProtos = new ArrayList<>();
for (ByteString bs : updateBytes) {
updateProtos.add(DescriptorProtos.FileDescriptorProto.parseFrom(bs));
}
return merge(updateProtos);
}
private void crosswire() {
HashMap<String, DescriptorProtos.FileDescriptorProto> map = new HashMap<>();
fileDescriptorSet.getFileList().stream()
.filter(fdp -> !fdp.getName().startsWith("google/protobuf"))
.forEach(fdp -> map.put(fdp.getName(), fdp));
ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
Map<String, Descriptors.FileDescriptor> outMap = new HashMap<>();
map.forEach(
(fileName, proto) -> convertToFileDescriptorMap(fileName, map, outMap, extensionRegistry));
fileDescriptorMap = outMap;
indexOptionsByNumber(fileDescriptorMap.values());
indexDescriptorByName();
}
@Test
public void addField() throws Exception {
ProtoDomain dRef = ProtoDomain.builder().add(FILE_V1).build();
DescriptorProtos.FileDescriptorProto fd =
FILE_V1
.toBuilder()
.setMessageType(
0,
FILE_V1
.getMessageType(0)
.toBuilder()
.addField(
DescriptorProtos.FieldDescriptorProto.newBuilder()
.setName("fourth_field")
.setNumber(4)
.setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_STRING)))
.build();
ProtoDomain dNew = ProtoDomain.builder().add(fd).build();
Report report = diff(dRef, dNew);
MessageResult result = report.getMessageResultsMap().get("package.v1.Message1");
Assert.assertEquals(ChangeType.UNCHANGED, result.getChange().getChangeType());
Assert.assertEquals(ChangeType.ADDITION, result.getFieldResults(0).getChange().getChangeType());
Assert.assertEquals(4, result.getFieldResults(0).getNumber());
Assert.assertEquals("fourth_field", result.getFieldResults(0).getName());
Assert.assertEquals("", result.getFieldResults(0).getChange().getFromName());
Assert.assertEquals("fourth_field", result.getFieldResults(0).getChange().getToName());
}
@Nonnull
private static Map<String, Descriptors.FileDescriptor> initGeneratedDependencies(@Nonnull Map<String, DescriptorProtos.FileDescriptorProto> protoDependencies) {
Map<String, Descriptors.FileDescriptor> generatedDependencies = new TreeMap<>();
if (!protoDependencies.containsKey(TupleFieldsProto.getDescriptor().getName())) {
generatedDependencies.put(TupleFieldsProto.getDescriptor().getName(), TupleFieldsProto.getDescriptor());
}
if (!protoDependencies.containsKey(RecordMetaDataOptionsProto.getDescriptor().getName())) {
generatedDependencies.put(RecordMetaDataOptionsProto.getDescriptor().getName(), RecordMetaDataOptionsProto.getDescriptor());
}
if (!protoDependencies.containsKey(RecordMetaDataProto.getDescriptor().getName())) {
generatedDependencies.put(RecordMetaDataProto.getDescriptor().getName(), RecordMetaDataProto.getDescriptor());
}
return generatedDependencies;
}
@Test
public void changeFieldType() throws Exception {
ProtoDomain dRef = ProtoDomain.builder().add(FILE_V1).build();
DescriptorProtos.FileDescriptorProto fd =
FILE_V1
.toBuilder()
.setMessageType(
0,
FILE_V1
.getMessageType(0)
.toBuilder()
.setField(
1,
DescriptorProtos.FieldDescriptorProto.newBuilder()
.setNumber(2)
.setName("seconde_nullable_field")
.setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_MESSAGE)
.setTypeName("google.protobuf.Int64Value")
.build())
.build())
.build();
ProtoDomain dNew = ProtoDomain.builder().add(fd).build();
Report report = diff(dRef, dNew);
MessageResult result = report.getMessageResultsMap().get("package.v1.Message1");
Assert.assertEquals(ChangeType.UNCHANGED, result.getChange().getChangeType());
Assert.assertEquals(ChangeType.CHANGED, result.getFieldResults(0).getChange().getChangeType());
Assert.assertEquals(
"google.protobuf.StringValue", result.getFieldResults(0).getChange().getFromTypeName());
Assert.assertEquals(
"google.protobuf.Int64Value", result.getFieldResults(0).getChange().getToTypeName());
}
@Test
public void renameMethod() throws Exception {
ProtoDomain dRef = ProtoDomain.builder().add(FILE_V1).build();
DescriptorProtos.FileDescriptorProto fd =
FILE_V1
.toBuilder()
.setService(
0,
FILE_V1
.getService(0)
.toBuilder()
.setMethod(
0, FILE_V1.getService(0).getMethod(0).toBuilder().setName("MethodX")))
.build();
ProtoDomain dNew = ProtoDomain.builder().add(fd).build();
Report report = diff(dRef, dNew);
ServiceResult result = report.getServiceResultsMap().get("package.v1.Service1");
Assert.assertEquals(ChangeType.UNCHANGED, result.getChange().getChangeType());
Assert.assertEquals(
ChangeType.ADDITION, result.getMethodResults(0).getChange().getChangeType());
Assert.assertEquals("MethodX", result.getMethodResults(0).getName());
Assert.assertEquals("", result.getMethodResults(0).getChange().getFromName());
Assert.assertEquals("MethodX", result.getMethodResults(0).getChange().getToName());
Assert.assertEquals(ChangeType.REMOVAL, result.getMethodResults(1).getChange().getChangeType());
Assert.assertEquals("Method1", result.getMethodResults(1).getName());
Assert.assertEquals("Method1", result.getMethodResults(1).getChange().getFromName());
Assert.assertEquals("", result.getMethodResults(1).getChange().getToName());
}
private static List<DescriptorProtos.DescriptorProto> getAllMessageTypesInDescriptorProto(
DescriptorProtos.FileDescriptorProto fileDescriptorProto
) {
Queue<DescriptorProtos.DescriptorProto> queue = new LinkedList<>();
queue.addAll(fileDescriptorProto.getMessageTypeList());
List<DescriptorProtos.DescriptorProto> result = new ArrayList<>();
while (!queue.isEmpty()) {
DescriptorProtos.DescriptorProto descriptorProto = queue.poll();
queue.addAll(descriptorProto.getNestedTypeList());
result.add(descriptorProto);
}
return result;
}
private String extractPackageName(DescriptorProtos.FileDescriptorProto proto) {
DescriptorProtos.FileOptions options = proto.getOptions();
if (options != null) {
String javaPackage = options.getJavaPackage();
if (!Strings.isNullOrEmpty(javaPackage)) {
return javaPackage;
}
}
return Strings.nullToEmpty(proto.getPackage());
}
@Test
public void testSingleLong() throws IOException, StatusRuntimeException {
String node = getJsonNode("testSingleLong");
final DescriptorProtos.FileDescriptorProto fileDescriptorProto =
TestSingleLong.getDescriptor().getFile().toProto();
ProtoDomain protoDomain = ProtoDomain.builder().add(fileDescriptorProto).build();
String avroSchema =
ProtoToAvroSchema.convert(
protoDomain, String.format("%s.TestSingleLong", fileDescriptorProto.getPackage()));
Assert.assertEquals(node, avroSchema);
}
@BeforeClass
public static void buildProtoTypeMap() throws IOException {
// Dump file generated during the maven generate-test-sources phase
final String dumpPath = "target/generated-test-sources/protobuf/dump/descriptor_dump";
byte[] generatorRequestBytes = ByteStreams.toByteArray(new FileInputStream(new File(dumpPath)));
PluginProtos.CodeGeneratorRequest request = PluginProtos.CodeGeneratorRequest.parseFrom(
generatorRequestBytes, ExtensionRegistry.newInstance());
List<DescriptorProtos.FileDescriptorProto> fileProtos = request.getProtoFileList();
protoTypeMap = ProtoTypeMap.of(fileProtos);
}
private static Map<String, DescriptorProtos.FileDescriptorProto> extractProtoMap(
DescriptorProtos.FileDescriptorSet fileDescriptorSet) {
HashMap<String, DescriptorProtos.FileDescriptorProto> map = new HashMap<>();
fileDescriptorSet.getFileList().forEach(fdp -> map.put(fdp.getName(), fdp));
return map;
}
static Map<String, Descriptors.FileDescriptor> convertFileDescriptorSet(
DescriptorProtos.FileDescriptorSet fileDescriptorSet) {
Map<String, DescriptorProtos.FileDescriptorProto> inMap = extractProtoMap(fileDescriptorSet);
return convertToFileDescriptorMap(inMap);
}
private void assertEnum(DescriptorProtos.FileDescriptorProto proto, ProtoDomain domain)
throws Descriptors.DescriptorValidationException {
testOutput(
proto,
domain,
"syntax = \"proto3\";\n"
+ "\n"
+ "import \"test/v1/option.proto\";\n"
+ "\n"
+ "\n"
+ "\n"
+ "enum WriteEnum {\n"
+ "\toption deprecated = true;\n"
+ "\toption (test.v1.enum_option) = {\n"
+ "\t\tsingle_string: \"testString\"\n"
+ "\t\trepeated_string: [\"test1\",\"test2\"]\n"
+ "\t\tsingle_int32: 2\n"
+ "\t\trepeated_int32: [3,4]\n"
+ "\t\tsingle_int64: 10\n"
+ "\t\tsingle_enum: ENUM2\n"
+ "\t\tsingle_message: {\n"
+ "\t\t\tsingle_string: \"minimal\"\n"
+ "\t\t\trepeated_string: [\"test1\",\"test2\"]\n"
+ "\t\t\tsingle_int32: 2\n"
+ "\t\t\trepeated_int32: [3]\n"
+ "\t\t\tsingle_enum: ENUM2\n"
+ "\t\t}\n"
+ "\t};\n"
+ "\toption (test.v1.enum_option_1) = 12;\n"
+ "\toption (test.v1.enum_option_2) = \"String\";\n"
+ "\toption (test.v1.enum_option_n) = \"Value I\";\n"
+ "\toption (test.v1.enum_option_n) = \"Value II\";\n"
+ "\toption (test.v1.enum_option_n) = \"Value III\";\n"
+ "\n"
+ "\tWRITE_ENUM_UNSET = 0 [\n"
+ "\t\tdeprecated = true,\n"
+ "\t\t(test.v1.enum_value_option) = {\n"
+ "\t\t\tsingle_string: \"testString\"\n"
+ "\t\t\trepeated_string: [\"test1\",\"test2\"]\n"
+ "\t\t\tsingle_int32: 2\n"
+ "\t\t\trepeated_int32: [3,4]\n"
+ "\t\t\tsingle_int64: 10\n"
+ "\t\t\tsingle_enum: ENUM2\n"
+ "\t\t\tsingle_message: {\n"
+ "\t\t\t\tsingle_string: \"minimal\"\n"
+ "\t\t\t\trepeated_string: [\"test1\",\"test2\"]\n"
+ "\t\t\t\tsingle_int32: 2\n"
+ "\t\t\t\trepeated_int32: [3]\n"
+ "\t\t\t\tsingle_enum: ENUM2\n"
+ "\t\t\t}\n"
+ "\t\t},\n"
+ "\t\t(test.v1.enum_value_option_1) = 12,\n"
+ "\t\t(test.v1.enum_value_option_2) = \"String\",\n"
+ "\t\t(test.v1.enum_value_option_n) = \"Value I\",\n"
+ "\t\t(test.v1.enum_value_option_n) = \"Value II\",\n"
+ "\t\t(test.v1.enum_value_option_n) = \"Value III\"\n"
+ "\t];\n"
+ "}\n");
}
/**
* Generate OpenAPI from protobuf.
*
* @param protoPath protobuf file path
* @param descriptorPath descriptor file path
* @return {@link OpenAPI} list of OpenAPIs
*/
public ArrayList<OpenAPI> generateOpenAPI(String protoPath, String descriptorPath) {
DescriptorProtos.FileDescriptorProto descriptor =
generateRootFileDescriptor(protoPath, descriptorPath);
return generateOpenAPIFromProto(descriptor, protoPath);
}