bjoernhaeuser
bjoernhaeuser

Reputation: 407

Extensions in proto3

Given the following proto definitions:

syntax = "proto3";

import "google/protobuf/descriptor.proto";

option java_package = "com.example.dto";

option java_multiple_files = true;

extend google.protobuf.FieldOptions {
    Projector projector = 50002;
}

message Projector {
    string name = 1;
    string class = 2;
    bool default = 3;
}

message SearchRequest {
    string query = 1 [(projector) = {name: "queryProjector", class: "foobar"}];
    int32 page_number = 2;
    int32 result_per_page = 3;
}

How can I access the field extension?

As far as I understand extension still work in proto3, but are generally replaced by the Any type?

I came as this far:

final Descriptors.Descriptor descriptor = SearchRequest.getDescriptor();

final Descriptors.FieldDescriptor query = descriptor.findFieldByName("query");

Is this the right way? Whats the next step?

Upvotes: 4

Views: 8643

Answers (1)

Marcel Lanz
Marcel Lanz

Reputation: 49

As stated here https://github.com/google/protobuf/issues/1460

Custom options are still supported. It's the only place where you can use extensions in proto3. It works the same way as in proto2. Languages that don't support proto2 may provide a special API to access custom options as they don't support extensions.

so custom options seem to be still supported and you should get them using

descriptor.findFieldByName("query").getOptions().getAllFields();

That would return you a map of your custom options (as fields)

final Map<Descriptors.FieldDescriptor, Object> allFields;

whereas the value would be the type of your option, Projector in your case.

The FileDescriptor for this custom option (projector) seems to be generated as a public static in a class named after your *.proto file using its camelCase name.

If your proto file is called search_service_v1.proto you might find the custom option directly as follows:

final DescriptorProtos.FieldOptions options descriptor.findFieldByName("query").getOptions();
final Object field = options.getField(SearchServiceV1.projector.getDescriptor());

And you'll get your extension by

final Projector projector = Projector.class.cast(field);

Upvotes: 4

Related Questions