/** * Generates a protobuf descriptor instance from a FileDescriptor set. * * @param set set of file descriptors * @param fileDescriptorMap map of message types to file descriptors * @param descriptorFile descriptor file for message to be decoded * @param qualifiedMessageType the name of the message to be decoded * @return protobuf descriptor instance * @throws StageException */ public static Descriptors.Descriptor getDescriptor( DescriptorProtos.FileDescriptorSet set, Map<String, Descriptors.FileDescriptor> fileDescriptorMap, String descriptorFile, String qualifiedMessageType) throws StageException { // find the FileDescriptorProto which contains the message type // IF cannot find, then bail out String packageName = null; String messageType = qualifiedMessageType; int lastIndex = qualifiedMessageType.lastIndexOf('.'); if (lastIndex != -1) { packageName = qualifiedMessageType.substring(0, lastIndex); messageType = qualifiedMessageType.substring(lastIndex + 1); } DescriptorProtos.FileDescriptorProto file = getFileDescProtoForMsgType(packageName, messageType, set); if (file == null) { // could not find the message type from all the proto files contained in the descriptor file throw new StageException(Errors.PROTOBUF_00, qualifiedMessageType, descriptorFile); } // finally get the FileDescriptor for the message type Descriptors.FileDescriptor fileDescriptor = fileDescriptorMap.get(file.getName()); // create builder using the FileDescriptor // this can only find the top level message types return fileDescriptor.findMessageTypeByName(messageType); }
/** * 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); } }
/** * Generates a protobuf descriptor instance from a FileDescriptor set. * * @param set set of file descriptors * @param fileDescriptorMap map of message types to file descriptors * @param descriptorFile descriptor file for message to be decoded * @param messageType the name of the message to be decoded * @return protobuf descriptor instance * @throws StageException */ public static Descriptors.Descriptor getDescriptor( DescriptorProtos.FileDescriptorSet set, Map<String, Descriptors.FileDescriptor> fileDescriptorMap, String descriptorFile, String messageType) throws StageException { // find the FileDescriptorProto which contains the message type // IF cannot find, then bail out DescriptorProtos.FileDescriptorProto file = null; for (DescriptorProtos.FileDescriptorProto fileDescriptorProto : set.getFileList()) { for (DescriptorProtos.DescriptorProto descriptorProto : getAllMessageTypesInDescriptorProto(fileDescriptorProto)) { if (messageType.equals(descriptorProto.getName())) { file = fileDescriptorProto; break; } } if (file != null) { break; } } if (file == null) { // could not find the message type from all the proto files contained in the descriptor file throw new StageException(Errors.PROTOBUF_00, messageType, descriptorFile); } // finally get the FileDescriptor for the message type Descriptors.FileDescriptor fileDescriptor = fileDescriptorMap.get(file.getName()); // create builder using the FileDescriptor return fileDescriptor.findMessageTypeByName(messageType); }
private static boolean packageMatch( DescriptorProtos.FileDescriptorProto fileDescriptorProto, String packageName) { // Its a match iff // 1. package name specified as part of message type matches the package name of // FileDescriptorProto // 2. No package specified as part of message type and no package name specified in // FileDescriptorProto boolean packageMatch = false; if (packageName != null && packageName.equals(fileDescriptorProto.getPackage())) { packageMatch = true; } else if (packageName == null && !fileDescriptorProto.hasPackage()) { packageMatch = true; } return packageMatch; }
/** * Returns a Message {@link Descriptor} for a dynamically generated DescriptorProto. * * @param descProto * @throws DescriptorValidationException */ public static Descriptor makeMessageDescriptor(DescriptorProto descProto) throws DescriptorValidationException { DescriptorProtos.FileDescriptorProto fileDescP = DescriptorProtos.FileDescriptorProto.newBuilder().addMessageType(descProto).build(); Descriptors.FileDescriptor[] fileDescs = new Descriptors.FileDescriptor[0]; Descriptors.FileDescriptor dynamicDescriptor = Descriptors.FileDescriptor.buildFrom(fileDescP, fileDescs); return dynamicDescriptor.findMessageTypeByName(descProto.getName()); }
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 static Set<Descriptors.FileDescriptor> getDependencies( Map<String, Set<Descriptors.FileDescriptor>> dependenciesMap, Map<String, Descriptors.FileDescriptor> fileDescriptorMap, DescriptorProtos.FileDescriptorProto file, DescriptorProtos.FileDescriptorSet set) throws StageException { Set<Descriptors.FileDescriptor> result = new LinkedHashSet<>(); for (String name : file.getDependencyList()) { DescriptorProtos.FileDescriptorProto fileDescriptorProto = null; for (DescriptorProtos.FileDescriptorProto fdp : set.getFileList()) { if (name.equals(fdp.getName())) { fileDescriptorProto = fdp; break; } } if (fileDescriptorProto == null) { // could not find the message type from all the proto files contained in the descriptor file throw new StageException(Errors.PROTOBUF_01, file.getName()); } Descriptors.FileDescriptor fileDescriptor; if (fileDescriptorMap.containsKey(fileDescriptorProto.getName())) { fileDescriptor = fileDescriptorMap.get(fileDescriptorProto.getName()); } else { Set<Descriptors.FileDescriptor> deps = new LinkedHashSet<>(); if (dependenciesMap.containsKey(name)) { deps.addAll(dependenciesMap.get(name)); } else { deps.addAll( getDependencies(dependenciesMap, fileDescriptorMap, fileDescriptorProto, set)); } try { fileDescriptor = Descriptors.FileDescriptor.buildFrom( fileDescriptorProto, deps.toArray(new Descriptors.FileDescriptor[deps.size()])); } catch (Descriptors.DescriptorValidationException e) { throw new StageException(Errors.PROTOBUF_07, e.getDescription(), e); } } result.add(fileDescriptor); } return result; }