title: How To Deserialize Generic Types with Moshi?
body: <p>Suppose we have this JSON:</p>
  
  <pre><code>[
    {
      "__typename": "Car",
      "id": "123",
      "name": "Toyota Prius",
      "numDoors": 4
    },
    {
      "__typename": "Boat",
      "id": "4567",
      "name": "U.S.S. Constitution",
      "propulsion": "SAIL"
    }
  ]
  </code></pre>
  
  <p>(there could be many more elements to the list; this just shows two)</p>
  
  <p>I have <code>Car</code> and <code>Boat</code> POJOs that use a <code>Vehicle</code> base class for the common fields:</p>
  
  <pre><code>public abstract class Vehicle {
    public final String id;
    public final String name;
  }
  
  public class Car extends Vehicle {
    public final Integer numDoors;
  }
  
  public class Boat extends Vehicle {
    public final String propulsion;
  }
  </code></pre>
  
  <p>The result of parsing this JSON should be a <code>List&lt;Vehicle&gt;</code>. The problem is that no JSON parser is going to know, out of the box, that <code>__typename</code> is how to distinguish a <code>Boat</code> from a <code>Car</code>.</p>
  
  <p>With Gson, I can create a <code>JsonDeserializer&lt;Vehicle&gt;</code> that can examine the <code>__typename</code> field, identify whether this is a <code>Car</code> or <code>Boat</code>, then use <code>deserialize()</code> on the supplied <code>JsonDeserializationContext</code> to parse the particular JSON object into the appropriate type. This works fine.</p>
  
  <p>However, the particular thing that I am building ought to support pluggable JSON parsers, and I thought that I would try Moshi as an alternative parser. However, this particular problem is not covered well in the Moshi documentation at the present time, and I am having difficulty figuring out how best to address it.</p>
  
  <p>The closest analogue to <code>JsonDeserializer&lt;T&gt;</code> <a href="http://square.github.io/moshi/1.x/moshi/com/squareup/moshi/JsonAdapter.html" rel="noreferrer">is <code>JsonAdapter&lt;T&gt;</code></a>. However, <code>fromJson()</code> gets passed a <code>JsonReader</code>, which has a destructive API. To find out what the <code>__typename</code> is, I would have to be able to parse everything by hand from the <code>JsonReader</code> events. While I could call <a href="http://square.github.io/moshi/1.x/moshi/com/squareup/moshi/Moshi.html#adapter-java.lang.reflect.Type-" rel="noreferrer"><code>adapter()</code> on the <code>Moshi</code> instance</a> to try to invoke existing Moshi parsing logic once I know the proper concrete type, I will have consumed data off of the <code>JsonReader</code> and broken its ability to provide the complete object description anymore.</p>
  
  <p>Another analogue of <code>JsonDeserializer&lt;Vehicle&gt;</code> would be a <a href="https://github.com/square/moshi#another-example" rel="noreferrer"><code>@FromJson</code>-annotated method</a> that returns a <code>Vehicle</code>. However, I cannot identify a simple thing to pass into the method. The only thing that I can think of is to create yet another POJO representing the union of all possible fields:</p>
  
  <pre><code>public class SemiParsedKindOfVehicle {
    public final String id;
    public final String name;
    public final Integer numDoors;
    public final String propulsion;
    public final String __typename;
  }
  </code></pre>
  
  <p>Then, in theory, if I have <code>@FromJson Vehicle rideLikeTheWind(SemiParsedKindOfVehicle rawVehicle)</code> on a class that I register as a type adapter with <code>Moshi</code>, Moshi might be able to parse my JSON objects into <code>SemiParsedKindOfVehicle</code> instances and call <code>rideLikeTheWind()</code>. In there, I would look up the <code>__typename</code>, identify the type, and completely build the <code>Car</code> or <code>Boat</code> myself, returning that object.</p>
  
  <p>While doable, this is a fair bit more complex than the Gson approach, and my <code>Car</code>/<code>Boat</code> scenario is on the simple end of the possible data structures that I will need to deal with.</p>
  
  <p>Is there another approach to handling this with Moshi that I am missing?</p>