Wire's Proto3 support is Out!

Starting in 3.3.0 Wire supports Proto3. What changes with Proto3? How does Wire make it comfortable to use? Let’s see.

Identity if absent

Proto3 doesn’t allow the required label anymore. All single fields are either without a label or optional 1. A single field without any label is what we call “Identity if absent” which is very much not optional. This means that a field, if not set, will default to its type’s identity value. For instance, int32 identity is 0. This also means that one cannot tell the difference between an absence of value and a value set to its identity.

In Kotlin, Wire is able to use default parameters to express this behavior in APIs.

message PizzaDelivery {
  string address = 1;

will generate

class PizzaDelivery(
  val address: String = "",
) : Message<PizzaDelivery, Builder> {}

New Types

Proto3 brings new powerful types to the table. There are types to express time, some to represent JSON objects, and one to placehold anything! Wire will reuse platform types when possible. For instance, google.protobuf.Duration will be generated using the java.time.Duration type on JVM platforms. Our documentation describes how we’re handling each of them.


While Proto2 didn’t, Proto3 specifies Protobuf serialization over JSON. We’ve tested Wire for compatibility with the spec and Protoc. Wire continues to support JSON serialization of Protobuf messages on both Moshi and Gson.


Both Proto2 and Proto3 types can be referenced by each other. For instance, one can add a google.protobuf.Duration field to a Proto2 message! The only exception being that Proto2 enums cannot be referenced inside a Proto3 message.


With the 3.3.0 release, Wire now handles Protobuf options idiomatically. There’s also a new file option for easy cohabitation of Wire alongside Protoc. And many other things! which are listed in our CHANGELOG. Try it out!

  1. Until recently, Google protobuf didn’t allow optional either, it has been added in protobuf 3.12