2016-12-15 158 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()時出現。