-
Notifications
You must be signed in to change notification settings - Fork 19
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
[Feature request] support extend
when nested inside a message definition
#135
Comments
Hello, I have to think more about this, but I'm not sure it's feasible 🤔. Indeed, there's nothing in a message that says it's been extended, there are just more fields from an extension. Even though these new fields will have identifiers which are not in the base message, they can overlap between extensions (even if it's not recommended), thus making it impossible to find the extension they are coming from. |
Hello again, I can't reproduce your problem:
|
it looks like you're using a different definition for Command_Ping than i am: // mine, not working
message Command_Ping {
extend SessionCommand {
optional Command_Ping ext = 1000;
}
}
// yours, working
message Command_Ping {
}
extend SessionCommand {
optional Command_Ping ext = 1000;
} |
i did a bit of testing, and it seems like the issue has to do with how code is generated when the definition is nested like i have it, since it affects encoding too running this: SessionCommand.encode!(%SessionCommand{ext: %Command_Ping{}}) |> IO.iodata_to_binary() returns ** (KeyError) key :ext not found
expanding struct: SessionCommand.__struct__/1
iex:6: (file)
(elixir 1.14.2) expanding macro: Kernel.|>/2
iex:6: (file) In order to get the same output with the nested definition, i had to run Command_Ping.encode!(%Command_Ping{ext: %Command_Ping{}}) |> IO.iodata_to_binary() If you need it, the full set of proto defs i am working with is here: https://github.com/Cockatrice/Cockatrice/tree/master/common/pb |
extend
when nested inside a message definition
OK, thanks, with all this information it will be easier to pinpoint the problem! I'll try to come up with a solution as soon as I can. |
I think I've fixed this. Could you try with the branch |
Yes, it seems to be working correctly! The only issue i have found is it currently (identically) defines |
OK, thanks for the feedback! If it works as is, I suggest you keep using this branch while I come up with a better solution. It might involve some API breaking, so I want to make sure I've got everything right. |
I've got a working solution for the decoding part (I still need to figure how to handle the encoding part): iex(1)> defmodule MyModule do
...(1)> use Protox,
...(1)> schema: """
...(1)> syntax = "proto2";
...(1)>
...(1)> message SessionCommand {
...(1)> enum SessionCommandType {
...(1)> PING = 1000;
...(1)> }
...(1)> extensions 100 to max;
...(1)> }
...(1)>
...(1)> message Command_Ping {
...(1)> extend SessionCommand {
...(1)> optional Command_Ping ext = 1000;
...(1)> }
...(1)> }
...(1)> """
...(1)> end
...
iex(2)> SessionCommand.decode!(<<194, 62, 0>>)
%SessionCommand{__uf__: [], ext: {Command_Ping, %Command_Ping{__uf__: []}}}
iex(3)> Note that now syntax = "proto2";
message Extendee {
extensions 100 to max;
}
message Extension1 {
extend Extendee {
optional int32 ext = 101;
}
}
message Extension2 {
extend Extendee {
optional int32 ext = 102;
}
}
So, to sum up: use the first field of the tuple to get the type of the extension field :-). I'll address the encoding part as soon as possible! |
I have the following (simplified) proto2 definition:
When decoding a Command_Ping (when i don't know what message type i'm looking at) I get the following struct:
I then have to detect and correctly decode the extension with something like this:
It would be much nicer if the SessionCommand decoder had a way to know what messages extend it, and then automatically decode to the correct struct (or decode them into some well-known field on the SessionCommand)
The text was updated successfully, but these errors were encountered: