/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Autogenerated by Thrift Compiler (0.18.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.model.appcatalog.parser;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.18.1)")
public class ParsingTemplate implements org.apache.thrift.TBase<ParsingTemplate, ParsingTemplate._Fields>, java.io.Serializable, Cloneable, Comparable<ParsingTemplate> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ParsingTemplate");

  private static final org.apache.thrift.protocol.TField ID_FIELD_DESC = new org.apache.thrift.protocol.TField("id", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField APPLICATION_INTERFACE_FIELD_DESC = new org.apache.thrift.protocol.TField("applicationInterface", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField INITIAL_INPUTS_FIELD_DESC = new org.apache.thrift.protocol.TField("initialInputs", org.apache.thrift.protocol.TType.LIST, (short)3);
  private static final org.apache.thrift.protocol.TField PARSER_CONNECTIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("parserConnections", org.apache.thrift.protocol.TType.LIST, (short)4);
  private static final org.apache.thrift.protocol.TField GATEWAY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("gatewayId", org.apache.thrift.protocol.TType.STRING, (short)5);

  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ParsingTemplateStandardSchemeFactory();
  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ParsingTemplateTupleSchemeFactory();

  private @org.apache.thrift.annotation.Nullable java.lang.String id; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String applicationInterface; // required
  private @org.apache.thrift.annotation.Nullable java.util.List<ParsingTemplateInput> initialInputs; // required
  private @org.apache.thrift.annotation.Nullable java.util.List<ParserConnector> parserConnections; // required
  private @org.apache.thrift.annotation.Nullable java.lang.String gatewayId; // required

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    ID((short)1, "id"),
    APPLICATION_INTERFACE((short)2, "applicationInterface"),
    INITIAL_INPUTS((short)3, "initialInputs"),
    PARSER_CONNECTIONS((short)4, "parserConnections"),
    GATEWAY_ID((short)5, "gatewayId");

    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

    static {
      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
        byName.put(field.getFieldName(), field);
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // ID
          return ID;
        case 2: // APPLICATION_INTERFACE
          return APPLICATION_INTERFACE;
        case 3: // INITIAL_INPUTS
          return INITIAL_INPUTS;
        case 4: // PARSER_CONNECTIONS
          return PARSER_CONNECTIONS;
        case 5: // GATEWAY_ID
          return GATEWAY_ID;
        default:
          return null;
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, throwing an exception
     * if it is not found.
     */
    public static _Fields findByThriftIdOrThrow(int fieldId) {
      _Fields fields = findByThriftId(fieldId);
      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByName(java.lang.String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final java.lang.String _fieldName;

    _Fields(short thriftId, java.lang.String fieldName) {
      _thriftId = thriftId;
      _fieldName = fieldName;
    }

    @Override
    public short getThriftFieldId() {
      return _thriftId;
    }

    @Override
    public java.lang.String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.ID, new org.apache.thrift.meta_data.FieldMetaData("id", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.APPLICATION_INTERFACE, new org.apache.thrift.meta_data.FieldMetaData("applicationInterface", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.INITIAL_INPUTS, new org.apache.thrift.meta_data.FieldMetaData("initialInputs", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ParsingTemplateInput.class))));
    tmpMap.put(_Fields.PARSER_CONNECTIONS, new org.apache.thrift.meta_data.FieldMetaData("parserConnections", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ParserConnector.class))));
    tmpMap.put(_Fields.GATEWAY_ID, new org.apache.thrift.meta_data.FieldMetaData("gatewayId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ParsingTemplate.class, metaDataMap);
  }

  public ParsingTemplate() {
  }

  public ParsingTemplate(
    java.lang.String id,
    java.lang.String applicationInterface,
    java.util.List<ParsingTemplateInput> initialInputs,
    java.util.List<ParserConnector> parserConnections,
    java.lang.String gatewayId)
  {
    this();
    this.id = id;
    this.applicationInterface = applicationInterface;
    this.initialInputs = initialInputs;
    this.parserConnections = parserConnections;
    this.gatewayId = gatewayId;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public ParsingTemplate(ParsingTemplate other) {
    if (other.isSetId()) {
      this.id = other.id;
    }
    if (other.isSetApplicationInterface()) {
      this.applicationInterface = other.applicationInterface;
    }
    if (other.isSetInitialInputs()) {
      java.util.List<ParsingTemplateInput> __this__initialInputs = new java.util.ArrayList<ParsingTemplateInput>(other.initialInputs.size());
      for (ParsingTemplateInput other_element : other.initialInputs) {
        __this__initialInputs.add(new ParsingTemplateInput(other_element));
      }
      this.initialInputs = __this__initialInputs;
    }
    if (other.isSetParserConnections()) {
      java.util.List<ParserConnector> __this__parserConnections = new java.util.ArrayList<ParserConnector>(other.parserConnections.size());
      for (ParserConnector other_element : other.parserConnections) {
        __this__parserConnections.add(new ParserConnector(other_element));
      }
      this.parserConnections = __this__parserConnections;
    }
    if (other.isSetGatewayId()) {
      this.gatewayId = other.gatewayId;
    }
  }

  @Override
  public ParsingTemplate deepCopy() {
    return new ParsingTemplate(this);
  }

  @Override
  public void clear() {
    this.id = null;
    this.applicationInterface = null;
    this.initialInputs = null;
    this.parserConnections = null;
    this.gatewayId = null;
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getId() {
    return this.id;
  }

  public void setId(@org.apache.thrift.annotation.Nullable java.lang.String id) {
    this.id = id;
  }

  public void unsetId() {
    this.id = null;
  }

  /** Returns true if field id is set (has been assigned a value) and false otherwise */
  public boolean isSetId() {
    return this.id != null;
  }

  public void setIdIsSet(boolean value) {
    if (!value) {
      this.id = null;
    }
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getApplicationInterface() {
    return this.applicationInterface;
  }

  public void setApplicationInterface(@org.apache.thrift.annotation.Nullable java.lang.String applicationInterface) {
    this.applicationInterface = applicationInterface;
  }

  public void unsetApplicationInterface() {
    this.applicationInterface = null;
  }

  /** Returns true if field applicationInterface is set (has been assigned a value) and false otherwise */
  public boolean isSetApplicationInterface() {
    return this.applicationInterface != null;
  }

  public void setApplicationInterfaceIsSet(boolean value) {
    if (!value) {
      this.applicationInterface = null;
    }
  }

  public int getInitialInputsSize() {
    return (this.initialInputs == null) ? 0 : this.initialInputs.size();
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<ParsingTemplateInput> getInitialInputsIterator() {
    return (this.initialInputs == null) ? null : this.initialInputs.iterator();
  }

  public void addToInitialInputs(ParsingTemplateInput elem) {
    if (this.initialInputs == null) {
      this.initialInputs = new java.util.ArrayList<ParsingTemplateInput>();
    }
    this.initialInputs.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<ParsingTemplateInput> getInitialInputs() {
    return this.initialInputs;
  }

  public void setInitialInputs(@org.apache.thrift.annotation.Nullable java.util.List<ParsingTemplateInput> initialInputs) {
    this.initialInputs = initialInputs;
  }

  public void unsetInitialInputs() {
    this.initialInputs = null;
  }

  /** Returns true if field initialInputs is set (has been assigned a value) and false otherwise */
  public boolean isSetInitialInputs() {
    return this.initialInputs != null;
  }

  public void setInitialInputsIsSet(boolean value) {
    if (!value) {
      this.initialInputs = null;
    }
  }

  public int getParserConnectionsSize() {
    return (this.parserConnections == null) ? 0 : this.parserConnections.size();
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<ParserConnector> getParserConnectionsIterator() {
    return (this.parserConnections == null) ? null : this.parserConnections.iterator();
  }

  public void addToParserConnections(ParserConnector elem) {
    if (this.parserConnections == null) {
      this.parserConnections = new java.util.ArrayList<ParserConnector>();
    }
    this.parserConnections.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<ParserConnector> getParserConnections() {
    return this.parserConnections;
  }

  public void setParserConnections(@org.apache.thrift.annotation.Nullable java.util.List<ParserConnector> parserConnections) {
    this.parserConnections = parserConnections;
  }

  public void unsetParserConnections() {
    this.parserConnections = null;
  }

  /** Returns true if field parserConnections is set (has been assigned a value) and false otherwise */
  public boolean isSetParserConnections() {
    return this.parserConnections != null;
  }

  public void setParserConnectionsIsSet(boolean value) {
    if (!value) {
      this.parserConnections = null;
    }
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getGatewayId() {
    return this.gatewayId;
  }

  public void setGatewayId(@org.apache.thrift.annotation.Nullable java.lang.String gatewayId) {
    this.gatewayId = gatewayId;
  }

  public void unsetGatewayId() {
    this.gatewayId = null;
  }

  /** Returns true if field gatewayId is set (has been assigned a value) and false otherwise */
  public boolean isSetGatewayId() {
    return this.gatewayId != null;
  }

  public void setGatewayIdIsSet(boolean value) {
    if (!value) {
      this.gatewayId = null;
    }
  }

  @Override
  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case ID:
      if (value == null) {
        unsetId();
      } else {
        setId((java.lang.String)value);
      }
      break;

    case APPLICATION_INTERFACE:
      if (value == null) {
        unsetApplicationInterface();
      } else {
        setApplicationInterface((java.lang.String)value);
      }
      break;

    case INITIAL_INPUTS:
      if (value == null) {
        unsetInitialInputs();
      } else {
        setInitialInputs((java.util.List<ParsingTemplateInput>)value);
      }
      break;

    case PARSER_CONNECTIONS:
      if (value == null) {
        unsetParserConnections();
      } else {
        setParserConnections((java.util.List<ParserConnector>)value);
      }
      break;

    case GATEWAY_ID:
      if (value == null) {
        unsetGatewayId();
      } else {
        setGatewayId((java.lang.String)value);
      }
      break;

    }
  }

  @org.apache.thrift.annotation.Nullable
  @Override
  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case ID:
      return getId();

    case APPLICATION_INTERFACE:
      return getApplicationInterface();

    case INITIAL_INPUTS:
      return getInitialInputs();

    case PARSER_CONNECTIONS:
      return getParserConnections();

    case GATEWAY_ID:
      return getGatewayId();

    }
    throw new java.lang.IllegalStateException();
  }

  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
  @Override
  public boolean isSet(_Fields field) {
    if (field == null) {
      throw new java.lang.IllegalArgumentException();
    }

    switch (field) {
    case ID:
      return isSetId();
    case APPLICATION_INTERFACE:
      return isSetApplicationInterface();
    case INITIAL_INPUTS:
      return isSetInitialInputs();
    case PARSER_CONNECTIONS:
      return isSetParserConnections();
    case GATEWAY_ID:
      return isSetGatewayId();
    }
    throw new java.lang.IllegalStateException();
  }

  @Override
  public boolean equals(java.lang.Object that) {
    if (that instanceof ParsingTemplate)
      return this.equals((ParsingTemplate)that);
    return false;
  }

  public boolean equals(ParsingTemplate that) {
    if (that == null)
      return false;
    if (this == that)
      return true;

    boolean this_present_id = true && this.isSetId();
    boolean that_present_id = true && that.isSetId();
    if (this_present_id || that_present_id) {
      if (!(this_present_id && that_present_id))
        return false;
      if (!this.id.equals(that.id))
        return false;
    }

    boolean this_present_applicationInterface = true && this.isSetApplicationInterface();
    boolean that_present_applicationInterface = true && that.isSetApplicationInterface();
    if (this_present_applicationInterface || that_present_applicationInterface) {
      if (!(this_present_applicationInterface && that_present_applicationInterface))
        return false;
      if (!this.applicationInterface.equals(that.applicationInterface))
        return false;
    }

    boolean this_present_initialInputs = true && this.isSetInitialInputs();
    boolean that_present_initialInputs = true && that.isSetInitialInputs();
    if (this_present_initialInputs || that_present_initialInputs) {
      if (!(this_present_initialInputs && that_present_initialInputs))
        return false;
      if (!this.initialInputs.equals(that.initialInputs))
        return false;
    }

    boolean this_present_parserConnections = true && this.isSetParserConnections();
    boolean that_present_parserConnections = true && that.isSetParserConnections();
    if (this_present_parserConnections || that_present_parserConnections) {
      if (!(this_present_parserConnections && that_present_parserConnections))
        return false;
      if (!this.parserConnections.equals(that.parserConnections))
        return false;
    }

    boolean this_present_gatewayId = true && this.isSetGatewayId();
    boolean that_present_gatewayId = true && that.isSetGatewayId();
    if (this_present_gatewayId || that_present_gatewayId) {
      if (!(this_present_gatewayId && that_present_gatewayId))
        return false;
      if (!this.gatewayId.equals(that.gatewayId))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    int hashCode = 1;

    hashCode = hashCode * 8191 + ((isSetId()) ? 131071 : 524287);
    if (isSetId())
      hashCode = hashCode * 8191 + id.hashCode();

    hashCode = hashCode * 8191 + ((isSetApplicationInterface()) ? 131071 : 524287);
    if (isSetApplicationInterface())
      hashCode = hashCode * 8191 + applicationInterface.hashCode();

    hashCode = hashCode * 8191 + ((isSetInitialInputs()) ? 131071 : 524287);
    if (isSetInitialInputs())
      hashCode = hashCode * 8191 + initialInputs.hashCode();

    hashCode = hashCode * 8191 + ((isSetParserConnections()) ? 131071 : 524287);
    if (isSetParserConnections())
      hashCode = hashCode * 8191 + parserConnections.hashCode();

    hashCode = hashCode * 8191 + ((isSetGatewayId()) ? 131071 : 524287);
    if (isSetGatewayId())
      hashCode = hashCode * 8191 + gatewayId.hashCode();

    return hashCode;
  }

  @Override
  public int compareTo(ParsingTemplate other) {
    if (!getClass().equals(other.getClass())) {
      return getClass().getName().compareTo(other.getClass().getName());
    }

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.compare(isSetId(), other.isSetId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.id, other.id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetApplicationInterface(), other.isSetApplicationInterface());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetApplicationInterface()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.applicationInterface, other.applicationInterface);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetInitialInputs(), other.isSetInitialInputs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetInitialInputs()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.initialInputs, other.initialInputs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetParserConnections(), other.isSetParserConnections());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetParserConnections()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parserConnections, other.parserConnections);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetGatewayId(), other.isSetGatewayId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGatewayId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.gatewayId, other.gatewayId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  @org.apache.thrift.annotation.Nullable
  @Override
  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  @Override
  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    scheme(iprot).read(iprot, this);
  }

  @Override
  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    scheme(oprot).write(oprot, this);
  }

  @Override
  public java.lang.String toString() {
    java.lang.StringBuilder sb = new java.lang.StringBuilder("ParsingTemplate(");
    boolean first = true;

    sb.append("id:");
    if (this.id == null) {
      sb.append("null");
    } else {
      sb.append(this.id);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("applicationInterface:");
    if (this.applicationInterface == null) {
      sb.append("null");
    } else {
      sb.append(this.applicationInterface);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("initialInputs:");
    if (this.initialInputs == null) {
      sb.append("null");
    } else {
      sb.append(this.initialInputs);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("parserConnections:");
    if (this.parserConnections == null) {
      sb.append("null");
    } else {
      sb.append(this.parserConnections);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("gatewayId:");
    if (this.gatewayId == null) {
      sb.append("null");
    } else {
      sb.append(this.gatewayId);
    }
    first = false;
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    if (!isSetId()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'id' is unset! Struct:" + toString());
    }

    if (!isSetApplicationInterface()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'applicationInterface' is unset! Struct:" + toString());
    }

    if (!isSetInitialInputs()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'initialInputs' is unset! Struct:" + toString());
    }

    if (!isSetParserConnections()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'parserConnections' is unset! Struct:" + toString());
    }

    if (!isSetGatewayId()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'gatewayId' is unset! Struct:" + toString());
    }

    // check for sub-struct validity
  }

  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    try {
      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
    try {
      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class ParsingTemplateStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    @Override
    public ParsingTemplateStandardScheme getScheme() {
      return new ParsingTemplateStandardScheme();
    }
  }

  private static class ParsingTemplateStandardScheme extends org.apache.thrift.scheme.StandardScheme<ParsingTemplate> {

    @Override
    public void read(org.apache.thrift.protocol.TProtocol iprot, ParsingTemplate struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.id = iprot.readString();
              struct.setIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // APPLICATION_INTERFACE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.applicationInterface = iprot.readString();
              struct.setApplicationInterfaceIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // INITIAL_INPUTS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list24 = iprot.readListBegin();
                struct.initialInputs = new java.util.ArrayList<ParsingTemplateInput>(_list24.size);
                @org.apache.thrift.annotation.Nullable ParsingTemplateInput _elem25;
                for (int _i26 = 0; _i26 < _list24.size; ++_i26)
                {
                  _elem25 = new ParsingTemplateInput();
                  _elem25.read(iprot);
                  struct.initialInputs.add(_elem25);
                }
                iprot.readListEnd();
              }
              struct.setInitialInputsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // PARSER_CONNECTIONS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list27 = iprot.readListBegin();
                struct.parserConnections = new java.util.ArrayList<ParserConnector>(_list27.size);
                @org.apache.thrift.annotation.Nullable ParserConnector _elem28;
                for (int _i29 = 0; _i29 < _list27.size; ++_i29)
                {
                  _elem28 = new ParserConnector();
                  _elem28.read(iprot);
                  struct.parserConnections.add(_elem28);
                }
                iprot.readListEnd();
              }
              struct.setParserConnectionsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // GATEWAY_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.gatewayId = iprot.readString();
              struct.setGatewayIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

    @Override
    public void write(org.apache.thrift.protocol.TProtocol oprot, ParsingTemplate struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.id != null) {
        oprot.writeFieldBegin(ID_FIELD_DESC);
        oprot.writeString(struct.id);
        oprot.writeFieldEnd();
      }
      if (struct.applicationInterface != null) {
        oprot.writeFieldBegin(APPLICATION_INTERFACE_FIELD_DESC);
        oprot.writeString(struct.applicationInterface);
        oprot.writeFieldEnd();
      }
      if (struct.initialInputs != null) {
        oprot.writeFieldBegin(INITIAL_INPUTS_FIELD_DESC);
        {
          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.initialInputs.size()));
          for (ParsingTemplateInput _iter30 : struct.initialInputs)
          {
            _iter30.write(oprot);
          }
          oprot.writeListEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.parserConnections != null) {
        oprot.writeFieldBegin(PARSER_CONNECTIONS_FIELD_DESC);
        {
          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.parserConnections.size()));
          for (ParserConnector _iter31 : struct.parserConnections)
          {
            _iter31.write(oprot);
          }
          oprot.writeListEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.gatewayId != null) {
        oprot.writeFieldBegin(GATEWAY_ID_FIELD_DESC);
        oprot.writeString(struct.gatewayId);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class ParsingTemplateTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    @Override
    public ParsingTemplateTupleScheme getScheme() {
      return new ParsingTemplateTupleScheme();
    }
  }

  private static class ParsingTemplateTupleScheme extends org.apache.thrift.scheme.TupleScheme<ParsingTemplate> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ParsingTemplate struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.id);
      oprot.writeString(struct.applicationInterface);
      {
        oprot.writeI32(struct.initialInputs.size());
        for (ParsingTemplateInput _iter32 : struct.initialInputs)
        {
          _iter32.write(oprot);
        }
      }
      {
        oprot.writeI32(struct.parserConnections.size());
        for (ParserConnector _iter33 : struct.parserConnections)
        {
          _iter33.write(oprot);
        }
      }
      oprot.writeString(struct.gatewayId);
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ParsingTemplate struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.id = iprot.readString();
      struct.setIdIsSet(true);
      struct.applicationInterface = iprot.readString();
      struct.setApplicationInterfaceIsSet(true);
      {
        org.apache.thrift.protocol.TList _list34 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
        struct.initialInputs = new java.util.ArrayList<ParsingTemplateInput>(_list34.size);
        @org.apache.thrift.annotation.Nullable ParsingTemplateInput _elem35;
        for (int _i36 = 0; _i36 < _list34.size; ++_i36)
        {
          _elem35 = new ParsingTemplateInput();
          _elem35.read(iprot);
          struct.initialInputs.add(_elem35);
        }
      }
      struct.setInitialInputsIsSet(true);
      {
        org.apache.thrift.protocol.TList _list37 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
        struct.parserConnections = new java.util.ArrayList<ParserConnector>(_list37.size);
        @org.apache.thrift.annotation.Nullable ParserConnector _elem38;
        for (int _i39 = 0; _i39 < _list37.size; ++_i39)
        {
          _elem38 = new ParserConnector();
          _elem38.read(iprot);
          struct.parserConnections.add(_elem38);
        }
      }
      struct.setParserConnectionsIsSet(true);
      struct.gatewayId = iprot.readString();
      struct.setGatewayIdIsSet(true);
    }
  }

  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
  }
}

