bufbuild / protobuf-es

Protocol Buffers for ECMAScript. The only JavaScript Protobuf library that is fully-compliant with Protobuf conformance tests.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Generated message types from .bin vs. runtime DescriptorSet

fubhy opened this issue · comments

I've got a use-case where I'm generating code (using protoc-gen-es) for a .bin file descriptor. So far so good...

However, at runtime I'd also like to use a registry for the same DescriptorSet. To do so, I've currently got the option to either manually
create a registry of all possible message types, or to use the same FileDescriptor again at runtime like so:

// From previously generated message types ...
createRegistry(...types); // Spread in all types after collecting them from all the generated code.

// From file ...
createRegistryFromDescriptors(createDescriptorSet(fs.readFileSync(...)))

The first option works but is annoying and less convenient than it could be imho.

The second option is quite convenient but doesn't work at runtime because now I've basically got two different instances of the same message types. And since it looks like we should prefer instanceof instead of a MessageType.is(...) util, this means that I can't really compare message types with this because the types in that registry are not the same prototypes as those from the generated code.

Furthermore, this option only really works in environments where I can easily load the binary into the runtime. But either way it feels weird (for this use-case) to do codegen and runtime injection of that FileDescriptor instead of just generating that beforehand too.

Hence, I think it would be quite useful if protoc-gen-es had an option to also generate a DescriptorSet that we could then use to more conveniently create registries at runtime. Thoughts?

How would this work though because the data inside the FileDescriptorSet is runtime data. Were you thinking of generating a FileDescriptorSet file with all of the proto data populated somehow?

It could be I'm just not following, though, so correct me if I'm wrong. It just seems like the current way of reading in the binary image and creating the registry at runtime is the most intuitive?

It's the most intuitive for sure but it runs into the issue of runtime instanceof not matching the generated message types.

Those are absolutely desirable for ergonomics (typings, etc.).

What I'd like to see is an option in protoc-gen-es that produces some kind of structure that I can easily create a registry from that then also works with instanceof. It doesn't have to be a FileDescriptorSet (in fact that would probably be overkill indeed). Maybe just a flat array of all message types that could the be spread into createRegistry(...types);?

Yeah, with a flat array of message types, though, we have the same issues as with providing top-level exports spelled out here: #455. Handling name clashes across packages would be tough.

I don't see us tackling this anytime soon, but this is something you could write a plugin for maybe?

@fubhy Going to close this but if you have any other concerns/questions, feel free to reopen.