Skip to content

[Feature Request] [protobuf] Support schematized declaration options. #4090

@witemple-msft

Description

@witemple-msft

Protobuf has a very comprehensive system for declaring options that can appear on declarations. Supporting these options in some capacity is essential for supporting several Protobuf usecases. For example, there are options in the google.api package that control how gRPC is transcoded to HTTP:

service Messaging {
  rpc GetMessage(GetMessageRequest) returns Message {
    option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}";
  }
}

They can also be compound message value expressions, like this:

service MyService {
  rpc HelloWorld(HelloWorldRequest) returns HelloWorldResponse {
    option (google.api.http) = {
      get: "/v1/hello"
      body: "greeting"
      additional_bindings {
        get: "/hello"
      }
    }
  }
}

Currently, we support some options at the package level only (since we don't support emitting a package to multiple files, we don't distinguish between file-level and package-file-level options), and they are stringly-typed. These options are tricky for a few reasons:

  1. The schemas for options are often declared on the protobuf side. So, the google.api.httpoption schema is enabled by a definition of a message called HttpRule in google/api/http.proto and is allowed on method declarations by an extends MethodOptions declaration in google/api/annotations.proto.
  2. The option schemas often make use of oneof declarations extensively. See [protobuf] Support unions. #1854.
  • oneof values in protocol buffer data are fundamentally tagged by field index, but union values in TypeSpec are not tagged.
  1. Options have their own, separate configuration annotations that look like this:
extend google.protobuf.FileOptions {
  // Specifies an option of type int32, valid on files, with field index 1234 that has "source retention" i.e. is not part of the runtime descriptor pool.
  optional int32 source_retention_option = 1234
      [retention = RETENTION_SOURCE];
}

Allowing a raw, grammatical options annotation like @Protobuf.methodOption("(google.api.http).get = \"/hello\"") could work as a stopgap without allowing the declaration of new options within TypeSpec, since the most common use case is probably to reference options from Google's library or some other extern source.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions