Skip to content

Support Proto oneOf with new annotations and polymophic serializer #2538

@xiaozhikang0916

Description

@xiaozhikang0916

I commented in the issue #67 but I think it is necessary to open a new issue for further discussion.


I am writing a code-gen plugin to build kotlin data class for our proto file. As for oneOf case, a sealed interface may be an ideal solution.

Let's say I have a proto message like

message Person {
    string name = 1;
    oneof phone {
        string mobile = 2;
        string home = 3;
    }
}

My ideal data class will be like

data class Person(
    val name: String,
    val phone: IPhoneType,
)

sealed interface IPhoneType

data class MobilePhone(val value: String): IPhoneType

data class HomePhone(val value: String): IPhoneType

So I need to tell the ProtoBuf Decoder that if it comes with ProtoNum 2 or 3, deserialize it as IPhoneType and assign to the phone field.

A custom serializer for the whole Person class can work, but it would be nice to have some additional annotation supports. Like:

data class Person(
    @ProtoNum(1) val name: String,
    @ProtoOneOfFields(2, 3) val phone: IPhoneType,
)

sealed interface IPhoneType

@ProtoOneOfNum(2)
data class MobilePhone(val value: String): IPhoneType

@ProtoOneOfNum(3)
data class HomePhone(val value: String): IPhoneType

@ProtoOneOfFields tells that this field may be assined by the following ProtoNums, and the @ProtoOneOfNum on the concrete class tells which ProtoNum can be parsed to this type.


Generally, this case could be a flatten key for common serializer ( not ProtoBuf only ).

For example, encoding an instance of Person defined like

@Serializable
data class Person(
    val name: String,
    @Flatten val address: Address,
)

@Serializable
data class Address(val city: String, val street: String)

is especting content (show in json) like:

{
    "name": "Jhon",
    "city": "London",
    "street": "1st Avenue"
}

And then, @ProtoOneOfFields can be a subtype of @Flatten, with more flexiable funcitons.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions