private T getManifestTemplateFromJson(String jsonString)
      throws IOException, UnknownManifestFormatException {
    ObjectNode node = new ObjectMapper().readValue(jsonString, ObjectNode.class);
    if (!node.has("schemaVersion")) {
      throw new UnknownManifestFormatException("Cannot find field 'schemaVersion' in manifest");
    }

    int schemaVersion = node.get("schemaVersion").asInt(-1);
    if (schemaVersion == -1) {
      throw new UnknownManifestFormatException("'schemaVersion' field is not an integer");
    }

    if (schemaVersion == 1) {
      return manifestTemplateClass.cast(
          JsonTemplateMapper.readJson(jsonString, V21ManifestTemplate.class));
    }
    if (schemaVersion == 2) {
      // 'schemaVersion' of 2 can be either Docker V2.2 or OCI.
      JsonNode mediaTypeNode = node.get("mediaType");
      if (mediaTypeNode == null) { // not Docker, hence OCI
        if (node.get("manifests") != null) {
          return manifestTemplateClass.cast(
              JsonTemplateMapper.readJson(jsonString, OciIndexTemplate.class));
        }
        if (node.get("config") != null) {
          return manifestTemplateClass.cast(
              JsonTemplateMapper.readJson(jsonString, OciManifestTemplate.class));
        }
        throw new UnknownManifestFormatException(
            "'schemaVersion' is 2, but neither 'manifests' nor 'config' exists");
      }

      String mediaType = mediaTypeNode.asText();
      if (OciManifestTemplate.MANIFEST_MEDIA_TYPE.equals(mediaType)) {
        return manifestTemplateClass.cast(
            JsonTemplateMapper.readJson(jsonString, OciManifestTemplate.class));
      }
      if (V22ManifestTemplate.MANIFEST_MEDIA_TYPE.equals(mediaType)) {
        return manifestTemplateClass.cast(
            JsonTemplateMapper.readJson(jsonString, V22ManifestTemplate.class));
      }
      if (V22ManifestListTemplate.MANIFEST_MEDIA_TYPE.equals(mediaType)) {
        return manifestTemplateClass.cast(
            JsonTemplateMapper.readJson(jsonString, V22ManifestListTemplate.class));
      }
      if (OciIndexTemplate.MEDIA_TYPE.equals(mediaType)) {
        return manifestTemplateClass.cast(
            JsonTemplateMapper.readJson(jsonString, OciIndexTemplate.class));
      }
      throw new UnknownManifestFormatException("Unknown mediaType: " + mediaType);
    }
    throw new UnknownManifestFormatException(
        "Unknown schemaVersion: " + schemaVersion + " - only 1 and 2 are supported");
  }
Instantiates a {@link ManifestTemplate} from a JSON string. This checks the {@code
schemaVersion} field of the JSON to determine which manifest version to use.
jib-core/src/main/java/com/google/cloud/tools/jib/registry/AbstractManifestPuller.java