-
Notifications
You must be signed in to change notification settings - Fork 620
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
Missing Feature - ProtoOneOf doesn't support complex objects #2718
Comments
Sorry but I cannot get your point. If you are saying a custom message type in oneof field, it is currently supported in protobuf. You can check this test for example. And your code seems not matching the protobuf declaration. |
Hey @xiaozhikang0916 ! Nice to see you around. You are right, the test works with single field, however if the subclass has more than one field it will fail. I simplified above example to avoid confusion |
Your example proto can be described in kotlin like import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromHexString
import kotlinx.serialization.encodeToHexString
import kotlin.test.Test
import kotlin.test.assertEquals
class TestComplicatedOneOf {
@Serializable
data class AttoTransaction(
@ProtoNumber(1) val sign: String,
@ProtoNumber(2) val work: String,
@ProtoOneOf val oneOf: IBlock,
)
@Serializable
sealed interface IBlock
@Serializable
data class BlockOpen(@ProtoNumber(3) val value: AttoOpen) : IBlock
@Serializable
data class BlockSend(@ProtoNumber(4) val value: AttoSend) : IBlock
@Serializable
data class AttoOpen(@ProtoNumber(1) val field1: String, @ProtoNumber(2) val field2: String)
@Serializable
data class AttoSend(@ProtoNumber(1) val field1: String, @ProtoNumber(2) val field2: String)
@Test
fun test() {
val attoTransactionOpen = AttoTransaction("sign1", "work1", BlockOpen(AttoOpen("atto", "open")))
val hex = ProtoBuf.encodeToHexString(AttoTransaction.serializer(), attoTransactionOpen)
println(hex)
val restored = ProtoBuf.decodeFromHexString(AttoTransaction.serializer(), hex)
assertEquals(attoTransactionOpen, restored)
val attoTransactionSend = AttoTransaction("sign2", "work2", BlockSend(AttoSend("hello", "send")))
val hex2 = ProtoBuf.encodeToHexString(AttoTransaction.serializer(), attoTransactionSend)
println(hex2)
val restored2 = ProtoBuf.decodeFromHexString(AttoTransaction.serializer(), hex2)
assertEquals(attoTransactionSend, restored2)
}
} And this test passed as expected. Did you miss the |
Sorry for the delay, I haven't seen the notification. I didn't realize that I should wrap the class... This definitely works and gives the correct Protobuf schema. However, I was under the impression the Kotlin definition would be similar to generated Protobuf Java classes (without the need for a wrapper class). This requirement also seems to break how JSON serialization of polymorphic serialization works; implementations are able to have more than one field. |
The Java class generated by proto plugin will generate a On the other hand, Wrapper class here, may not be ideal, but should be the best way for the oneof field, as long as kotlin does not support union types yet.
That is not true. |
What is your use-case and why do you need this feature?
@ProtoOneOf
was introduced in the last release, allowing us to define polymorphic classes in a protobuf way. However, it seems we are missing a critical feature: support for complex children.Describe the solution you'd like
kotlinx.serialization
protobuf oneof supports complex types:The text was updated successfully, but these errors were encountered: