3

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?

Noel Yap
  • 18,822
  • 21
  • 92
  • 144
  • Be it an extension at file level, class level or at Enum's level; in java you can get the value by specifying that entity(file/enum/class etc) and then get its' Descripter() or ValueDescripter() and then specify getExtension(). Similar to this answer https://stackoverflow.com/a/64416797/1750360 – pxm Mar 07 '23 at 21:45

2 Answers2

4

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)
Noel Yap
  • 18,822
  • 21
  • 92
  • 144
  • 2
    I wish I could gild you or something. I have scoured the web trying to figure out why my code generator isn't seeing the extensions I've added and finally after 8 hours of banging my head against the wall came across this gem. A++ for your "Also..." addition to this answer which made my day. – TheSoftwareJedi Oct 03 '19 at 20:06
  • 1
    Your comment made my day :-) Thanks! – Noel Yap Oct 03 '19 at 20:41
-1

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().

Adam Cozzette
  • 1,396
  • 8
  • 9