Reputation: 19778
Background: I'm writing a protoc
plugin.
The custom protobuf option is implemented with the following:
syntax = "proto3";
package com.example.proto.options;
import "google/protobuf/descriptor.proto";
option java_multiple_files = true;
option java_outer_classname = "ServerOptionsProto";
option java_package = "com.example.proto.options";
extend google.protobuf.FileOptions {
ServerOptions server = 50621;
}
message ServerOptions {
// Java classname
string name = 1;
}
The following is an example usage:
syntax = "proto3";
package com.example.testdata;
import "com/example/proto/options/server.proto";
option java_multiple_files = true;
option java_package = "com.example.testdata.protogen";
option java_outer_classname = "TestDataProto";
option (com.example.proto.options.server).name = "TestData";
Trying to follow https://developers.google.com/protocol-buffers/docs/proto#options, the following (in Groovy) doesn't work:
request.getProtoFileList().stream().filter { proto ->
proto.serviceCount > 0
}.flatMap { proto ->
serverName = proto.getDescriptor().getOptions()?.getExtension(com.example.proto.options.ServerOptionsProto.server)?.name
}
What's the right way in Java to access the value of the custom option?
Upvotes: 3
Views: 5193
Reputation: 491
For those that need to do it in Java:
as mentioned by Noel, to refer to the a given custom option in your java source code, use java_package
+ java_outer_classname
values that you have defined on top of your proto file.
Concrete example:
syntax = "proto3";
import "google/protobuf/descriptor.proto";
option java_multiple_files = true;
option java_package = "com.marco.grpc.server.v1";
option java_outer_classname = "MyGrpcServer";
extend google.protobuf.FieldOptions {
bool encrypt = 50001;
}
Then in the source code, with the following code you can retrieve all the names of the fields that have a given option, in this case the custom encrypt
option:
myProtoMessage.getDescriptorForType().getFields()
.stream()
.filter(field -> field.getOptions().getExtension(com.marco.grpc.server.v1.MyGrpcServer.encrypt))
.map(FieldDescriptor::getName)
.collect(Collectors.toList());
Upvotes: 0
Reputation: 19778
The java_package
and java_outer_classname
options need to be used:
serverName = proto.getOptions()?.getExtension(com.example.proto.options.ServerOptionsProto.server)?.name
Also, since this is processed by a protoc
plugin, the extension needs to be registered as per Extensions:
final registry = ExtensionRegistry.newInstance();
registry.add(ServerOptionsProto.server)
final request = PluginProtos.CodeGeneratorRequest.parseFrom(input, registry)
Upvotes: 4
Reputation: 1476
I believe the problem is that your option is a file-level one, but you are trying to access it as if it were a message-level option. Instead of proto.getDescriptor().getOptions()
, try proto.getDescriptor().getFile().getOptions()
.
Upvotes: -1