/**
 * 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.10.0)
 *
 * 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.10.0)")
public class Parser implements org.apache.thrift.TBase<Parser, Parser._Fields>, java.io.Serializable, Cloneable, Comparable<Parser> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Parser");

  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 IMAGE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("imageName", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField OUTPUT_DIR_PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("outputDirPath", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField INPUT_DIR_PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("inputDirPath", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField EXECUTION_COMMAND_FIELD_DESC = new org.apache.thrift.protocol.TField("executionCommand", org.apache.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.thrift.protocol.TField INPUT_FILES_FIELD_DESC = new org.apache.thrift.protocol.TField("inputFiles", org.apache.thrift.protocol.TType.LIST, (short)6);
  private static final org.apache.thrift.protocol.TField OUTPUT_FILES_FIELD_DESC = new org.apache.thrift.protocol.TField("outputFiles", org.apache.thrift.protocol.TType.LIST, (short)7);
  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)8);

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

  private java.lang.String id; // required
  private java.lang.String imageName; // required
  private java.lang.String outputDirPath; // required
  private java.lang.String inputDirPath; // required
  private java.lang.String executionCommand; // required
  private java.util.List<ParserInput> inputFiles; // required
  private java.util.List<ParserOutput> outputFiles; // required
  private 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"),
    IMAGE_NAME((short)2, "imageName"),
    OUTPUT_DIR_PATH((short)3, "outputDirPath"),
    INPUT_DIR_PATH((short)4, "inputDirPath"),
    EXECUTION_COMMAND((short)5, "executionCommand"),
    INPUT_FILES((short)6, "inputFiles"),
    OUTPUT_FILES((short)7, "outputFiles"),
    GATEWAY_ID((short)8, "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.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // ID
          return ID;
        case 2: // IMAGE_NAME
          return IMAGE_NAME;
        case 3: // OUTPUT_DIR_PATH
          return OUTPUT_DIR_PATH;
        case 4: // INPUT_DIR_PATH
          return INPUT_DIR_PATH;
        case 5: // EXECUTION_COMMAND
          return EXECUTION_COMMAND;
        case 6: // INPUT_FILES
          return INPUT_FILES;
        case 7: // OUTPUT_FILES
          return OUTPUT_FILES;
        case 8: // 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.
     */
    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;
    }

    public short getThriftFieldId() {
      return _thriftId;
    }

    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.IMAGE_NAME, new org.apache.thrift.meta_data.FieldMetaData("imageName", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.OUTPUT_DIR_PATH, new org.apache.thrift.meta_data.FieldMetaData("outputDirPath", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.INPUT_DIR_PATH, new org.apache.thrift.meta_data.FieldMetaData("inputDirPath", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.EXECUTION_COMMAND, new org.apache.thrift.meta_data.FieldMetaData("executionCommand", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.INPUT_FILES, new org.apache.thrift.meta_data.FieldMetaData("inputFiles", 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, ParserInput.class))));
    tmpMap.put(_Fields.OUTPUT_FILES, new org.apache.thrift.meta_data.FieldMetaData("outputFiles", 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, ParserOutput.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(Parser.class, metaDataMap);
  }

  public Parser() {
  }

  public Parser(
    java.lang.String id,
    java.lang.String imageName,
    java.lang.String outputDirPath,
    java.lang.String inputDirPath,
    java.lang.String executionCommand,
    java.util.List<ParserInput> inputFiles,
    java.util.List<ParserOutput> outputFiles,
    java.lang.String gatewayId)
  {
    this();
    this.id = id;
    this.imageName = imageName;
    this.outputDirPath = outputDirPath;
    this.inputDirPath = inputDirPath;
    this.executionCommand = executionCommand;
    this.inputFiles = inputFiles;
    this.outputFiles = outputFiles;
    this.gatewayId = gatewayId;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public Parser(Parser other) {
    if (other.isSetId()) {
      this.id = other.id;
    }
    if (other.isSetImageName()) {
      this.imageName = other.imageName;
    }
    if (other.isSetOutputDirPath()) {
      this.outputDirPath = other.outputDirPath;
    }
    if (other.isSetInputDirPath()) {
      this.inputDirPath = other.inputDirPath;
    }
    if (other.isSetExecutionCommand()) {
      this.executionCommand = other.executionCommand;
    }
    if (other.isSetInputFiles()) {
      java.util.List<ParserInput> __this__inputFiles = new java.util.ArrayList<ParserInput>(other.inputFiles.size());
      for (ParserInput other_element : other.inputFiles) {
        __this__inputFiles.add(new ParserInput(other_element));
      }
      this.inputFiles = __this__inputFiles;
    }
    if (other.isSetOutputFiles()) {
      java.util.List<ParserOutput> __this__outputFiles = new java.util.ArrayList<ParserOutput>(other.outputFiles.size());
      for (ParserOutput other_element : other.outputFiles) {
        __this__outputFiles.add(new ParserOutput(other_element));
      }
      this.outputFiles = __this__outputFiles;
    }
    if (other.isSetGatewayId()) {
      this.gatewayId = other.gatewayId;
    }
  }

  public Parser deepCopy() {
    return new Parser(this);
  }

  @Override
  public void clear() {
    this.id = null;
    this.imageName = null;
    this.outputDirPath = null;
    this.inputDirPath = null;
    this.executionCommand = null;
    this.inputFiles = null;
    this.outputFiles = null;
    this.gatewayId = null;
  }

  public java.lang.String getId() {
    return this.id;
  }

  public void setId(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;
    }
  }

  public java.lang.String getImageName() {
    return this.imageName;
  }

  public void setImageName(java.lang.String imageName) {
    this.imageName = imageName;
  }

  public void unsetImageName() {
    this.imageName = null;
  }

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

  public void setImageNameIsSet(boolean value) {
    if (!value) {
      this.imageName = null;
    }
  }

  public java.lang.String getOutputDirPath() {
    return this.outputDirPath;
  }

  public void setOutputDirPath(java.lang.String outputDirPath) {
    this.outputDirPath = outputDirPath;
  }

  public void unsetOutputDirPath() {
    this.outputDirPath = null;
  }

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

  public void setOutputDirPathIsSet(boolean value) {
    if (!value) {
      this.outputDirPath = null;
    }
  }

  public java.lang.String getInputDirPath() {
    return this.inputDirPath;
  }

  public void setInputDirPath(java.lang.String inputDirPath) {
    this.inputDirPath = inputDirPath;
  }

  public void unsetInputDirPath() {
    this.inputDirPath = null;
  }

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

  public void setInputDirPathIsSet(boolean value) {
    if (!value) {
      this.inputDirPath = null;
    }
  }

  public java.lang.String getExecutionCommand() {
    return this.executionCommand;
  }

  public void setExecutionCommand(java.lang.String executionCommand) {
    this.executionCommand = executionCommand;
  }

  public void unsetExecutionCommand() {
    this.executionCommand = null;
  }

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

  public void setExecutionCommandIsSet(boolean value) {
    if (!value) {
      this.executionCommand = null;
    }
  }

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

  public java.util.Iterator<ParserInput> getInputFilesIterator() {
    return (this.inputFiles == null) ? null : this.inputFiles.iterator();
  }

  public void addToInputFiles(ParserInput elem) {
    if (this.inputFiles == null) {
      this.inputFiles = new java.util.ArrayList<ParserInput>();
    }
    this.inputFiles.add(elem);
  }

  public java.util.List<ParserInput> getInputFiles() {
    return this.inputFiles;
  }

  public void setInputFiles(java.util.List<ParserInput> inputFiles) {
    this.inputFiles = inputFiles;
  }

  public void unsetInputFiles() {
    this.inputFiles = null;
  }

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

  public void setInputFilesIsSet(boolean value) {
    if (!value) {
      this.inputFiles = null;
    }
  }

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

  public java.util.Iterator<ParserOutput> getOutputFilesIterator() {
    return (this.outputFiles == null) ? null : this.outputFiles.iterator();
  }

  public void addToOutputFiles(ParserOutput elem) {
    if (this.outputFiles == null) {
      this.outputFiles = new java.util.ArrayList<ParserOutput>();
    }
    this.outputFiles.add(elem);
  }

  public java.util.List<ParserOutput> getOutputFiles() {
    return this.outputFiles;
  }

  public void setOutputFiles(java.util.List<ParserOutput> outputFiles) {
    this.outputFiles = outputFiles;
  }

  public void unsetOutputFiles() {
    this.outputFiles = null;
  }

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

  public void setOutputFilesIsSet(boolean value) {
    if (!value) {
      this.outputFiles = null;
    }
  }

  public java.lang.String getGatewayId() {
    return this.gatewayId;
  }

  public void setGatewayId(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;
    }
  }

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

    case IMAGE_NAME:
      if (value == null) {
        unsetImageName();
      } else {
        setImageName((java.lang.String)value);
      }
      break;

    case OUTPUT_DIR_PATH:
      if (value == null) {
        unsetOutputDirPath();
      } else {
        setOutputDirPath((java.lang.String)value);
      }
      break;

    case INPUT_DIR_PATH:
      if (value == null) {
        unsetInputDirPath();
      } else {
        setInputDirPath((java.lang.String)value);
      }
      break;

    case EXECUTION_COMMAND:
      if (value == null) {
        unsetExecutionCommand();
      } else {
        setExecutionCommand((java.lang.String)value);
      }
      break;

    case INPUT_FILES:
      if (value == null) {
        unsetInputFiles();
      } else {
        setInputFiles((java.util.List<ParserInput>)value);
      }
      break;

    case OUTPUT_FILES:
      if (value == null) {
        unsetOutputFiles();
      } else {
        setOutputFiles((java.util.List<ParserOutput>)value);
      }
      break;

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

    }
  }

  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case ID:
      return getId();

    case IMAGE_NAME:
      return getImageName();

    case OUTPUT_DIR_PATH:
      return getOutputDirPath();

    case INPUT_DIR_PATH:
      return getInputDirPath();

    case EXECUTION_COMMAND:
      return getExecutionCommand();

    case INPUT_FILES:
      return getInputFiles();

    case OUTPUT_FILES:
      return getOutputFiles();

    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 */
  public boolean isSet(_Fields field) {
    if (field == null) {
      throw new java.lang.IllegalArgumentException();
    }

    switch (field) {
    case ID:
      return isSetId();
    case IMAGE_NAME:
      return isSetImageName();
    case OUTPUT_DIR_PATH:
      return isSetOutputDirPath();
    case INPUT_DIR_PATH:
      return isSetInputDirPath();
    case EXECUTION_COMMAND:
      return isSetExecutionCommand();
    case INPUT_FILES:
      return isSetInputFiles();
    case OUTPUT_FILES:
      return isSetOutputFiles();
    case GATEWAY_ID:
      return isSetGatewayId();
    }
    throw new java.lang.IllegalStateException();
  }

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

  public boolean equals(Parser 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_imageName = true && this.isSetImageName();
    boolean that_present_imageName = true && that.isSetImageName();
    if (this_present_imageName || that_present_imageName) {
      if (!(this_present_imageName && that_present_imageName))
        return false;
      if (!this.imageName.equals(that.imageName))
        return false;
    }

    boolean this_present_outputDirPath = true && this.isSetOutputDirPath();
    boolean that_present_outputDirPath = true && that.isSetOutputDirPath();
    if (this_present_outputDirPath || that_present_outputDirPath) {
      if (!(this_present_outputDirPath && that_present_outputDirPath))
        return false;
      if (!this.outputDirPath.equals(that.outputDirPath))
        return false;
    }

    boolean this_present_inputDirPath = true && this.isSetInputDirPath();
    boolean that_present_inputDirPath = true && that.isSetInputDirPath();
    if (this_present_inputDirPath || that_present_inputDirPath) {
      if (!(this_present_inputDirPath && that_present_inputDirPath))
        return false;
      if (!this.inputDirPath.equals(that.inputDirPath))
        return false;
    }

    boolean this_present_executionCommand = true && this.isSetExecutionCommand();
    boolean that_present_executionCommand = true && that.isSetExecutionCommand();
    if (this_present_executionCommand || that_present_executionCommand) {
      if (!(this_present_executionCommand && that_present_executionCommand))
        return false;
      if (!this.executionCommand.equals(that.executionCommand))
        return false;
    }

    boolean this_present_inputFiles = true && this.isSetInputFiles();
    boolean that_present_inputFiles = true && that.isSetInputFiles();
    if (this_present_inputFiles || that_present_inputFiles) {
      if (!(this_present_inputFiles && that_present_inputFiles))
        return false;
      if (!this.inputFiles.equals(that.inputFiles))
        return false;
    }

    boolean this_present_outputFiles = true && this.isSetOutputFiles();
    boolean that_present_outputFiles = true && that.isSetOutputFiles();
    if (this_present_outputFiles || that_present_outputFiles) {
      if (!(this_present_outputFiles && that_present_outputFiles))
        return false;
      if (!this.outputFiles.equals(that.outputFiles))
        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 + ((isSetImageName()) ? 131071 : 524287);
    if (isSetImageName())
      hashCode = hashCode * 8191 + imageName.hashCode();

    hashCode = hashCode * 8191 + ((isSetOutputDirPath()) ? 131071 : 524287);
    if (isSetOutputDirPath())
      hashCode = hashCode * 8191 + outputDirPath.hashCode();

    hashCode = hashCode * 8191 + ((isSetInputDirPath()) ? 131071 : 524287);
    if (isSetInputDirPath())
      hashCode = hashCode * 8191 + inputDirPath.hashCode();

    hashCode = hashCode * 8191 + ((isSetExecutionCommand()) ? 131071 : 524287);
    if (isSetExecutionCommand())
      hashCode = hashCode * 8191 + executionCommand.hashCode();

    hashCode = hashCode * 8191 + ((isSetInputFiles()) ? 131071 : 524287);
    if (isSetInputFiles())
      hashCode = hashCode * 8191 + inputFiles.hashCode();

    hashCode = hashCode * 8191 + ((isSetOutputFiles()) ? 131071 : 524287);
    if (isSetOutputFiles())
      hashCode = hashCode * 8191 + outputFiles.hashCode();

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

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetId()).compareTo(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.valueOf(isSetImageName()).compareTo(other.isSetImageName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetImageName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.imageName, other.imageName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetOutputDirPath()).compareTo(other.isSetOutputDirPath());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetOutputDirPath()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.outputDirPath, other.outputDirPath);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetInputDirPath()).compareTo(other.isSetInputDirPath());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetInputDirPath()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.inputDirPath, other.inputDirPath);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetExecutionCommand()).compareTo(other.isSetExecutionCommand());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExecutionCommand()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.executionCommand, other.executionCommand);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetInputFiles()).compareTo(other.isSetInputFiles());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetInputFiles()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.inputFiles, other.inputFiles);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetOutputFiles()).compareTo(other.isSetOutputFiles());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetOutputFiles()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.outputFiles, other.outputFiles);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetGatewayId()).compareTo(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;
  }

  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

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

  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("Parser(");
    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("imageName:");
    if (this.imageName == null) {
      sb.append("null");
    } else {
      sb.append(this.imageName);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("outputDirPath:");
    if (this.outputDirPath == null) {
      sb.append("null");
    } else {
      sb.append(this.outputDirPath);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("inputDirPath:");
    if (this.inputDirPath == null) {
      sb.append("null");
    } else {
      sb.append(this.inputDirPath);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("executionCommand:");
    if (this.executionCommand == null) {
      sb.append("null");
    } else {
      sb.append(this.executionCommand);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("inputFiles:");
    if (this.inputFiles == null) {
      sb.append("null");
    } else {
      sb.append(this.inputFiles);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("outputFiles:");
    if (this.outputFiles == null) {
      sb.append("null");
    } else {
      sb.append(this.outputFiles);
    }
    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 (!isSetImageName()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'imageName' is unset! Struct:" + toString());
    }

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

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

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

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

    if (!isSetOutputFiles()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'outputFiles' 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 ParserStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public ParserStandardScheme getScheme() {
      return new ParserStandardScheme();
    }
  }

  private static class ParserStandardScheme extends org.apache.thrift.scheme.StandardScheme<Parser> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, Parser 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: // IMAGE_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.imageName = iprot.readString();
              struct.setImageNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // OUTPUT_DIR_PATH
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.outputDirPath = iprot.readString();
              struct.setOutputDirPathIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // INPUT_DIR_PATH
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.inputDirPath = iprot.readString();
              struct.setInputDirPathIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // EXECUTION_COMMAND
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.executionCommand = iprot.readString();
              struct.setExecutionCommandIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // INPUT_FILES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                struct.inputFiles = new java.util.ArrayList<ParserInput>(_list0.size);
                ParserInput _elem1;
                for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                {
                  _elem1 = new ParserInput();
                  _elem1.read(iprot);
                  struct.inputFiles.add(_elem1);
                }
                iprot.readListEnd();
              }
              struct.setInputFilesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // OUTPUT_FILES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list3 = iprot.readListBegin();
                struct.outputFiles = new java.util.ArrayList<ParserOutput>(_list3.size);
                ParserOutput _elem4;
                for (int _i5 = 0; _i5 < _list3.size; ++_i5)
                {
                  _elem4 = new ParserOutput();
                  _elem4.read(iprot);
                  struct.outputFiles.add(_elem4);
                }
                iprot.readListEnd();
              }
              struct.setOutputFilesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // 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();
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot, Parser 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.imageName != null) {
        oprot.writeFieldBegin(IMAGE_NAME_FIELD_DESC);
        oprot.writeString(struct.imageName);
        oprot.writeFieldEnd();
      }
      if (struct.outputDirPath != null) {
        oprot.writeFieldBegin(OUTPUT_DIR_PATH_FIELD_DESC);
        oprot.writeString(struct.outputDirPath);
        oprot.writeFieldEnd();
      }
      if (struct.inputDirPath != null) {
        oprot.writeFieldBegin(INPUT_DIR_PATH_FIELD_DESC);
        oprot.writeString(struct.inputDirPath);
        oprot.writeFieldEnd();
      }
      if (struct.executionCommand != null) {
        oprot.writeFieldBegin(EXECUTION_COMMAND_FIELD_DESC);
        oprot.writeString(struct.executionCommand);
        oprot.writeFieldEnd();
      }
      if (struct.inputFiles != null) {
        oprot.writeFieldBegin(INPUT_FILES_FIELD_DESC);
        {
          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.inputFiles.size()));
          for (ParserInput _iter6 : struct.inputFiles)
          {
            _iter6.write(oprot);
          }
          oprot.writeListEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.outputFiles != null) {
        oprot.writeFieldBegin(OUTPUT_FILES_FIELD_DESC);
        {
          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.outputFiles.size()));
          for (ParserOutput _iter7 : struct.outputFiles)
          {
            _iter7.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 ParserTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public ParserTupleScheme getScheme() {
      return new ParserTupleScheme();
    }
  }

  private static class ParserTupleScheme extends org.apache.thrift.scheme.TupleScheme<Parser> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, Parser 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.imageName);
      oprot.writeString(struct.outputDirPath);
      oprot.writeString(struct.inputDirPath);
      oprot.writeString(struct.executionCommand);
      {
        oprot.writeI32(struct.inputFiles.size());
        for (ParserInput _iter8 : struct.inputFiles)
        {
          _iter8.write(oprot);
        }
      }
      {
        oprot.writeI32(struct.outputFiles.size());
        for (ParserOutput _iter9 : struct.outputFiles)
        {
          _iter9.write(oprot);
        }
      }
      oprot.writeString(struct.gatewayId);
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, Parser 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.imageName = iprot.readString();
      struct.setImageNameIsSet(true);
      struct.outputDirPath = iprot.readString();
      struct.setOutputDirPathIsSet(true);
      struct.inputDirPath = iprot.readString();
      struct.setInputDirPathIsSet(true);
      struct.executionCommand = iprot.readString();
      struct.setExecutionCommandIsSet(true);
      {
        org.apache.thrift.protocol.TList _list10 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
        struct.inputFiles = new java.util.ArrayList<ParserInput>(_list10.size);
        ParserInput _elem11;
        for (int _i12 = 0; _i12 < _list10.size; ++_i12)
        {
          _elem11 = new ParserInput();
          _elem11.read(iprot);
          struct.inputFiles.add(_elem11);
        }
      }
      struct.setInputFilesIsSet(true);
      {
        org.apache.thrift.protocol.TList _list13 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
        struct.outputFiles = new java.util.ArrayList<ParserOutput>(_list13.size);
        ParserOutput _elem14;
        for (int _i15 = 0; _i15 < _list13.size; ++_i15)
        {
          _elem14 = new ParserOutput();
          _elem14.read(iprot);
          struct.outputFiles.add(_elem14);
        }
      }
      struct.setOutputFilesIsSet(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();
  }
}

