Reputation: 859
I try to parse the .proto file with the protobuf compiler. But here is a confusing problem that I can't get the options for method.
It seems that my options are treated as "unknown fields" but not the options.
Is there any way to solve the problem? Thanks.
(I hate to paste a lot of code here, but I think it's essential to fully describe the problem. Sorry for that.)
(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;
}
}
Upvotes: 3
Views: 4659
Reputation: 45171
The options are not unknown fields because they are extensions! Extensions were supposedly removed in proto3, but when you parse the .proto
files dynamically using Importer
, extensions are enabled regardless of the syntax version you declare.
If you add a line to your inner for() loop like:
print(method_d->options().DebugString());
You'll get output like:
[lrpc.CmdID]: 1
You can enumerate extension values using protobuf reflection -- they show up when you call Reflection::ListFields()
.
Upvotes: 3