/**
 * 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.12.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.storm.generated;

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

  private static final org.apache.storm.thrift.protocol.TField SERVICE_TYPE_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("serviceType", org.apache.storm.thrift.protocol.TType.I32, (short)1);
  private static final org.apache.storm.thrift.protocol.TField INFO_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("info", org.apache.storm.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.storm.thrift.protocol.TField SIGNATURE_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("signature", org.apache.storm.thrift.protocol.TType.STRING, (short)3);

  private static final org.apache.storm.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new WorkerTokenStandardSchemeFactory();
  private static final org.apache.storm.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new WorkerTokenTupleSchemeFactory();

  private @org.apache.storm.thrift.annotation.Nullable WorkerTokenServiceType serviceType; // required
  private @org.apache.storm.thrift.annotation.Nullable java.nio.ByteBuffer info; // required
  private @org.apache.storm.thrift.annotation.Nullable java.nio.ByteBuffer signature; // required

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
    /**
     * 
     * @see WorkerTokenServiceType
     */
    SERVICE_TYPE((short)1, "serviceType"),
    INFO((short)2, "info"),
    SIGNATURE((short)3, "signature");

    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.storm.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // SERVICE_TYPE
          return SERVICE_TYPE;
        case 2: // INFO
          return INFO;
        case 3: // SIGNATURE
          return SIGNATURE;
        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.storm.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;
    }

    public short getThriftFieldId() {
      return _thriftId;
    }

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

  // isset id assignments
  public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.SERVICE_TYPE, new org.apache.storm.thrift.meta_data.FieldMetaData("serviceType", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.EnumMetaData(org.apache.storm.thrift.protocol.TType.ENUM, WorkerTokenServiceType.class)));
    tmpMap.put(_Fields.INFO, new org.apache.storm.thrift.meta_data.FieldMetaData("info", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING        , true)));
    tmpMap.put(_Fields.SIGNATURE, new org.apache.storm.thrift.meta_data.FieldMetaData("signature", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING        , true)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(WorkerToken.class, metaDataMap);
  }

  public WorkerToken() {
  }

  public WorkerToken(
    WorkerTokenServiceType serviceType,
    java.nio.ByteBuffer info,
    java.nio.ByteBuffer signature)
  {
    this();
    this.serviceType = serviceType;
    this.info = org.apache.storm.thrift.TBaseHelper.copyBinary(info);
    this.signature = org.apache.storm.thrift.TBaseHelper.copyBinary(signature);
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public WorkerToken(WorkerToken other) {
    if (other.is_set_serviceType()) {
      this.serviceType = other.serviceType;
    }
    if (other.is_set_info()) {
      this.info = org.apache.storm.thrift.TBaseHelper.copyBinary(other.info);
    }
    if (other.is_set_signature()) {
      this.signature = org.apache.storm.thrift.TBaseHelper.copyBinary(other.signature);
    }
  }

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

  @Override
  public void clear() {
    this.serviceType = null;
    this.info = null;
    this.signature = null;
  }

  /**
   * 
   * @see WorkerTokenServiceType
   */
  @org.apache.storm.thrift.annotation.Nullable
  public WorkerTokenServiceType get_serviceType() {
    return this.serviceType;
  }

  /**
   * 
   * @see WorkerTokenServiceType
   */
  public void set_serviceType(@org.apache.storm.thrift.annotation.Nullable WorkerTokenServiceType serviceType) {
    this.serviceType = serviceType;
  }

  public void unset_serviceType() {
    this.serviceType = null;
  }

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

  public void set_serviceType_isSet(boolean value) {
    if (!value) {
      this.serviceType = null;
    }
  }

  public byte[] get_info() {
    set_info(org.apache.storm.thrift.TBaseHelper.rightSize(info));
    return info == null ? null : info.array();
  }

  public java.nio.ByteBuffer buffer_for_info() {
    return org.apache.storm.thrift.TBaseHelper.copyBinary(info);
  }

  public void set_info(byte[] info) {
    this.info = info == null ? (java.nio.ByteBuffer)null   : java.nio.ByteBuffer.wrap(info.clone());
  }

  public void set_info(@org.apache.storm.thrift.annotation.Nullable java.nio.ByteBuffer info) {
    this.info = org.apache.storm.thrift.TBaseHelper.copyBinary(info);
  }

  public void unset_info() {
    this.info = null;
  }

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

  public void set_info_isSet(boolean value) {
    if (!value) {
      this.info = null;
    }
  }

  public byte[] get_signature() {
    set_signature(org.apache.storm.thrift.TBaseHelper.rightSize(signature));
    return signature == null ? null : signature.array();
  }

  public java.nio.ByteBuffer buffer_for_signature() {
    return org.apache.storm.thrift.TBaseHelper.copyBinary(signature);
  }

  public void set_signature(byte[] signature) {
    this.signature = signature == null ? (java.nio.ByteBuffer)null   : java.nio.ByteBuffer.wrap(signature.clone());
  }

  public void set_signature(@org.apache.storm.thrift.annotation.Nullable java.nio.ByteBuffer signature) {
    this.signature = org.apache.storm.thrift.TBaseHelper.copyBinary(signature);
  }

  public void unset_signature() {
    this.signature = null;
  }

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

  public void set_signature_isSet(boolean value) {
    if (!value) {
      this.signature = null;
    }
  }

  public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case SERVICE_TYPE:
      if (value == null) {
        unset_serviceType();
      } else {
        set_serviceType((WorkerTokenServiceType)value);
      }
      break;

    case INFO:
      if (value == null) {
        unset_info();
      } else {
        if (value instanceof byte[]) {
          set_info((byte[])value);
        } else {
          set_info((java.nio.ByteBuffer)value);
        }
      }
      break;

    case SIGNATURE:
      if (value == null) {
        unset_signature();
      } else {
        if (value instanceof byte[]) {
          set_signature((byte[])value);
        } else {
          set_signature((java.nio.ByteBuffer)value);
        }
      }
      break;

    }
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case SERVICE_TYPE:
      return get_serviceType();

    case INFO:
      return get_info();

    case SIGNATURE:
      return get_signature();

    }
    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 SERVICE_TYPE:
      return is_set_serviceType();
    case INFO:
      return is_set_info();
    case SIGNATURE:
      return is_set_signature();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_serviceType = true && this.is_set_serviceType();
    boolean that_present_serviceType = true && that.is_set_serviceType();
    if (this_present_serviceType || that_present_serviceType) {
      if (!(this_present_serviceType && that_present_serviceType))
        return false;
      if (!this.serviceType.equals(that.serviceType))
        return false;
    }

    boolean this_present_info = true && this.is_set_info();
    boolean that_present_info = true && that.is_set_info();
    if (this_present_info || that_present_info) {
      if (!(this_present_info && that_present_info))
        return false;
      if (!this.info.equals(that.info))
        return false;
    }

    boolean this_present_signature = true && this.is_set_signature();
    boolean that_present_signature = true && that.is_set_signature();
    if (this_present_signature || that_present_signature) {
      if (!(this_present_signature && that_present_signature))
        return false;
      if (!this.signature.equals(that.signature))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((is_set_serviceType()) ? 131071 : 524287);
    if (is_set_serviceType())
      hashCode = hashCode * 8191 + serviceType.getValue();

    hashCode = hashCode * 8191 + ((is_set_info()) ? 131071 : 524287);
    if (is_set_info())
      hashCode = hashCode * 8191 + info.hashCode();

    hashCode = hashCode * 8191 + ((is_set_signature()) ? 131071 : 524287);
    if (is_set_signature())
      hashCode = hashCode * 8191 + signature.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(is_set_serviceType()).compareTo(other.is_set_serviceType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_serviceType()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.serviceType, other.serviceType);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_info()).compareTo(other.is_set_info());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_info()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.info, other.info);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_signature()).compareTo(other.is_set_signature());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_signature()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.signature, other.signature);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    sb.append("serviceType:");
    if (this.serviceType == null) {
      sb.append("null");
    } else {
      sb.append(this.serviceType);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("info:");
    if (this.info == null) {
      sb.append("null");
    } else {
      org.apache.storm.thrift.TBaseHelper.toString(this.info, sb);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("signature:");
    if (this.signature == null) {
      sb.append("null");
    } else {
      org.apache.storm.thrift.TBaseHelper.toString(this.signature, sb);
    }
    first = false;
    sb.append(")");
    return sb.toString();
  }

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

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

    if (!is_set_signature()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'signature' 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.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.storm.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.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.storm.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class WorkerTokenStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public WorkerTokenStandardScheme getScheme() {
      return new WorkerTokenStandardScheme();
    }
  }

  private static class WorkerTokenStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<WorkerToken> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, WorkerToken struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.storm.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // SERVICE_TYPE
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.serviceType = org.apache.storm.generated.WorkerTokenServiceType.findByValue(iprot.readI32());
              struct.set_serviceType_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // INFO
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.info = iprot.readBinary();
              struct.set_info_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // SIGNATURE
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.signature = iprot.readBinary();
              struct.set_signature_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.serviceType != null) {
        oprot.writeFieldBegin(SERVICE_TYPE_FIELD_DESC);
        oprot.writeI32(struct.serviceType.getValue());
        oprot.writeFieldEnd();
      }
      if (struct.info != null) {
        oprot.writeFieldBegin(INFO_FIELD_DESC);
        oprot.writeBinary(struct.info);
        oprot.writeFieldEnd();
      }
      if (struct.signature != null) {
        oprot.writeFieldBegin(SIGNATURE_FIELD_DESC);
        oprot.writeBinary(struct.signature);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class WorkerTokenTupleSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public WorkerTokenTupleScheme getScheme() {
      return new WorkerTokenTupleScheme();
    }
  }

  private static class WorkerTokenTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<WorkerToken> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, WorkerToken struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      oprot.writeI32(struct.serviceType.getValue());
      oprot.writeBinary(struct.info);
      oprot.writeBinary(struct.signature);
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, WorkerToken struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      struct.serviceType = org.apache.storm.generated.WorkerTokenServiceType.findByValue(iprot.readI32());
      struct.set_serviceType_isSet(true);
      struct.info = iprot.readBinary();
      struct.set_info_isSet(true);
      struct.signature = iprot.readBinary();
      struct.set_signature_isSet(true);
    }
  }

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

