/**
 * 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.allocation.manager.models;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
 * <p>Allocation Request status details</p>
 * <li>projectId: Unique id of the project</li>
 * <li>awardAllocation: Allocation awarded</li>
 * <li>endDate: End date of the request</li>
 * <li>reviewers: reviewers of the request</li>
 * <li>startDate: Start date of the allocation</li>
 * <li>status: Status of the allocation request</li>
 * 
 */
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class RequestStatus implements org.apache.thrift.TBase<RequestStatus, RequestStatus._Fields>, java.io.Serializable, Cloneable, Comparable<RequestStatus> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RequestStatus");

  private static final org.apache.thrift.protocol.TField PROJECT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("projectId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField AWARD_ALLOCATION_FIELD_DESC = new org.apache.thrift.protocol.TField("awardAllocation", org.apache.thrift.protocol.TType.I64, (short)2);
  private static final org.apache.thrift.protocol.TField END_DATE_FIELD_DESC = new org.apache.thrift.protocol.TField("endDate", org.apache.thrift.protocol.TType.I64, (short)3);
  private static final org.apache.thrift.protocol.TField REVIEWERS_FIELD_DESC = new org.apache.thrift.protocol.TField("reviewers", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField START_DATE_FIELD_DESC = new org.apache.thrift.protocol.TField("startDate", org.apache.thrift.protocol.TType.I64, (short)5);
  private static final org.apache.thrift.protocol.TField STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("status", org.apache.thrift.protocol.TType.STRING, (short)6);

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

  public java.lang.String projectId; // optional
  public long awardAllocation; // optional
  public long endDate; // optional
  public java.lang.String reviewers; // optional
  public long startDate; // optional
  public java.lang.String status; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    PROJECT_ID((short)1, "projectId"),
    AWARD_ALLOCATION((short)2, "awardAllocation"),
    END_DATE((short)3, "endDate"),
    REVIEWERS((short)4, "reviewers"),
    START_DATE((short)5, "startDate"),
    STATUS((short)6, "status");

    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: // PROJECT_ID
          return PROJECT_ID;
        case 2: // AWARD_ALLOCATION
          return AWARD_ALLOCATION;
        case 3: // END_DATE
          return END_DATE;
        case 4: // REVIEWERS
          return REVIEWERS;
        case 5: // START_DATE
          return START_DATE;
        case 6: // STATUS
          return STATUS;
        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
  private static final int __AWARDALLOCATION_ISSET_ID = 0;
  private static final int __ENDDATE_ISSET_ID = 1;
  private static final int __STARTDATE_ISSET_ID = 2;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.PROJECT_ID,_Fields.AWARD_ALLOCATION,_Fields.END_DATE,_Fields.REVIEWERS,_Fields.START_DATE,_Fields.STATUS};
  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.PROJECT_ID, new org.apache.thrift.meta_data.FieldMetaData("projectId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.AWARD_ALLOCATION, new org.apache.thrift.meta_data.FieldMetaData("awardAllocation", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.END_DATE, new org.apache.thrift.meta_data.FieldMetaData("endDate", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.REVIEWERS, new org.apache.thrift.meta_data.FieldMetaData("reviewers", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.START_DATE, new org.apache.thrift.meta_data.FieldMetaData("startDate", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.STATUS, new org.apache.thrift.meta_data.FieldMetaData("status", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        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(RequestStatus.class, metaDataMap);
  }

  public RequestStatus() {
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public RequestStatus(RequestStatus other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetProjectId()) {
      this.projectId = other.projectId;
    }
    this.awardAllocation = other.awardAllocation;
    this.endDate = other.endDate;
    if (other.isSetReviewers()) {
      this.reviewers = other.reviewers;
    }
    this.startDate = other.startDate;
    if (other.isSetStatus()) {
      this.status = other.status;
    }
  }

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

  @Override
  public void clear() {
    this.projectId = null;
    setAwardAllocationIsSet(false);
    this.awardAllocation = 0;
    setEndDateIsSet(false);
    this.endDate = 0;
    this.reviewers = null;
    setStartDateIsSet(false);
    this.startDate = 0;
    this.status = null;
  }

  public java.lang.String getProjectId() {
    return this.projectId;
  }

  public RequestStatus setProjectId(java.lang.String projectId) {
    this.projectId = projectId;
    return this;
  }

  public void unsetProjectId() {
    this.projectId = null;
  }

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

  public void setProjectIdIsSet(boolean value) {
    if (!value) {
      this.projectId = null;
    }
  }

  public long getAwardAllocation() {
    return this.awardAllocation;
  }

  public RequestStatus setAwardAllocation(long awardAllocation) {
    this.awardAllocation = awardAllocation;
    setAwardAllocationIsSet(true);
    return this;
  }

  public void unsetAwardAllocation() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __AWARDALLOCATION_ISSET_ID);
  }

  /** Returns true if field awardAllocation is set (has been assigned a value) and false otherwise */
  public boolean isSetAwardAllocation() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __AWARDALLOCATION_ISSET_ID);
  }

  public void setAwardAllocationIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __AWARDALLOCATION_ISSET_ID, value);
  }

  public long getEndDate() {
    return this.endDate;
  }

  public RequestStatus setEndDate(long endDate) {
    this.endDate = endDate;
    setEndDateIsSet(true);
    return this;
  }

  public void unsetEndDate() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __ENDDATE_ISSET_ID);
  }

  /** Returns true if field endDate is set (has been assigned a value) and false otherwise */
  public boolean isSetEndDate() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __ENDDATE_ISSET_ID);
  }

  public void setEndDateIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __ENDDATE_ISSET_ID, value);
  }

  public java.lang.String getReviewers() {
    return this.reviewers;
  }

  public RequestStatus setReviewers(java.lang.String reviewers) {
    this.reviewers = reviewers;
    return this;
  }

  public void unsetReviewers() {
    this.reviewers = null;
  }

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

  public void setReviewersIsSet(boolean value) {
    if (!value) {
      this.reviewers = null;
    }
  }

  public long getStartDate() {
    return this.startDate;
  }

  public RequestStatus setStartDate(long startDate) {
    this.startDate = startDate;
    setStartDateIsSet(true);
    return this;
  }

  public void unsetStartDate() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __STARTDATE_ISSET_ID);
  }

  /** Returns true if field startDate is set (has been assigned a value) and false otherwise */
  public boolean isSetStartDate() {
    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __STARTDATE_ISSET_ID);
  }

  public void setStartDateIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __STARTDATE_ISSET_ID, value);
  }

  public java.lang.String getStatus() {
    return this.status;
  }

  public RequestStatus setStatus(java.lang.String status) {
    this.status = status;
    return this;
  }

  public void unsetStatus() {
    this.status = null;
  }

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

  public void setStatusIsSet(boolean value) {
    if (!value) {
      this.status = null;
    }
  }

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

    case AWARD_ALLOCATION:
      if (value == null) {
        unsetAwardAllocation();
      } else {
        setAwardAllocation((java.lang.Long)value);
      }
      break;

    case END_DATE:
      if (value == null) {
        unsetEndDate();
      } else {
        setEndDate((java.lang.Long)value);
      }
      break;

    case REVIEWERS:
      if (value == null) {
        unsetReviewers();
      } else {
        setReviewers((java.lang.String)value);
      }
      break;

    case START_DATE:
      if (value == null) {
        unsetStartDate();
      } else {
        setStartDate((java.lang.Long)value);
      }
      break;

    case STATUS:
      if (value == null) {
        unsetStatus();
      } else {
        setStatus((java.lang.String)value);
      }
      break;

    }
  }

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

    case AWARD_ALLOCATION:
      return getAwardAllocation();

    case END_DATE:
      return getEndDate();

    case REVIEWERS:
      return getReviewers();

    case START_DATE:
      return getStartDate();

    case STATUS:
      return getStatus();

    }
    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 PROJECT_ID:
      return isSetProjectId();
    case AWARD_ALLOCATION:
      return isSetAwardAllocation();
    case END_DATE:
      return isSetEndDate();
    case REVIEWERS:
      return isSetReviewers();
    case START_DATE:
      return isSetStartDate();
    case STATUS:
      return isSetStatus();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_projectId = true && this.isSetProjectId();
    boolean that_present_projectId = true && that.isSetProjectId();
    if (this_present_projectId || that_present_projectId) {
      if (!(this_present_projectId && that_present_projectId))
        return false;
      if (!this.projectId.equals(that.projectId))
        return false;
    }

    boolean this_present_awardAllocation = true && this.isSetAwardAllocation();
    boolean that_present_awardAllocation = true && that.isSetAwardAllocation();
    if (this_present_awardAllocation || that_present_awardAllocation) {
      if (!(this_present_awardAllocation && that_present_awardAllocation))
        return false;
      if (this.awardAllocation != that.awardAllocation)
        return false;
    }

    boolean this_present_endDate = true && this.isSetEndDate();
    boolean that_present_endDate = true && that.isSetEndDate();
    if (this_present_endDate || that_present_endDate) {
      if (!(this_present_endDate && that_present_endDate))
        return false;
      if (this.endDate != that.endDate)
        return false;
    }

    boolean this_present_reviewers = true && this.isSetReviewers();
    boolean that_present_reviewers = true && that.isSetReviewers();
    if (this_present_reviewers || that_present_reviewers) {
      if (!(this_present_reviewers && that_present_reviewers))
        return false;
      if (!this.reviewers.equals(that.reviewers))
        return false;
    }

    boolean this_present_startDate = true && this.isSetStartDate();
    boolean that_present_startDate = true && that.isSetStartDate();
    if (this_present_startDate || that_present_startDate) {
      if (!(this_present_startDate && that_present_startDate))
        return false;
      if (this.startDate != that.startDate)
        return false;
    }

    boolean this_present_status = true && this.isSetStatus();
    boolean that_present_status = true && that.isSetStatus();
    if (this_present_status || that_present_status) {
      if (!(this_present_status && that_present_status))
        return false;
      if (!this.status.equals(that.status))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((isSetProjectId()) ? 131071 : 524287);
    if (isSetProjectId())
      hashCode = hashCode * 8191 + projectId.hashCode();

    hashCode = hashCode * 8191 + ((isSetAwardAllocation()) ? 131071 : 524287);
    if (isSetAwardAllocation())
      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(awardAllocation);

    hashCode = hashCode * 8191 + ((isSetEndDate()) ? 131071 : 524287);
    if (isSetEndDate())
      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(endDate);

    hashCode = hashCode * 8191 + ((isSetReviewers()) ? 131071 : 524287);
    if (isSetReviewers())
      hashCode = hashCode * 8191 + reviewers.hashCode();

    hashCode = hashCode * 8191 + ((isSetStartDate()) ? 131071 : 524287);
    if (isSetStartDate())
      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(startDate);

    hashCode = hashCode * 8191 + ((isSetStatus()) ? 131071 : 524287);
    if (isSetStatus())
      hashCode = hashCode * 8191 + status.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(isSetProjectId()).compareTo(other.isSetProjectId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetProjectId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.projectId, other.projectId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetAwardAllocation()).compareTo(other.isSetAwardAllocation());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAwardAllocation()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.awardAllocation, other.awardAllocation);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetEndDate()).compareTo(other.isSetEndDate());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetEndDate()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.endDate, other.endDate);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetReviewers()).compareTo(other.isSetReviewers());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetReviewers()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.reviewers, other.reviewers);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetStartDate()).compareTo(other.isSetStartDate());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStartDate()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startDate, other.startDate);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(isSetStatus()).compareTo(other.isSetStatus());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStatus()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.status, other.status);
      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("RequestStatus(");
    boolean first = true;

    if (isSetProjectId()) {
      sb.append("projectId:");
      if (this.projectId == null) {
        sb.append("null");
      } else {
        sb.append(this.projectId);
      }
      first = false;
    }
    if (isSetAwardAllocation()) {
      if (!first) sb.append(", ");
      sb.append("awardAllocation:");
      sb.append(this.awardAllocation);
      first = false;
    }
    if (isSetEndDate()) {
      if (!first) sb.append(", ");
      sb.append("endDate:");
      sb.append(this.endDate);
      first = false;
    }
    if (isSetReviewers()) {
      if (!first) sb.append(", ");
      sb.append("reviewers:");
      if (this.reviewers == null) {
        sb.append("null");
      } else {
        sb.append(this.reviewers);
      }
      first = false;
    }
    if (isSetStartDate()) {
      if (!first) sb.append(", ");
      sb.append("startDate:");
      sb.append(this.startDate);
      first = false;
    }
    if (isSetStatus()) {
      if (!first) sb.append(", ");
      sb.append("status:");
      if (this.status == null) {
        sb.append("null");
      } else {
        sb.append(this.status);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    // 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 {
      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
      __isset_bitfield = 0;
      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 RequestStatusStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public RequestStatusStandardScheme getScheme() {
      return new RequestStatusStandardScheme();
    }
  }

  private static class RequestStatusStandardScheme extends org.apache.thrift.scheme.StandardScheme<RequestStatus> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, RequestStatus 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: // PROJECT_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.projectId = iprot.readString();
              struct.setProjectIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // AWARD_ALLOCATION
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.awardAllocation = iprot.readI64();
              struct.setAwardAllocationIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // END_DATE
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.endDate = iprot.readI64();
              struct.setEndDateIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // REVIEWERS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.reviewers = iprot.readString();
              struct.setReviewersIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // START_DATE
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.startDate = iprot.readI64();
              struct.setStartDateIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // STATUS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.status = iprot.readString();
              struct.setStatusIsSet(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();

      // check for required fields of primitive type, which can't be checked in the validate method
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.projectId != null) {
        if (struct.isSetProjectId()) {
          oprot.writeFieldBegin(PROJECT_ID_FIELD_DESC);
          oprot.writeString(struct.projectId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetAwardAllocation()) {
        oprot.writeFieldBegin(AWARD_ALLOCATION_FIELD_DESC);
        oprot.writeI64(struct.awardAllocation);
        oprot.writeFieldEnd();
      }
      if (struct.isSetEndDate()) {
        oprot.writeFieldBegin(END_DATE_FIELD_DESC);
        oprot.writeI64(struct.endDate);
        oprot.writeFieldEnd();
      }
      if (struct.reviewers != null) {
        if (struct.isSetReviewers()) {
          oprot.writeFieldBegin(REVIEWERS_FIELD_DESC);
          oprot.writeString(struct.reviewers);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetStartDate()) {
        oprot.writeFieldBegin(START_DATE_FIELD_DESC);
        oprot.writeI64(struct.startDate);
        oprot.writeFieldEnd();
      }
      if (struct.status != null) {
        if (struct.isSetStatus()) {
          oprot.writeFieldBegin(STATUS_FIELD_DESC);
          oprot.writeString(struct.status);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class RequestStatusTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public RequestStatusTupleScheme getScheme() {
      return new RequestStatusTupleScheme();
    }
  }

  private static class RequestStatusTupleScheme extends org.apache.thrift.scheme.TupleScheme<RequestStatus> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, RequestStatus struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetProjectId()) {
        optionals.set(0);
      }
      if (struct.isSetAwardAllocation()) {
        optionals.set(1);
      }
      if (struct.isSetEndDate()) {
        optionals.set(2);
      }
      if (struct.isSetReviewers()) {
        optionals.set(3);
      }
      if (struct.isSetStartDate()) {
        optionals.set(4);
      }
      if (struct.isSetStatus()) {
        optionals.set(5);
      }
      oprot.writeBitSet(optionals, 6);
      if (struct.isSetProjectId()) {
        oprot.writeString(struct.projectId);
      }
      if (struct.isSetAwardAllocation()) {
        oprot.writeI64(struct.awardAllocation);
      }
      if (struct.isSetEndDate()) {
        oprot.writeI64(struct.endDate);
      }
      if (struct.isSetReviewers()) {
        oprot.writeString(struct.reviewers);
      }
      if (struct.isSetStartDate()) {
        oprot.writeI64(struct.startDate);
      }
      if (struct.isSetStatus()) {
        oprot.writeString(struct.status);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, RequestStatus struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet incoming = iprot.readBitSet(6);
      if (incoming.get(0)) {
        struct.projectId = iprot.readString();
        struct.setProjectIdIsSet(true);
      }
      if (incoming.get(1)) {
        struct.awardAllocation = iprot.readI64();
        struct.setAwardAllocationIsSet(true);
      }
      if (incoming.get(2)) {
        struct.endDate = iprot.readI64();
        struct.setEndDateIsSet(true);
      }
      if (incoming.get(3)) {
        struct.reviewers = iprot.readString();
        struct.setReviewersIsSet(true);
      }
      if (incoming.get(4)) {
        struct.startDate = iprot.readI64();
        struct.setStartDateIsSet(true);
      }
      if (incoming.get(5)) {
        struct.status = iprot.readString();
        struct.setStatusIsSet(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();
  }
}

