Repository: square/retrofit
Issue: Update to Wire 2

Waiting for its 2.0.0 final release (October), blocks our 2.0.0 release.


Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/pom.xml b/pom.xml
index 40b028a8d4..b26fb4a242 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,7 +60,7 @@
     <gson.version>2.4</gson.version>
     <protobuf.version>2.5.0</protobuf.version>
     <jackson.version>2.4.3</jackson.version>
-    <wire.version>1.7.0</wire.version>
+    <wire.version>2.0.0</wire.version>
     <simplexml.version>2.7.1</simplexml.version>
     <moshi.version>1.0.0</moshi.version>
 
diff --git a/retrofit-converters/wire/README.md b/retrofit-converters/wire/README.md
index 88069b48f3..9c82b143e9 100644
--- a/retrofit-converters/wire/README.md
+++ b/retrofit-converters/wire/README.md
@@ -3,8 +3,5 @@ Wire Converter
 
 A `Converter` which uses [Wire][1] for protocol buffer-compatible serialization.
 
-A default `Wire` instance will be created or one can be configured and passed to the
-`WireConverter` construction to further control the serialization.
-
 
  [1]: https://github.com/square/wire
diff --git a/retrofit-converters/wire/src/main/java/retrofit/WireConverterFactory.java b/retrofit-converters/wire/src/main/java/retrofit/WireConverterFactory.java
index 569527460a..cb108be028 100644
--- a/retrofit-converters/wire/src/main/java/retrofit/WireConverterFactory.java
+++ b/retrofit-converters/wire/src/main/java/retrofit/WireConverterFactory.java
@@ -18,33 +18,21 @@
 import com.squareup.okhttp.RequestBody;
 import com.squareup.okhttp.ResponseBody;
 import com.squareup.wire.Message;
-import com.squareup.wire.Wire;
+import com.squareup.wire.ProtoAdapter;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 
 /**
  * A {@linkplain Converter.Factory converter} that uses Wire for protocol buffers.
  * <p>
- * This converter only applies for types which extend from {@link Message} (or one of its
- * subclasses).
+ * This converter only applies for types which extend from {@link Message}.
  */
 public final class WireConverterFactory extends Converter.Factory {
-  /** Create an instance using a default {@link Wire} instance for conversion. */
   public static WireConverterFactory create() {
-    return create(new Wire());
+    return new WireConverterFactory();
   }
 
-  /** Create an instance using {@code wire} for conversion. */
-  public static WireConverterFactory create(Wire wire) {
-    return new WireConverterFactory(wire);
-  }
-
-  private final Wire wire;
-
-  /** Create a converter using the supplied {@link Wire} instance. */
-  private WireConverterFactory(Wire wire) {
-    if (wire == null) throw new NullPointerException("wire == null");
-    this.wire = wire;
+  private WireConverterFactory() {
   }
 
   @Override
@@ -57,16 +45,20 @@ private WireConverterFactory(Wire wire) {
       return null;
     }
     //noinspection unchecked
-    return new WireResponseBodyConverter<>(wire, (Class<? extends Message>) c);
+    ProtoAdapter<? extends Message> adapter = ProtoAdapter.get((Class<? extends Message>) c);
+    return new WireResponseBodyConverter<>(adapter);
   }
 
   @Override public Converter<?, RequestBody> toRequestBody(Type type, Annotation[] annotations) {
     if (!(type instanceof Class<?>)) {
       return null;
     }
-    if (!Message.class.isAssignableFrom((Class<?>) type)) {
+    Class<?> c = (Class<?>) type;
+    if (!Message.class.isAssignableFrom(c)) {
       return null;
     }
-    return new WireRequestBodyConverter<>();
+    //noinspection unchecked
+    ProtoAdapter<? extends Message> adapter = ProtoAdapter.get((Class<? extends Message>) c);
+    return new WireRequestBodyConverter<>(adapter);
   }
 }
diff --git a/retrofit-converters/wire/src/main/java/retrofit/WireRequestBodyConverter.java b/retrofit-converters/wire/src/main/java/retrofit/WireRequestBodyConverter.java
index fd2defd6e0..9f90062eab 100644
--- a/retrofit-converters/wire/src/main/java/retrofit/WireRequestBodyConverter.java
+++ b/retrofit-converters/wire/src/main/java/retrofit/WireRequestBodyConverter.java
@@ -18,13 +18,22 @@
 import com.squareup.okhttp.MediaType;
 import com.squareup.okhttp.RequestBody;
 import com.squareup.wire.Message;
+import com.squareup.wire.ProtoAdapter;
 import java.io.IOException;
+import okio.Buffer;
 
-final class WireRequestBodyConverter<T extends Message> implements Converter<T, RequestBody> {
+final class WireRequestBodyConverter<T extends Message<T, ?>> implements Converter<T, RequestBody> {
   private static final MediaType MEDIA_TYPE = MediaType.parse("application/x-protobuf");
 
+  private final ProtoAdapter<T> adapter;
+
+  WireRequestBodyConverter(ProtoAdapter<T> adapter) {
+    this.adapter = adapter;
+  }
+
   @Override public RequestBody convert(T value) throws IOException {
-    byte[] bytes = value.toByteArray();
-    return RequestBody.create(MEDIA_TYPE, bytes);
+    Buffer buffer = new Buffer();
+    adapter.encode(buffer, value);
+    return RequestBody.create(MEDIA_TYPE, buffer.snapshot());
   }
 }
diff --git a/retrofit-converters/wire/src/main/java/retrofit/WireResponseBodyConverter.java b/retrofit-converters/wire/src/main/java/retrofit/WireResponseBodyConverter.java
index 13530a9adf..8dce25081c 100644
--- a/retrofit-converters/wire/src/main/java/retrofit/WireResponseBodyConverter.java
+++ b/retrofit-converters/wire/src/main/java/retrofit/WireResponseBodyConverter.java
@@ -17,25 +17,24 @@
 
 import com.squareup.okhttp.ResponseBody;
 import com.squareup.wire.Message;
-import com.squareup.wire.Wire;
+import com.squareup.wire.ProtoAdapter;
 import java.io.IOException;
 import okio.BufferedSource;
 
-final class WireResponseBodyConverter<T extends Message> implements Converter<ResponseBody, T> {
-  private final Wire wire;
-  private final Class<T> cls;
+final class WireResponseBodyConverter<T extends Message<T, ?>>
+    implements Converter<ResponseBody, T> {
+  private final ProtoAdapter<T> adapter;
 
-  WireResponseBodyConverter(Wire wire, Class<T> cls) {
-    this.wire = wire;
-    this.cls = cls;
+  WireResponseBodyConverter(ProtoAdapter<T> adapter) {
+    this.adapter = adapter;
   }
 
   @Override public T convert(ResponseBody value) throws IOException {
-    BufferedSource source = value.source();
     try {
-      return wire.parseFrom(source, cls);
+      BufferedSource source = value.source();
+      return adapter.decode(source);
     } finally {
-      Utils.closeQuietly(source);
+      Utils.closeQuietly(value);
     }
   }
 }


Test patch:
diff --git a/retrofit-converters/wire/src/test/java/retrofit/Phone.java b/retrofit-converters/wire/src/test/java/retrofit/Phone.java
index e8a47989d8..ab0a73683f 100644
--- a/retrofit-converters/wire/src/test/java/retrofit/Phone.java
+++ b/retrofit-converters/wire/src/test/java/retrofit/Phone.java
@@ -1,27 +1,80 @@
 // Code generated by Wire protocol buffer compiler, do not edit.
-// Source file: ../wire-runtime/src/test/proto/person.proto
+// Source file: test.proto at 2:1
 package retrofit;
 
+import com.squareup.wire.FieldEncoding;
 import com.squareup.wire.Message;
-import com.squareup.wire.ProtoField;
+import com.squareup.wire.ProtoAdapter;
+import com.squareup.wire.ProtoReader;
+import com.squareup.wire.ProtoWriter;
+import java.io.IOException;
+import java.lang.Object;
+import java.lang.Override;
+import java.lang.String;
+import java.lang.StringBuilder;
+import okio.ByteString;
 
-import static com.squareup.wire.Message.Datatype.STRING;
-import static com.squareup.wire.Message.Label.OPTIONAL;
+public final class Phone extends Message<Phone, Phone.Builder> {
+  public static final ProtoAdapter<Phone> ADAPTER = new ProtoAdapter<Phone>(FieldEncoding.LENGTH_DELIMITED, Phone.class) {
+    @Override
+    public int encodedSize(Phone value) {
+      return (value.number != null ? ProtoAdapter.STRING.encodedSizeWithTag(1, value.number) : 0)
+          + value.unknownFields().size();
+    }
+
+    @Override
+    public void encode(ProtoWriter writer, Phone value) throws IOException {
+      if (value.number != null) ProtoAdapter.STRING.encodeWithTag(writer, 1, value.number);
+      writer.writeBytes(value.unknownFields());
+    }
+
+    @Override
+    public Phone decode(ProtoReader reader) throws IOException {
+      Builder builder = new Builder();
+      long token = reader.beginMessage();
+      for (int tag; (tag = reader.nextTag()) != -1;) {
+        switch (tag) {
+          case 1: builder.number(ProtoAdapter.STRING.decode(reader)); break;
+          default: {
+            FieldEncoding fieldEncoding = reader.peekFieldEncoding();
+            Object value = fieldEncoding.rawProtoAdapter().decode(reader);
+            builder.addUnknownField(tag, fieldEncoding, value);
+          }
+        }
+      }
+      reader.endMessage(token);
+      return builder.build();
+    }
+
+    @Override
+    public Phone redact(Phone value) {
+      Builder builder = value.newBuilder();
+      builder.clearUnknownFields();
+      return builder.build();
+    }
+  };
 
-public final class Phone extends Message {
+  private static final long serialVersionUID = 0L;
 
-  public static final String DEFAULT_PHONE = "";
+  public static final String DEFAULT_NUMBER = "";
 
-  @ProtoField(tag = 1, type = STRING, label = OPTIONAL)
   public final String number;
 
   public Phone(String number) {
+    this(number, ByteString.EMPTY);
+  }
+
+  public Phone(String number, ByteString unknownFields) {
+    super(unknownFields);
     this.number = number;
   }
 
-  private Phone(Builder builder) {
-    this(builder.number);
-    setBuilder(builder);
+  @Override
+  public Builder newBuilder() {
+    Builder builder = new Builder();
+    builder.number = number;
+    builder.addUnknownFields(unknownFields());
+    return builder;
   }
 
   @Override
@@ -29,41 +82,42 @@ public boolean equals(Object other) {
     if (other == this) return true;
     if (!(other instanceof Phone)) return false;
     Phone o = (Phone) other;
-    return equals(number, o.number);
+    return equals(unknownFields(), o.unknownFields())
+        && equals(number, o.number);
   }
 
   @Override
   public int hashCode() {
-    int result = hashCode;
+    int result = super.hashCode;
     if (result == 0) {
-      result = number != null ? number.hashCode() : 0;
-      hashCode = result;
+      result = unknownFields().hashCode();
+      result = result * 37 + (number != null ? number.hashCode() : 0);
+      super.hashCode = result;
     }
     return result;
   }
 
-  public static final class Builder extends Message.Builder<Phone> {
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    if (number != null) builder.append(", number=").append(number);
+    return builder.replace(0, 2, "Phone{").append('}').toString();
+  }
 
+  public static final class Builder extends com.squareup.wire.Message.Builder<Phone, Builder> {
     public String number;
 
     public Builder() {
     }
 
-    public Builder(Phone message) {
-      super(message);
-      if (message == null) return;
-      this.number = message.number;
-    }
-
-    public Builder number(String name) {
-      this.number = name;
+    public Builder number(String number) {
+      this.number = number;
       return this;
     }
 
     @Override
     public Phone build() {
-      checkRequiredFields();
-      return new Phone(this);
+      return new Phone(number, buildUnknownFields());
     }
   }
 }