/**
 * Autogenerated by Thrift
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 */
package backtype.storm.generated;

import org.apache.commons.lang.builder.HashCodeBuilder;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.thrift.*;
import org.apache.thrift.async.*;
import org.apache.thrift.meta_data.*;
import org.apache.thrift.transport.*;
import org.apache.thrift.protocol.*;

public class GlobalStreamId implements TBase<GlobalStreamId, GlobalStreamId._Fields>, java.io.Serializable, Cloneable {
  private static final TStruct STRUCT_DESC = new TStruct("GlobalStreamId");

  private static final TField COMPONENT_ID_FIELD_DESC = new TField("componentId", TType.I32, (short)1);
  private static final TField STREAM_ID_FIELD_DESC = new TField("streamId", TType.I32, (short)2);

  private int componentId;
  private int streamId;

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements TFieldIdEnum {
    COMPONENT_ID((short)1, "componentId"),
    STREAM_ID((short)2, "streamId");

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

    static {
      for (_Fields field : 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: // COMPONENT_ID
          return COMPONENT_ID;
        case 2: // STREAM_ID
          return STREAM_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 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(String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __COMPONENTID_ISSET_ID = 0;
  private static final int __STREAMID_ISSET_ID = 1;
  private BitSet __isset_bit_vector = new BitSet(2);

  public static final Map<_Fields, FieldMetaData> metaDataMap;
  static {
    Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.COMPONENT_ID, new FieldMetaData("componentId", TFieldRequirementType.REQUIRED, 
        new FieldValueMetaData(TType.I32)));
    tmpMap.put(_Fields.STREAM_ID, new FieldMetaData("streamId", TFieldRequirementType.REQUIRED, 
        new FieldValueMetaData(TType.I32)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    FieldMetaData.addStructMetaDataMap(GlobalStreamId.class, metaDataMap);
  }

  public GlobalStreamId() {
  }

  public GlobalStreamId(
    int componentId,
    int streamId)
  {
    this();
    this.componentId = componentId;
    set_componentId_isSet(true);
    this.streamId = streamId;
    set_streamId_isSet(true);
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public GlobalStreamId(GlobalStreamId other) {
    __isset_bit_vector.clear();
    __isset_bit_vector.or(other.__isset_bit_vector);
    this.componentId = other.componentId;
    this.streamId = other.streamId;
  }

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

  @Deprecated
  public GlobalStreamId clone() {
    return new GlobalStreamId(this);
  }

  public int get_componentId() {
    return this.componentId;
  }

  public void set_componentId(int componentId) {
    this.componentId = componentId;
    set_componentId_isSet(true);
  }

  public void unset_componentId() {
    __isset_bit_vector.clear(__COMPONENTID_ISSET_ID);
  }

  /** Returns true if field componentId is set (has been asigned a value) and false otherwise */
  public boolean is_set_componentId() {
    return __isset_bit_vector.get(__COMPONENTID_ISSET_ID);
  }

  public void set_componentId_isSet(boolean value) {
    __isset_bit_vector.set(__COMPONENTID_ISSET_ID, value);
  }

  public int get_streamId() {
    return this.streamId;
  }

  public void set_streamId(int streamId) {
    this.streamId = streamId;
    set_streamId_isSet(true);
  }

  public void unset_streamId() {
    __isset_bit_vector.clear(__STREAMID_ISSET_ID);
  }

  /** Returns true if field streamId is set (has been asigned a value) and false otherwise */
  public boolean is_set_streamId() {
    return __isset_bit_vector.get(__STREAMID_ISSET_ID);
  }

  public void set_streamId_isSet(boolean value) {
    __isset_bit_vector.set(__STREAMID_ISSET_ID, value);
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case COMPONENT_ID:
      if (value == null) {
        unset_componentId();
      } else {
        set_componentId((Integer)value);
      }
      break;

    case STREAM_ID:
      if (value == null) {
        unset_streamId();
      } else {
        set_streamId((Integer)value);
      }
      break;

    }
  }

  public void setFieldValue(int fieldID, Object value) {
    setFieldValue(_Fields.findByThriftIdOrThrow(fieldID), value);
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case COMPONENT_ID:
      return new Integer(get_componentId());

    case STREAM_ID:
      return new Integer(get_streamId());

    }
    throw new IllegalStateException();
  }

  public Object getFieldValue(int fieldId) {
    return getFieldValue(_Fields.findByThriftIdOrThrow(fieldId));
  }

  /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */
  public boolean isSet(_Fields field) {
    switch (field) {
    case COMPONENT_ID:
      return is_set_componentId();
    case STREAM_ID:
      return is_set_streamId();
    }
    throw new IllegalStateException();
  }

  public boolean isSet(int fieldID) {
    return isSet(_Fields.findByThriftIdOrThrow(fieldID));
  }

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

  public boolean equals(GlobalStreamId that) {
    if (that == null)
      return false;

    boolean this_present_componentId = true;
    boolean that_present_componentId = true;
    if (this_present_componentId || that_present_componentId) {
      if (!(this_present_componentId && that_present_componentId))
        return false;
      if (this.componentId != that.componentId)
        return false;
    }

    boolean this_present_streamId = true;
    boolean that_present_streamId = true;
    if (this_present_streamId || that_present_streamId) {
      if (!(this_present_streamId && that_present_streamId))
        return false;
      if (this.streamId != that.streamId)
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    HashCodeBuilder builder = new HashCodeBuilder();

    boolean present_componentId = true;
    builder.append(present_componentId);
    if (present_componentId)
      builder.append(componentId);

    boolean present_streamId = true;
    builder.append(present_streamId);
    if (present_streamId)
      builder.append(streamId);

    return builder.toHashCode();
  }

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

    int lastComparison = 0;
    GlobalStreamId typedOther = (GlobalStreamId)other;

    lastComparison = Boolean.valueOf(is_set_componentId()).compareTo(typedOther.is_set_componentId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_componentId()) {      lastComparison = TBaseHelper.compareTo(this.componentId, typedOther.componentId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_streamId()).compareTo(typedOther.is_set_streamId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_streamId()) {      lastComparison = TBaseHelper.compareTo(this.streamId, typedOther.streamId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  public void read(TProtocol iprot) throws TException {
    TField field;
    iprot.readStructBegin();
    while (true)
    {
      field = iprot.readFieldBegin();
      if (field.type == TType.STOP) { 
        break;
      }
      switch (field.id) {
        case 1: // COMPONENT_ID
          if (field.type == TType.I32) {
            this.componentId = iprot.readI32();
            set_componentId_isSet(true);
          } else { 
            TProtocolUtil.skip(iprot, field.type);
          }
          break;
        case 2: // STREAM_ID
          if (field.type == TType.I32) {
            this.streamId = iprot.readI32();
            set_streamId_isSet(true);
          } else { 
            TProtocolUtil.skip(iprot, field.type);
          }
          break;
        default:
          TProtocolUtil.skip(iprot, field.type);
      }
      iprot.readFieldEnd();
    }
    iprot.readStructEnd();
    validate();
  }

  public void write(TProtocol oprot) throws TException {
    validate();

    oprot.writeStructBegin(STRUCT_DESC);
    oprot.writeFieldBegin(COMPONENT_ID_FIELD_DESC);
    oprot.writeI32(this.componentId);
    oprot.writeFieldEnd();
    oprot.writeFieldBegin(STREAM_ID_FIELD_DESC);
    oprot.writeI32(this.streamId);
    oprot.writeFieldEnd();
    oprot.writeFieldStop();
    oprot.writeStructEnd();
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("GlobalStreamId(");
    boolean first = true;

    sb.append("componentId:");
    sb.append(this.componentId);
    first = false;
    if (!first) sb.append(", ");
    sb.append("streamId:");
    sb.append(this.streamId);
    first = false;
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws TException {
    // check for required fields
    if (!is_set_componentId()) {
      throw new TProtocolException("Required field 'componentId' is unset! Struct:" + toString());
    }

    if (!is_set_streamId()) {
      throw new TProtocolException("Required field 'streamId' is unset! Struct:" + toString());
    }

  }

}

