导入包含导入的描述符

时间:2018-11-21 13:56:30

标签: java protocol-buffers

我正在尝试从外部源获取负载描述符。 当使用没有导入的生成文件时,它没有问题,但是当原型具有导入,然后在构建FileDescriptor时,我得到DescriptorValidationException:

  

无法解析描述符./descriptors/test.dsc   com.google.protobuf.Descriptors $ DescriptorValidationException:AccessRequest.date_from:“。google.protobuf.Timestamp”未定义。

我用来获取* .dsc文件的原始文件:

syntax = "proto3";
import "google/protobuf/timestamp.proto";
message AccessRequest {
    int64 cabinet_id = 1;
    google.protobuf.Timestamp date_from = 2;
    google.protobuf.Timestamp date_to = 3;
}

我用来获取* .dsc的命令:

protoc --include_imports --proto_path=src/main/proto/ --descriptor_set_out=descriptors/test.dsc  src/main/proto/test.proto 

我要加载* .dsc文件的代码:

try (final InputStream stream = Files.newInputStream(path)) {
            final FileDescriptorSet fds = FileDescriptorSet.parseFrom(stream);

            final TypeRegistry.Builder builder = TypeRegistry.newBuilder();
            for (final FileDescriptorProto fdp : fds.getFileList()) {
                final FileDescriptor fd = FileDescriptor.buildFrom(fdp, new FileDescriptor[]{});
                builder.add(fd.getMessageTypes());
                globalBuilder.add(fd.getMessageTypes());
            }
            return new Queue(base, builder.build());
        }

2 个答案:

答案 0 :(得分:0)

FileDescriptor.buildFrom(fdp, new FileDescriptor[]{})是关键。 您应该递归地构建依赖关系原型proto(import),并使用结果替换第二个参数。 给我我的代码以供参考

private FileDescriptor buildFileDescriptor(FileDescriptorProto currentFileProto,
                                           Map<String, FileDescriptorProto> fileProtoCache) {
    List<FileDescriptor> dependencyFileDescriptorList = new ArrayList<>();
    currentFileProto.getDependencyList().forEach(dependencyStr -> {
        FileDescriptorProto dependencyFileProto = fileProtoCache.get(dependencyStr);
        FileDescriptor dependencyFileDescriptor = buildFileDescriptor(dependencyFileProto, fileProtoCache);
        dependencyFileDescriptorList.add(dependencyFileDescriptor);
    });
    try {
        return FileDescriptor.buildFrom(currentFileProto, dependencyFileDescriptorList.toArray(new FileDescriptor[0]));
    } catch (DescriptorValidationException e) {
        throw new IllegalStateException("FileDescriptor build fail!", e);
    }
}

答案 1 :(得分:0)

我知道已经很晚了,但是如果有人想用导入来解析.desc文件,这似乎对我有用:

'''
class Node{
    int data;
    Node left, right;
    int height;
    Node(int d){
        this.data = d;
        this.left = this.right = null;
        this.height = 1;
    }
    Node(){
        this.left = this.right = null;
    }
}

class MedianFinder {
    static Node root;
    MedianFinder(){
        root = new Node();
    }
    public void addNum(int num) {

        insert(root, num);
    }


    public static Node insert(Node root, int num){
        if(root == null)
            return (new Node(num));

        if(root.data < num){
            root.right = insert(root.right, num);
        }
        else if(root.data > num)
            root.left = insert(root.left, num);


        root.height = max(height(root.left) , height(root.right)) + 1;

        int balance = get_balance(root);
        // if left left
        if(balance > 2 && num < root.left.data){
            return rightRotation(root);
        }
        // left right case
        if(balance > 2 && num > root.left.data){
            leftRotation(root.left);
            return rightRotation(root);
        }
        // right right case
        if(balance < -1 && num > root.right.data)
            return leftRotation(root);

        // right left case
        if(balance < -1 && num < root.right.data){
            rightRotation(root.right);
            return leftRotation(root);
        }
        return root;

    }

    public static Node rightRotation(Node node){
        Node temp = node.left;
        Node tempright = temp.right;
        temp.right = node;
        node.left = tempright;

        node.height = max(height(node.left), height(node.right)) + 1;
        temp.height = max(height(temp.left), height(temp.right)) + 1;

        return temp;
    }

    public static Node leftRotation(Node node){
        Node temp = node.right;
        Node templeft = temp.left;
        temp.left = node;
        node.right = templeft;

        node.height = max(height(node.left), height(node.right)) + 1;
        temp.height = max(height(temp.left), height(temp.right)) + 1;

        return temp;
    }

    public static int get_balance(Node node){
        if(node == null)
            return 0;
        return height(node.left) - height(node.right);
    }

    public static int height(Node node){
        if(node == null)
            return 0;
        return node.height;
    }
    public static int max(int a, int b){
        return a>b?a:b;
    }

    public double findMedian() {

        if(height(root.left) == height(root.right))
            return root.data;
        return (root.data + root.right.data) / 2;

    }

    public static int count(Node node){
        if(node == null)
            return 0;
        return 1 + count(node.left) + count(node.right);
    }
}

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */

'''