2016-12-15 155 views
1

我尝试使用protobuf编译器解析.proto文件。但是,这是一个令人困惑的问题,我无法获得方法的选项。如何从protobuf描述符中获取方法选项?

看来我的选项被视为“未知字段”而不是选项。

有什么办法可以解决这个问题吗?谢谢。

(我讨厌在这里贴了很多代码,但我认为这是必要的,充分说明问题很抱歉的说。)

(ENV:G ++ 4.7,Ubuntu的16.04,的Protobuf 3.0.0)

#include <google/protobuf/descriptor.h> 
#include <google/protobuf/descriptor.pb.h> 
#include <google/protobuf/dynamic_message.h> 
#include <google/protobuf/compiler/importer.h> 

using namespace std; 
using namespace google::protobuf; 
using namespace google::protobuf::compiler; 

#define print(x) std::cout << x << std::endl 
#define input(x) std::cin >> x 

int main() { 
    DiskSourceTree sourceTree; 
    sourceTree.MapPath("", "./"); 
    sourceTree.MapPath("", "./protobuf/include/"); 
    Importer importer(&sourceTree, NULL); 

    auto fd = importer.Import("example.proto"); 
    assert(fd); 

    int service_count = fd->service_count(); 

    for (int i = 0; i < service_count; i++) { 
     auto service_d = fd->service(i); 
     int method_count = service_d->method_count(); 
     for (int j = 0; j < method_count; j++) { 
      auto method_d = service_d->method(j); 
      print(method_d->options().unknown_fields().field_count());$ 
      print(">> " << method_d->options().uninterpreted_option_size()); 
     } 
    } 
    return 0; 
} 

// lrpc.proto 
syntax = "proto3"; 
package lrpc; 
import "google/protobuf/descriptor.proto"; 


extend google.protobuf.MethodOptions { 
    int32 CmdID  = 50000; 
    string OptString = 50001; 
    string Usage  = 50002; 
} 

// example.proto 
syntax = "proto3"; 

package foobar; 

import "google/protobuf/wrappers.proto"; 
import "google/protobuf/empty.proto"; 

import "lrpc.proto"; 

message SearchRequest { 
    // ... 
} 

message SearchResponse { 
    // ... 
} 

service SearchService { 
    rpc Search(SearchRequest) returns(SearchResponse) { 
     option(lrpc.CmdID) = 1; 
    } 
} 

回答

1

选项不是未知字段,因为它们是extensions!扩展名被认为在proto3中被删除,但是当您使用Importer动态地解析.proto文件时,无论您声明的语法版本如何,都会启用扩展。

如果您添加一行到你内心的()循环,如:

print(method_d->options().DebugString()); 

你会得到输出如下:

[lrpc.CmdID]: 1 

可以使用protobuf的反射枚举值延伸 - 他们当您拨打Reflection::ListFields()时出现。