protobuf-es icon indicating copy to clipboard operation
protobuf-es copied to clipboard

Simple approach for proto2 extensions

Open timostamm opened this issue 3 years ago • 0 comments

This is a simplistic approach at supporting proto2 extensions. Instead of introducing a bespoke type that users attach to a message, generate the fields added by an extension right on the extended message, like any other field.

syntax = "proto2";
package spec;
message Proto2Extendee {
  extensions 100 to max;
}
extend Proto2Extendee {
  repeated string bar = 101;
}
export class Proto2Extendee extends Message<Proto2Extendee> {
  /**
   * @generated from extension spec.bar
   */
  "spec.bar": string[] = [];

This works because ECMAScript allows arbitrary strings as property names, and completely avoids the complexity of global registries. This does not give us a good place to generate comments for an extension, and the approach falls short for use cases where the user is not in control of the generated code of the extendee - most importantly in the case of handling custom options in a code generator plugin.

This is a prototype to evaluate the approach. It may never land.

There are quite a few loose ends, namely:

  • find a decent naming scheme for namespace-less extension fields, which potentially clash with extendee fields
  • implement extensions in DescriptorSet, with correct localName and jsonName
  • support extensions in createRegistryFromDescriptors()
  • replace DescMessage.getExtensions() with pre-computed array, and add to DescMessage.members
  • consolidate the functions creating names (too many functions in names.ts now)
  • generate extension fields in JS
  • optimize FieldInfo for extensions in generated code
  • add meaningful tests

timostamm avatar Sep 27 '22 13:09 timostamm