Search code examples
javakotlinprotocol-buffers

How to pack a repeated protobuf message into an Any


I'm working with a third party service that consumes a com.google.protobuf.Any. I need to pass in a repeated Message myObject object, but how does one pack a repeated protobuf field into an Any?

I'm writing a Kotlin extension function along the lines of fun List<Message>.toProtobufAny(): com.google.protobuf.Any {...} to (hopefully) make this generic for any Message because I'll be sending in a variety of repeated message types. My first attempts have been to implement an Any.pack(RepeatedFieldBuilder<>), but haven't been successful yet with the syntax. Not finding very many code example out there on this specific use case.

Thanks.

Edit to include example

@ILYAS_Kerbal

I set up a basic message to hold a repeated list of Anys

message RepeatedAny {
    repeated google.protobuf.Any values = 1;
}

And then created a couple extension functions to support it...


/**
 * Given a list of protobuf messages, create a protobuf.Any
 */
fun List<Message>.toProtoAny(): Any {
    val repeatedAny = RepeatedAny.newBuilder().addAllValues(
        this.map { msg -> msg.toProtoAny() }
    ).build()

    return repeatedAny.toProtoAny()
}

/**
 * Pack a protobuf.Message into a protobuf.Any
 */
fun Message.toProtoAny(): Any = this.packAny()

/**
 * Pack a protobuf.Message into a protobuf.Any
 */
private fun Message.packAny(): Any =
    Any.pack(this, "$defaultAnyLibrary/${this.javaClass.name}")

Hope that helps


Solution

  • An Any contains a single proto, not a repeated field.

    You can create a List<Any>, your own AnyRepeated proto, or an Any containing a proto that has a repeated proto field for your chosen message type, but you cannot pack more than one proto into an Any.