下面列出了com.google.protobuf.Descriptors.FileDescriptor#buildFrom ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Recursively constructs file descriptors for all dependencies of the supplied proto and returns
* a {@link FileDescriptor} for the supplied proto itself. For maximal efficiency, reuse the
* descriptorCache argument across calls.
*/
private static FileDescriptor descriptorFromProto(
FileDescriptorProto descriptorProto,
ImmutableMap<String, FileDescriptorProto> descriptorProtoIndex,
Map<String, FileDescriptor> descriptorCache) throws DescriptorValidationException {
// First, check the cache.
String descriptorName = descriptorProto.getName();
if (descriptorCache.containsKey(descriptorName)) {
return descriptorCache.get(descriptorName);
}
// Then, fetch all the required dependencies recursively.
ImmutableList.Builder<FileDescriptor> dependencies = ImmutableList.builder();
for (String dependencyName : descriptorProto.getDependencyList()) {
if (!descriptorProtoIndex.containsKey(dependencyName)) {
throw new IllegalArgumentException("Could not find dependency: " + dependencyName);
}
FileDescriptorProto dependencyProto = descriptorProtoIndex.get(dependencyName);
dependencies.add(descriptorFromProto(dependencyProto, descriptorProtoIndex, descriptorCache));
}
// Finally, construct the actual descriptor.
FileDescriptor[] empty = new FileDescriptor[0];
return FileDescriptor.buildFrom(descriptorProto, dependencies.build().toArray(empty));
}
/**
* Recursively constructs file descriptors for all dependencies of the supplied proto and returns
* a {@link FileDescriptor} for the supplied proto itself. For maximal efficiency, reuse the
* descriptorCache argument across calls.
*/
private static FileDescriptor descriptorFromProto(
FileDescriptorProto descriptorProto,
ImmutableMap<String, FileDescriptorProto> descriptorProtoIndex,
Map<String, FileDescriptor> descriptorCache) throws DescriptorValidationException {
// First, check the cache.
String descritorName = descriptorProto.getName();
if (descriptorCache.containsKey(descritorName)) {
return descriptorCache.get(descritorName);
}
// Then, fetch all the required dependencies recursively.
ImmutableList.Builder<FileDescriptor> dependencies = ImmutableList.builder();
for (String dependencyName : descriptorProto.getDependencyList()) {
if (!descriptorProtoIndex.containsKey(dependencyName)) {
throw new IllegalArgumentException("Could not find dependency: " + dependencyName);
}
FileDescriptorProto dependencyProto = descriptorProtoIndex.get(dependencyName);
dependencies.add(descriptorFromProto(dependencyProto, descriptorProtoIndex, descriptorCache));
}
// Finally, construct the actual descriptor.
FileDescriptor[] empty = new FileDescriptor[0];
return FileDescriptor.buildFrom(descriptorProto, dependencies.build().toArray(empty));
}
/**
* Recursively constructs file descriptors for all dependencies of the supplied proto and returns
* a {@link FileDescriptor} for the supplied proto itself. For maximal efficiency, reuse the
* descriptorCache argument across calls.
*/
private static FileDescriptor descriptorFromProto(
FileDescriptorProto descriptorProto,
ImmutableMap<String, FileDescriptorProto> descriptorProtoIndex,
Map<String, FileDescriptor> descriptorCache) throws DescriptorValidationException {
// First, check the cache.
String descriptorName = descriptorProto.getName();
if (descriptorCache.containsKey(descriptorName)) {
return descriptorCache.get(descriptorName);
}
// Then, fetch all the required dependencies recursively.
ImmutableList.Builder<FileDescriptor> dependencies = ImmutableList.builder();
for (String dependencyName : descriptorProto.getDependencyList()) {
if (!descriptorProtoIndex.containsKey(dependencyName)) {
throw new IllegalArgumentException("Could not find dependency: " + dependencyName);
}
FileDescriptorProto dependencyProto = descriptorProtoIndex.get(dependencyName);
dependencies.add(descriptorFromProto(dependencyProto, descriptorProtoIndex, descriptorCache));
}
// Finally, construct the actual descriptor.
FileDescriptor[] empty = new FileDescriptor[0];
return FileDescriptor.buildFrom(descriptorProto, dependencies.build().toArray(empty));
}
void loadProtos(RpcApp app, String proto) {
if (isEmpty(proto)) {
log.info("no dynamic proto resource need to load");
return;
}
if (!proto.endsWith("/")) proto = proto + "/";
try {
InputStream basein = RpcMetas.class.getResourceAsStream("descriptor.proto.pb");
FileDescriptorSet baseSet = FileDescriptorSet.parseFrom(basein);
basein.close();
FileDescriptor base = FileDescriptor.buildFrom(baseSet.getFile(0), new FileDescriptor[]{});
List<String> files = getProtoFiles(proto);
for (String file : files) {
loadProtoFile(app, base, proto + file);
}
} catch (Exception e) {
log.error("load dynamic proto resource failed", e);
}
}
/**
* Encodes the data portion of an ExecutionResult as ByteString.
*
* <p>The FileDescriptorSet must contain a message with the name "{operationName}Response". This
* message will be populated with data from the execution result and encoded as a ByteString.
*/
public static ByteString encodeResponse(
String operationName, FileDescriptorSet fileDescriptorSet, ExecutionResult executionResult) {
try {
// TODO: Support multiple FileDescriptors in FileDescriptorSet
FileDescriptor fileDescriptor =
FileDescriptor.buildFrom(fileDescriptorSet.getFileList().get(0), new FileDescriptor[] {});
Descriptor messageType = fileDescriptor.findMessageTypeByName(operationName + "Response");
Message message = DynamicMessage.parseFrom(messageType, ByteString.EMPTY);
Message responseData = QueryResponseToProto.buildMessage(message, executionResult.getData());
return responseData.toByteString();
} catch (DescriptorValidationException | InvalidProtocolBufferException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Nonnull
static FileDescriptor mutateFile(@Nonnull FileDescriptor originalFile, @Nonnull Consumer<DescriptorProtos.FileDescriptorProto.Builder> fileMutation) {
DescriptorProtos.FileDescriptorProto.Builder fileBuilder = originalFile.toProto().toBuilder();
fileMutation.accept(fileBuilder);
try {
return FileDescriptor.buildFrom(fileBuilder.build(), new FileDescriptor[]{RecordMetaDataOptionsProto.getDescriptor()});
} catch (Descriptors.DescriptorValidationException e) {
throw new RecordCoreException("unable to build file descriptor", e);
}
}
private void loadProtoFile(RpcApp app, FileDescriptor base, String file) throws IOException, DescriptorValidationException {
InputStream in = getResource(file);
FileDescriptorSet descriptorSet = FileDescriptorSet.parseFrom(in);
in.close();
Map<String, Descriptor> descriptors = new HashMap<>();
for (FileDescriptorProto fdp : descriptorSet.getFileList()) {
FileDescriptor fd = FileDescriptor.buildFrom(fdp, new FileDescriptor[]{base});
for (Descriptor descriptor : fd.getMessageTypes()) {
String className = descriptor.getName();
descriptors.put(className, descriptor);
}
for (ServiceDescriptor svr : fd.getServices()) {
Field f = svr.getOptions().getUnknownFields().getField(KrpcExt.SERVICEID_FIELD_NUMBER);
String serviceName = svr.getName();
int serviceId = f.getVarintList().get(0).intValue();
for (MethodDescriptor m : svr.getMethods()) {
String msgName = m.getName();
Field f2 = m.getOptions().getUnknownFields().getField(KrpcExt.MSGID_FIELD_NUMBER);
int msgId = f2.getVarintList().get(0).intValue();
log.info(String.format("dynamic proto resource loaded, serviceId=%d,msgId=%d,serviceName=%s,msgName=%s", serviceId, msgId, serviceName, msgName));
Descriptor reqDesc = m.getInputType();
Descriptor resDesc = m.getOutputType();
app.serviceMetas.addDynamic(serviceId, msgId, reqDesc, resDesc, serviceName, msgName);
}
}
}
}
/**
* Returns a Map containing data from a ByteString that is parsed using the Proto Descriptor.
*
* <p>The FileDescriptorSet must contain a message with the name "{operationName}Request". This
* message will be used to parse the ByteString, and the resulting message will be transformed and
* returned as a Map.
*/
public static Map<String, Object> decodeVariables(
String operationName, FileDescriptorSet fileDescriptorSet, ByteString encodedRequest) {
try {
// TODO: Support multiple FileDescriptors in FileDescriptorSet
FileDescriptor fileDescriptor =
FileDescriptor.buildFrom(fileDescriptorSet.getFileList().get(0), new FileDescriptor[] {});
Descriptor messageType = fileDescriptor.findMessageTypeByName(operationName + "Request");
Message message = DynamicMessage.parseFrom(messageType, encodedRequest);
return ProtoToMap.messageToMap(message);
} catch (DescriptorValidationException | InvalidProtocolBufferException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
static ProtobufRowDataConverter buildRowDataConverter(HasStorage object,
FileDescriptorProto fileProto) {
Group group = (Group)object;
FileDescriptor fileDescriptor;
try {
fileDescriptor = FileDescriptor.buildFrom(fileProto, DEPENDENCIES);
}
catch (DescriptorValidationException ex) {
throw new ProtobufBuildException(ex);
}
return ProtobufRowDataConverter.forGroup(group, fileDescriptor);
}
static ProtobufRowConverter buildRowConverter(HasStorage object, FileDescriptorProto fileProto) {
Group group = (Group) object;
FileDescriptor fileDescriptor;
try {
fileDescriptor = FileDescriptor.buildFrom(fileProto, DEPENDENCIES);
}
catch (DescriptorValidationException ex) {
throw new ProtobufBuildException(ex);
}
return ProtobufRowConverter.forGroup(group, fileDescriptor);
}
protected ProtobufRowConverter converter(Group g) throws Exception {
AISToProtobuf a2p = new AISToProtobuf(ProtobufRowFormat.Type.GROUP_MESSAGE);
a2p.addGroup(g);
FileDescriptorSet set = a2p.build();
FileDescriptor gdesc = FileDescriptor.buildFrom(set.getFile(0),
ProtobufStorageDescriptionHelper.DEPENDENCIES);
return ProtobufRowConverter.forGroup(g, gdesc);
}
protected ProtobufRowDataConverter converter(Group g) throws Exception {
AISToProtobuf a2p = new AISToProtobuf(ProtobufRowFormat.Type.GROUP_MESSAGE);
a2p.addGroup(g);
FileDescriptorSet set = a2p.build();
if (false) {
new ProtobufDecompiler((Appendable)System.out).decompile(set);
}
FileDescriptor gdesc = FileDescriptor.buildFrom(set.getFile(0),
ProtobufStorageDescriptionHelper.DEPENDENCIES);
return ProtobufRowDataConverter.forGroup(g, gdesc);
}
static FileDescriptorProto validateAndGenerate(HasStorage object,
ProtobufRowFormat.Type formatType,
FileDescriptorProto fileProto,
AISValidationOutput output) {
if (!(object instanceof Group)) {
output.reportFailure(new AISValidationFailure(new StorageDescriptionInvalidException(object, "is not a Group and cannot use Protocol Buffers")));
return null;
}
Group group = (Group)object;
if (formatType == ProtobufRowFormat.Type.SINGLE_TABLE) {
if (!group.getRoot().getChildJoins().isEmpty()) {
output.reportFailure(new AISValidationFailure(new StorageDescriptionInvalidException(object, "has more than one table")));
return null;
}
}
int currentVersion = sumTableVersions(group.getRoot());
if (fileProto != null) {
int storedVersion = fileProto.getOptions()
.getExtension(CustomOptions.GroupOptions.fdbsql).getVersion();
if (storedVersion == currentVersion) {
return fileProto;
}
}
FileDescriptorSet set = null;
if (fileProto != null) {
FileDescriptorSet.Builder builder = FileDescriptorSet.newBuilder();
builder.addFile(fileProto);
set = builder.build();
}
AISToProtobuf ais2p = new AISToProtobuf(formatType, set);
ais2p.addGroup(group);
set = ais2p.build();
fileProto = set.getFile(0); // Only added one group.
// Make sure it will build before committing to this format.
try {
FileDescriptor.buildFrom(fileProto, DEPENDENCIES);
}
catch (DescriptorValidationException ex) {
output.reportFailure(new AISValidationFailure(new ProtobufBuildException(ex)));
}
return fileProto;
}