-
Couldn't load subscription status.
- Fork 318
Description
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:
- 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 calledHttpRuleingoogle/api/http.protoand is allowed on method declarations by anextends MethodOptionsdeclaration ingoogle/api/annotations.proto. - The option schemas often make use of
oneofdeclarations extensively. See [protobuf] Support unions. #1854.
oneofvalues in protocol buffer data are fundamentally tagged by field index, but union values in TypeSpec are not tagged.
- 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.