2016-12-15 8 views
1

Я пытаюсь разобрать файл .proto вместе с компилятором protobuf. Но вот запутанная проблема, что я не могу получить варианты метода.Как получить параметры метода из дескриптора protobuf?

Похоже, что мои параметры рассматриваются как «неизвестные поля», но не параметры.

Есть ли способ решить эту проблему? Благодарю.

(я ненавижу, чтобы вставить много кода, но я думаю, что очень важно, чтобы в полной мере описать проблему Извините за это.).

(ко: г ++ 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, но при синтаксическом анализе файлов .proto с использованием Importer расширения включаются независимо от версии синтаксиса, которую вы объявляете.

Если добавить строку в ваш внутренний для() цикл, как:

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

Вы получите выход как:

[lrpc.CmdID]: 1 

Вы можете перечислить значения расширения с помощью Protobuf отражения - они отображается, когда вы звоните Reflection::ListFields().