Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose message class's canonical name #739

Closed
FND opened this issue Mar 6, 2024 · 4 comments
Closed

Expose message class's canonical name #739

FND opened this issue Mar 6, 2024 · 4 comments

Comments

@FND
Copy link

FND commented Mar 6, 2024

In order to do reliable message correlation (think request/response matching or dispatching via oneof), it would be helpful if message classes exposed a canonical name.

Given a message like this:

import { proto3 } from "@bufbuild/protobuf";

const MyResponse = proto3.makeMessageType("my_package.MyResponse", () => [
    { no: 1, name: "request_id", kind: "scalar", T: 13 /* uint32 */ }
]);

... I'd like to convert MyResponse to "myResponse" - i.e. the same value used within oneof messages' case property. (I'm aware that such local names do not necessarily constitute unique identifiers, so one might argue that both full and local name was necessary.)

A bit of reverse engineering suggests I could use localName({ kind: "rpc", name: MyResponse.name }) from a private module, but that seems ill-advised.

FWIW, I don't have strong feelings about instance/static property vs. a (m: Message) => string utility function.

PS: Thanks for your efforts on this project; it helped keep me comparatively sane.

@timostamm
Copy link
Member

Hey @FND, the localName function is exported through the codegenInfo object:

import {codegenInfo} from "@bufbuild/protobuf";
codegenInfo.localName(...);

Note that it requires one of the Desc types as input.

The codegenInfo object also provides the functions safeIdentifier and safeObjectProperty. They are useful for escaping a Protobuf identifier for ECMAScript.

We don't have a function for what you want specifically, but with the functions above, it should be implement a function that reliably converts message names any way you want.

@FND
Copy link
Author

FND commented Mar 20, 2024

Thanks for the response! That sounds promising, but I have to admit it's not clear to me how I can get from a message class (MyResponse in my example) to such a descriptor. My own reading, exploration and reverse engineering got me nowhere; can you enlighten me?

@timostamm
Copy link
Member

Descriptors are not available at runtime. They are available in plugins (see docs), but it looks like that's not what you're doing.

Messages have a type name. In your example, the type name is "my_package.MyResponse". You can get it from a message instance via message.getType().typeName. You can strip the package prefix and lowercase the first character to get to "myResponse".

I'm not sure that this is what you want. You mentioned the names in oneof fields. Note that these are all field names, not message names.

@FND
Copy link
Author

FND commented Mar 26, 2024

You're right, I got myself confused there: Turns out I mostly just need the fields, not the message class itself. The puzzle pieces you've provided were helpful nonetheless; thank you!

Also, I was previously hesitant to derive identifiers from typeName, but I guess it shouldn't be an issue in practice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants