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
Adding special value UNRECOGNIZED to the enum type #2725
Comments
I'm surprised protoc didn't throw on that. Is there a lenient flag you can turn on to get that behaviour? |
The doc says it adds it all the time? https://protobuf.dev/reference/java/java-generated/#enum Even if the example had a constant with a What is happening... |
|
Hi, we don't use any special flags. The protoc compiler automatically adds Here’s a part of our proto scheme (luckily here we have that
And this is the corresponding generated enum in Java (a part of generated code):
The generated Price class looks like this (part of it):
As illustrated, the constructor initializes the default value to |
Got it. Wire since the beginning has been returning null. This would be breaking for most consumers. Maybe we could put it behind an option for Java and Kotlin generation... 🤔 Java: public static CurrencyCodeType fromValue(int value) {
switch (value) {
case 0: return CURRENCYCODETYPE_UNKNOWN;
case 1: return CURRENCYCODETYPE_EUR;
case 2: return CURRENCYCODETYPE_USD;
default: return null;
}
} Kotlin: public fun fromValue(`value`: Int): CurrencyCodeType? = when (value) {
0 -> CURRENCYCODETYPE_UNKNOWN
1 -> CURRENCYCODETYPE_EUR
2 -> CURRENCYCODETYPE_USD
else -> null
} |
I don't believe the issue lies with returning null (my example also returns null). The potential problem, as I see it, could arise with the decode function in messages that utilize enum. Take a look at the following example, which is a snippet from the Price source code generated using Wire:
Or, as you've highlighted, if the |
I wonder if protoc-kotlin does it too? I'm surprised Java does it on its own since it's not specified in the specs. Serialisation should work even if the service on the other side doesn't do that. |
protoc-kotlinIt's important to note that protoc-kotlin operates similarly to protoc-java because it essentially acts as a Kotlin wrapper over the Java code, as outlined in the Protocol Buffers Kotlin tutorial. This means it doesn't generate enums specifically for Kotlin; they aren't necessary due to this underlying Java implementation. However, a key distinction with protoc-kotlin is its handling of proto
This DSL essentially provides a Kotlin-friendly way to interact with the underlying Java builder. For example, the currencyCode property in the Kotlin DSL:
corresponds to the Java generated code, like so:
In essence, the Kotlin DSL is a layer on top of the Java builder, ultimately calling the same underlying Java functions for properties like currencyCodeType. In response to the comment about "wire breaking"
Your point about Wire potentially breaking existing call sites is valid, though I find this primarily affects properties due to their naming patterns. Although it's interesting why Wire uses underscore naming instead of camelCase, that's not our main focus here, so I'll put that topic aside for now. For enums, Wire does things similarly to protoc-java, so we get the Kotlin versions without having to change any code, which is great because the names stay the same. The only hitch is that Wire skips adding the UNRECOGNIZED value to the enums, unlike protoc-java which always includes it. Swapping that out isn't too tough, but the issue with Wire is it falls back to the first value by default. That's tricky for us because then we can't tell if it's really the first value or some new value that the client doesn't know about yet. |
Hi @oldergod, I've forked the repository and submitted a pull request with my proposed solution to address the issue |
Sorry I missed your last message, I've been thinking about it and I cannot convince myself that the change is required. |
Oh, right, I just meant that Wire defaults to the value at 0, which is usually the first one listed, hence my 'first value' mix-up 😅. I get why you might not see the need for a change. The thing is, when our proto models were initially set up (before my time on the project), there was this fallback to -1, which is even mentioned in the proto docs. So, I guess that's why some of our developers didn't always bother to put a special or unknown value in the 0 position. |
I think I'm starting to understand what's happening. Why?With the new no-label field in proto3, an enum cannot be null. It has to be of some value, defaulting to its identity value ( The $10 question is: you receive the value
So how about this?
I might have time to do that but that'll be Feb 2024. @JurajBegovac if you're willing to do it, why not? We could start on one language at first (the adapter code is shared anyway). I'll be out for a few weeks so won't be able to give feedback for a while. |
Awesome news 😄 By the way, you should probably see if this change might affect any existing clients. Perhaps making it optional would be a good idea – like something we can toggle via the Gradle plugin (https://square.github.io/wire/wire_compiler/#kotlin). Or are you thinking it should be a default thing for all proto3 projects? 🤷 No hurry on our end (we're still using protoc, so we're all good for now). Also, I'm up for working on this. If you've got any tips, ideas, or suggestions on where I should start, that'd be really helpful! |
This would be a feature one has to opt-in. I'm not sure about the integration. The safe first step would be to add it to |
I've already added it in to |
Hi @oldergod 😄 |
It's on my radar but other priorities right now. I don't have a clear image yet as how to implement it. I don't think the constant -1 makes sense with the current API offered by Wire. |
Summary of some digging:
Steps (PR separation):
|
I guess only kotlin is fine but as you wish 😄 |
Hello @oldergod, I was wondering if there's been any update on the task. Please let me know if there's anything I can assist with. |
@JurajBegovac We started work on it 2 weeks ago. Should be ready by the end of April, or early May at the latest. We update #2725 (comment) as we go |
Are there any plans for Wire to add an UNRECOGNIZED value to enums, similar to the functionality provided by the proto3 compiler for Java?
https://protobuf.dev/reference/java/java-generated/#enum
The context for my query is that I'm working on a project where we're considering switching to Wire for generating Kotlin code from our proto3 schema. However, I've noticed that not all enums in our existing proto schema include a special type in the first position (value 0). This feature of handling unknown enum values automatically is important for our project's compatibility and robustness, and I'm interested in knowing if Wire plans to support something similar for Kotlin. If this feature is not planned, is there a possibility for me to implement it myself using some custom handler or workaround?
Thank you in advance
The text was updated successfully, but these errors were encountered: