@Override
 public void fromGson(JsonElement json, Gson gson, RawStringData raw) throws GsonException {
   reset();
   JsonObject jsonObject = json.getAsJsonObject();
   // NOTE: always check with has(...) as the json might not have all required
   // fields set.
   if (jsonObject.has("1")) {
     setDocumentId(jsonObject.get("1").getAsString());
   }
   if (jsonObject.has("2")) {
     ProtocolDocumentOperationGsonImpl payload = new ProtocolDocumentOperationGsonImpl();
     GsonUtil.extractJsonObject(payload, jsonObject.get("2"), gson, raw);
     setDocumentOperation(payload);
   }
   if (jsonObject.has("3")) {
     setAuthor(jsonObject.get("3").getAsString());
   }
   if (jsonObject.has("4")) {
     JsonArray array = jsonObject.get("4").getAsJsonArray();
     for (int i = 0; i < array.size(); i++) {
       addContributor(array.get(i).getAsString());
     }
   }
   if (jsonObject.has("5")) {
     setLastModifiedVersion(GsonUtil.fromJson(jsonObject.get("5")));
   }
   if (jsonObject.has("6")) {
     setLastModifiedTime(GsonUtil.fromJson(jsonObject.get("6")));
   }
 }
 /**
  * Static implementation-independent GSON serializer. Call this from {@link #toGson} to avoid
  * subclassing issues with inner message types.
  */
 public static JsonElement toGsonHelper(DocumentSnapshot message, RawStringData raw, Gson gson) {
   JsonObject json = new JsonObject();
   json.add("1", new JsonPrimitive(message.getDocumentId()));
   json.add(
       "2",
       ProtocolDocumentOperationGsonImpl.toGsonHelper(message.getDocumentOperation(), raw, gson));
   json.add("3", new JsonPrimitive(message.getAuthor()));
   {
     JsonArray array = new JsonArray();
     for (int i = 0; i < message.getContributorSize(); i++) {
       array.add(new JsonPrimitive(message.getContributor(i)));
     }
     json.add("4", array);
   }
   json.add("5", GsonUtil.toJson(message.getLastModifiedVersion()));
   json.add("6", GsonUtil.toJson(message.getLastModifiedTime()));
   return json;
 }
 @Override
 public void fromGson(JsonElement json, Gson gson, RawStringData raw) throws GsonException {
   reset();
   JsonObject jsonObject = json.getAsJsonObject();
   // NOTE: always check with has(...) as the json might not have all required
   // fields set.
   if (jsonObject.has("1")) {
     ResponseStatusGsonImpl payload = new ResponseStatusGsonImpl();
     GsonUtil.extractJsonObject(payload, jsonObject.get("1"), gson, raw);
     setStatus(payload);
   }
   if (jsonObject.has("2")) {
     JsonArray array = jsonObject.get("2").getAsJsonArray();
     for (int i = 0; i < array.size(); i++) {
       WaveletDiffGsonImpl payload = new WaveletDiffGsonImpl();
       GsonUtil.extractJsonObject(payload, array.get(i), gson, raw);
       addWavelet(payload);
     }
   }
 }
 @Override
 public void fromGson(JsonElement json, Gson gson, RawStringData raw) throws GsonException {
   reset();
   JsonObject jsonObject = json.getAsJsonObject();
   // NOTE: always check with has(...) as the json might not have all required
   // fields set.
   if (jsonObject.has("1")) {
     setWaveletId(jsonObject.get("1").getAsString());
   }
   if (jsonObject.has("2")) {
     JsonElement elem = jsonObject.get("2");
     if (!elem.isJsonNull()) {
       WaveletDiffSnapshotGsonImpl payload = new WaveletDiffSnapshotGsonImpl();
       GsonUtil.extractJsonObject(payload, elem, gson, raw);
       setSnapshot(payload);
     }
   }
 }