Datastore · Chaining serializers / Default values
Asked Answered
G

0

7

The core problem is that I want to set default values for child messages. Since proto3 doesn't allow the setting of default values in the proto file.

Example Protobuf

message Person {
  int32 age = 1;
  repeated Doggo doggos = 2;
}

message Doggo {
  int32 rating = 1;
}

Example Serializer

object PersonSerializer : Serializer<Person> {
    override val defaultValue: Person =
        Person.getDefaultInstance().toBuilder()
            .setAge(1)
            .build()

    override suspend fun readFrom(input: InputStream): Person {
        try {
            return Person.parseFrom(input)
        } catch (exception: InvalidProtocolBufferException) {
            throw CorruptionException("Cannot read proto.", exception)
        }
    }

    override suspend fun writeTo(t: Person, output: OutputStream) {
        t.writeTo(output)
    }
}

This works to set a default age to 1 for all Persons. The standard value being 0.

However, I also need to set the rating for all Doggos to 10. This cannot be accomplished in this Person serializer.

I would expect there to be a way for me to provide additional serializers for deserializing children.

Such a system could look like this:

object PersonSerializer : Serializer<Person> {
    override val defaultValue: Person =
        Person.getDefaultInstance().toBuilder()
            .setAge(1)
            .build()

    override suspend fun readFrom(input: InputStream): Person {
        try {
            return Person.parseFrom(input,
                serializers = listOf(
                    DoggoSerializer
                )
            )
        } catch (exception: InvalidProtocolBufferException) {
            throw CorruptionException("Cannot read proto.", exception)
        }
    }

    override suspend fun writeTo(t: Person, output: OutputStream) {
        t.writeTo(output)
    }
}

object DoggoSerializer : Serializer<Doggo> {
    override val defaultValue: Doggo =
        Doggo.getDefaultInstance().toBuilder()
            .setRating(10)
            .build()

    override suspend fun readFrom(input: InputStream): Doggo {
        try {
            return Doggo.parseFrom(input)
        } catch (exception: InvalidProtocolBufferException) {
            throw CorruptionException("Cannot read proto.", exception)
        }
    }

    override suspend fun writeTo(t: Doggo, output: OutputStream) {
        t.writeTo(output)
    }
}

Can this be resolved in the current system?

Glassy answered 17/3, 2022 at 16:31 Comment(2)
Have you solved this problem? @GlassySadiras
Unfortunately no. This is an ongoing issue.Glassy

© 2022 - 2024 — McMap. All rights reserved.