public static @Nullable <T> T readOne(JsonReaderAdapter<T> adapter, ReadBuffer buffer) {
    List<T> out = new ArrayList<>(1); // TODO: could make single-element list w/o array
    if (!read(adapter, buffer, out)) return null;
    return out.get(0);
  }
This explicitly constructs instances of model classes via manual parsing for a number of
reasons.

<ul>
  <li>Eliminates the need to keep separate model classes for proto3 vs json
  <li>Avoids magic field initialization which, can miss constructor guards
  <li>Allows us to safely re-use the json form in toString methods
  <li>Encourages logic to be based on the json shape of objects
  <li>Ensures the order and naming of the fields in json is stable
</ul>

<p>There is the up-front cost of creating this, and maintenance of this to consider. However,
this should be easy to justify as these objects don't change much at all.
zipkin/src/main/java/zipkin2/internal/JsonCodec.java