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

import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.AbstractNonblockingServer.*;
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.nio.ByteBuffer;
import java.util.Arrays;
import javax.annotation.Generated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2015-10-20")
public class TopologyMetric implements org.apache.thrift.TBase<TopologyMetric, TopologyMetric._Fields>, java.io.Serializable, Cloneable, Comparable<TopologyMetric> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TopologyMetric");

  private static final org.apache.thrift.protocol.TField TOPOLOGY_METRIC_FIELD_DESC = new org.apache.thrift.protocol.TField("topologyMetric", org.apache.thrift.protocol.TType.STRUCT, (short)1);
  private static final org.apache.thrift.protocol.TField COMPONENT_METRIC_FIELD_DESC = new org.apache.thrift.protocol.TField("componentMetric", org.apache.thrift.protocol.TType.STRUCT, (short)2);
  private static final org.apache.thrift.protocol.TField WORKER_METRIC_FIELD_DESC = new org.apache.thrift.protocol.TField("workerMetric", org.apache.thrift.protocol.TType.STRUCT, (short)3);
  private static final org.apache.thrift.protocol.TField TASK_METRIC_FIELD_DESC = new org.apache.thrift.protocol.TField("taskMetric", org.apache.thrift.protocol.TType.STRUCT, (short)4);
  private static final org.apache.thrift.protocol.TField STREAM_METRIC_FIELD_DESC = new org.apache.thrift.protocol.TField("streamMetric", org.apache.thrift.protocol.TType.STRUCT, (short)5);
  private static final org.apache.thrift.protocol.TField NETTY_METRIC_FIELD_DESC = new org.apache.thrift.protocol.TField("nettyMetric", org.apache.thrift.protocol.TType.STRUCT, (short)6);

  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
  static {
    schemes.put(StandardScheme.class, new TopologyMetricStandardSchemeFactory());
    schemes.put(TupleScheme.class, new TopologyMetricTupleSchemeFactory());
  }

  private MetricInfo topologyMetric; // required
  private MetricInfo componentMetric; // required
  private MetricInfo workerMetric; // required
  private MetricInfo taskMetric; // required
  private MetricInfo streamMetric; // required
  private MetricInfo nettyMetric; // 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 {
    TOPOLOGY_METRIC((short)1, "topologyMetric"),
    COMPONENT_METRIC((short)2, "componentMetric"),
    WORKER_METRIC((short)3, "workerMetric"),
    TASK_METRIC((short)4, "taskMetric"),
    STREAM_METRIC((short)5, "streamMetric"),
    NETTY_METRIC((short)6, "nettyMetric");

    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: // TOPOLOGY_METRIC
          return TOPOLOGY_METRIC;
        case 2: // COMPONENT_METRIC
          return COMPONENT_METRIC;
        case 3: // WORKER_METRIC
          return WORKER_METRIC;
        case 4: // TASK_METRIC
          return TASK_METRIC;
        case 5: // STREAM_METRIC
          return STREAM_METRIC;
        case 6: // NETTY_METRIC
          return NETTY_METRIC;
        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
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.TOPOLOGY_METRIC, new org.apache.thrift.meta_data.FieldMetaData("topologyMetric", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, MetricInfo.class)));
    tmpMap.put(_Fields.COMPONENT_METRIC, new org.apache.thrift.meta_data.FieldMetaData("componentMetric", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, MetricInfo.class)));
    tmpMap.put(_Fields.WORKER_METRIC, new org.apache.thrift.meta_data.FieldMetaData("workerMetric", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, MetricInfo.class)));
    tmpMap.put(_Fields.TASK_METRIC, new org.apache.thrift.meta_data.FieldMetaData("taskMetric", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, MetricInfo.class)));
    tmpMap.put(_Fields.STREAM_METRIC, new org.apache.thrift.meta_data.FieldMetaData("streamMetric", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, MetricInfo.class)));
    tmpMap.put(_Fields.NETTY_METRIC, new org.apache.thrift.meta_data.FieldMetaData("nettyMetric", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, MetricInfo.class)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TopologyMetric.class, metaDataMap);
  }

  public TopologyMetric() {
  }

  public TopologyMetric(
    MetricInfo topologyMetric,
    MetricInfo componentMetric,
    MetricInfo workerMetric,
    MetricInfo taskMetric,
    MetricInfo streamMetric,
    MetricInfo nettyMetric)
  {
    this();
    this.topologyMetric = topologyMetric;
    this.componentMetric = componentMetric;
    this.workerMetric = workerMetric;
    this.taskMetric = taskMetric;
    this.streamMetric = streamMetric;
    this.nettyMetric = nettyMetric;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TopologyMetric(TopologyMetric other) {
    if (other.is_set_topologyMetric()) {
      this.topologyMetric = new MetricInfo(other.topologyMetric);
    }
    if (other.is_set_componentMetric()) {
      this.componentMetric = new MetricInfo(other.componentMetric);
    }
    if (other.is_set_workerMetric()) {
      this.workerMetric = new MetricInfo(other.workerMetric);
    }
    if (other.is_set_taskMetric()) {
      this.taskMetric = new MetricInfo(other.taskMetric);
    }
    if (other.is_set_streamMetric()) {
      this.streamMetric = new MetricInfo(other.streamMetric);
    }
    if (other.is_set_nettyMetric()) {
      this.nettyMetric = new MetricInfo(other.nettyMetric);
    }
  }

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

  @Override
  public void clear() {
    this.topologyMetric = null;
    this.componentMetric = null;
    this.workerMetric = null;
    this.taskMetric = null;
    this.streamMetric = null;
    this.nettyMetric = null;
  }

  public MetricInfo get_topologyMetric() {
    return this.topologyMetric;
  }

  public void set_topologyMetric(MetricInfo topologyMetric) {
    this.topologyMetric = topologyMetric;
  }

  public void unset_topologyMetric() {
    this.topologyMetric = null;
  }

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

  public void set_topologyMetric_isSet(boolean value) {
    if (!value) {
      this.topologyMetric = null;
    }
  }

  public MetricInfo get_componentMetric() {
    return this.componentMetric;
  }

  public void set_componentMetric(MetricInfo componentMetric) {
    this.componentMetric = componentMetric;
  }

  public void unset_componentMetric() {
    this.componentMetric = null;
  }

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

  public void set_componentMetric_isSet(boolean value) {
    if (!value) {
      this.componentMetric = null;
    }
  }

  public MetricInfo get_workerMetric() {
    return this.workerMetric;
  }

  public void set_workerMetric(MetricInfo workerMetric) {
    this.workerMetric = workerMetric;
  }

  public void unset_workerMetric() {
    this.workerMetric = null;
  }

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

  public void set_workerMetric_isSet(boolean value) {
    if (!value) {
      this.workerMetric = null;
    }
  }

  public MetricInfo get_taskMetric() {
    return this.taskMetric;
  }

  public void set_taskMetric(MetricInfo taskMetric) {
    this.taskMetric = taskMetric;
  }

  public void unset_taskMetric() {
    this.taskMetric = null;
  }

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

  public void set_taskMetric_isSet(boolean value) {
    if (!value) {
      this.taskMetric = null;
    }
  }

  public MetricInfo get_streamMetric() {
    return this.streamMetric;
  }

  public void set_streamMetric(MetricInfo streamMetric) {
    this.streamMetric = streamMetric;
  }

  public void unset_streamMetric() {
    this.streamMetric = null;
  }

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

  public void set_streamMetric_isSet(boolean value) {
    if (!value) {
      this.streamMetric = null;
    }
  }

  public MetricInfo get_nettyMetric() {
    return this.nettyMetric;
  }

  public void set_nettyMetric(MetricInfo nettyMetric) {
    this.nettyMetric = nettyMetric;
  }

  public void unset_nettyMetric() {
    this.nettyMetric = null;
  }

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

  public void set_nettyMetric_isSet(boolean value) {
    if (!value) {
      this.nettyMetric = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case TOPOLOGY_METRIC:
      if (value == null) {
        unset_topologyMetric();
      } else {
        set_topologyMetric((MetricInfo)value);
      }
      break;

    case COMPONENT_METRIC:
      if (value == null) {
        unset_componentMetric();
      } else {
        set_componentMetric((MetricInfo)value);
      }
      break;

    case WORKER_METRIC:
      if (value == null) {
        unset_workerMetric();
      } else {
        set_workerMetric((MetricInfo)value);
      }
      break;

    case TASK_METRIC:
      if (value == null) {
        unset_taskMetric();
      } else {
        set_taskMetric((MetricInfo)value);
      }
      break;

    case STREAM_METRIC:
      if (value == null) {
        unset_streamMetric();
      } else {
        set_streamMetric((MetricInfo)value);
      }
      break;

    case NETTY_METRIC:
      if (value == null) {
        unset_nettyMetric();
      } else {
        set_nettyMetric((MetricInfo)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case TOPOLOGY_METRIC:
      return get_topologyMetric();

    case COMPONENT_METRIC:
      return get_componentMetric();

    case WORKER_METRIC:
      return get_workerMetric();

    case TASK_METRIC:
      return get_taskMetric();

    case STREAM_METRIC:
      return get_streamMetric();

    case NETTY_METRIC:
      return get_nettyMetric();

    }
    throw new 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 IllegalArgumentException();
    }

    switch (field) {
    case TOPOLOGY_METRIC:
      return is_set_topologyMetric();
    case COMPONENT_METRIC:
      return is_set_componentMetric();
    case WORKER_METRIC:
      return is_set_workerMetric();
    case TASK_METRIC:
      return is_set_taskMetric();
    case STREAM_METRIC:
      return is_set_streamMetric();
    case NETTY_METRIC:
      return is_set_nettyMetric();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_topologyMetric = true && this.is_set_topologyMetric();
    boolean that_present_topologyMetric = true && that.is_set_topologyMetric();
    if (this_present_topologyMetric || that_present_topologyMetric) {
      if (!(this_present_topologyMetric && that_present_topologyMetric))
        return false;
      if (!this.topologyMetric.equals(that.topologyMetric))
        return false;
    }

    boolean this_present_componentMetric = true && this.is_set_componentMetric();
    boolean that_present_componentMetric = true && that.is_set_componentMetric();
    if (this_present_componentMetric || that_present_componentMetric) {
      if (!(this_present_componentMetric && that_present_componentMetric))
        return false;
      if (!this.componentMetric.equals(that.componentMetric))
        return false;
    }

    boolean this_present_workerMetric = true && this.is_set_workerMetric();
    boolean that_present_workerMetric = true && that.is_set_workerMetric();
    if (this_present_workerMetric || that_present_workerMetric) {
      if (!(this_present_workerMetric && that_present_workerMetric))
        return false;
      if (!this.workerMetric.equals(that.workerMetric))
        return false;
    }

    boolean this_present_taskMetric = true && this.is_set_taskMetric();
    boolean that_present_taskMetric = true && that.is_set_taskMetric();
    if (this_present_taskMetric || that_present_taskMetric) {
      if (!(this_present_taskMetric && that_present_taskMetric))
        return false;
      if (!this.taskMetric.equals(that.taskMetric))
        return false;
    }

    boolean this_present_streamMetric = true && this.is_set_streamMetric();
    boolean that_present_streamMetric = true && that.is_set_streamMetric();
    if (this_present_streamMetric || that_present_streamMetric) {
      if (!(this_present_streamMetric && that_present_streamMetric))
        return false;
      if (!this.streamMetric.equals(that.streamMetric))
        return false;
    }

    boolean this_present_nettyMetric = true && this.is_set_nettyMetric();
    boolean that_present_nettyMetric = true && that.is_set_nettyMetric();
    if (this_present_nettyMetric || that_present_nettyMetric) {
      if (!(this_present_nettyMetric && that_present_nettyMetric))
        return false;
      if (!this.nettyMetric.equals(that.nettyMetric))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    List<Object> list = new ArrayList<Object>();

    boolean present_topologyMetric = true && (is_set_topologyMetric());
    list.add(present_topologyMetric);
    if (present_topologyMetric)
      list.add(topologyMetric);

    boolean present_componentMetric = true && (is_set_componentMetric());
    list.add(present_componentMetric);
    if (present_componentMetric)
      list.add(componentMetric);

    boolean present_workerMetric = true && (is_set_workerMetric());
    list.add(present_workerMetric);
    if (present_workerMetric)
      list.add(workerMetric);

    boolean present_taskMetric = true && (is_set_taskMetric());
    list.add(present_taskMetric);
    if (present_taskMetric)
      list.add(taskMetric);

    boolean present_streamMetric = true && (is_set_streamMetric());
    list.add(present_streamMetric);
    if (present_streamMetric)
      list.add(streamMetric);

    boolean present_nettyMetric = true && (is_set_nettyMetric());
    list.add(present_nettyMetric);
    if (present_nettyMetric)
      list.add(nettyMetric);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(is_set_topologyMetric()).compareTo(other.is_set_topologyMetric());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topologyMetric()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.topologyMetric, other.topologyMetric);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_componentMetric()).compareTo(other.is_set_componentMetric());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_componentMetric()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.componentMetric, other.componentMetric);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_workerMetric()).compareTo(other.is_set_workerMetric());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_workerMetric()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.workerMetric, other.workerMetric);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_taskMetric()).compareTo(other.is_set_taskMetric());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_taskMetric()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.taskMetric, other.taskMetric);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_streamMetric()).compareTo(other.is_set_streamMetric());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_streamMetric()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.streamMetric, other.streamMetric);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_nettyMetric()).compareTo(other.is_set_nettyMetric());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_nettyMetric()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nettyMetric, other.nettyMetric);
      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 TException {
    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
  }

  public void write(org.apache.thrift.protocol.TProtocol oprot) throws TException {
    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
  }

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

    sb.append("topologyMetric:");
    if (this.topologyMetric == null) {
      sb.append("null");
    } else {
      sb.append(this.topologyMetric);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("componentMetric:");
    if (this.componentMetric == null) {
      sb.append("null");
    } else {
      sb.append(this.componentMetric);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("workerMetric:");
    if (this.workerMetric == null) {
      sb.append("null");
    } else {
      sb.append(this.workerMetric);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("taskMetric:");
    if (this.taskMetric == null) {
      sb.append("null");
    } else {
      sb.append(this.taskMetric);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("streamMetric:");
    if (this.streamMetric == null) {
      sb.append("null");
    } else {
      sb.append(this.streamMetric);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("nettyMetric:");
    if (this.nettyMetric == null) {
      sb.append("null");
    } else {
      sb.append(this.nettyMetric);
    }
    first = false;
    sb.append(")");
    return sb.toString();
  }

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

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

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

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

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

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

    // check for sub-struct validity
    if (topologyMetric != null) {
      topologyMetric.validate();
    }
    if (componentMetric != null) {
      componentMetric.validate();
    }
    if (workerMetric != null) {
      workerMetric.validate();
    }
    if (taskMetric != null) {
      taskMetric.validate();
    }
    if (streamMetric != null) {
      streamMetric.validate();
    }
    if (nettyMetric != null) {
      nettyMetric.validate();
    }
  }

  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 (TException te) {
      throw new java.io.IOException(te);
    }
  }

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

  private static class TopologyMetricStandardSchemeFactory implements SchemeFactory {
    public TopologyMetricStandardScheme getScheme() {
      return new TopologyMetricStandardScheme();
    }
  }

  private static class TopologyMetricStandardScheme extends StandardScheme<TopologyMetric> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, TopologyMetric struct) throws 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: // TOPOLOGY_METRIC
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.topologyMetric = new MetricInfo();
              struct.topologyMetric.read(iprot);
              struct.set_topologyMetric_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // COMPONENT_METRIC
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.componentMetric = new MetricInfo();
              struct.componentMetric.read(iprot);
              struct.set_componentMetric_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // WORKER_METRIC
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.workerMetric = new MetricInfo();
              struct.workerMetric.read(iprot);
              struct.set_workerMetric_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // TASK_METRIC
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.taskMetric = new MetricInfo();
              struct.taskMetric.read(iprot);
              struct.set_taskMetric_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // STREAM_METRIC
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.streamMetric = new MetricInfo();
              struct.streamMetric.read(iprot);
              struct.set_streamMetric_isSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // NETTY_METRIC
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.nettyMetric = new MetricInfo();
              struct.nettyMetric.read(iprot);
              struct.set_nettyMetric_isSet(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, TopologyMetric struct) throws TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.topologyMetric != null) {
        oprot.writeFieldBegin(TOPOLOGY_METRIC_FIELD_DESC);
        struct.topologyMetric.write(oprot);
        oprot.writeFieldEnd();
      }
      if (struct.componentMetric != null) {
        oprot.writeFieldBegin(COMPONENT_METRIC_FIELD_DESC);
        struct.componentMetric.write(oprot);
        oprot.writeFieldEnd();
      }
      if (struct.workerMetric != null) {
        oprot.writeFieldBegin(WORKER_METRIC_FIELD_DESC);
        struct.workerMetric.write(oprot);
        oprot.writeFieldEnd();
      }
      if (struct.taskMetric != null) {
        oprot.writeFieldBegin(TASK_METRIC_FIELD_DESC);
        struct.taskMetric.write(oprot);
        oprot.writeFieldEnd();
      }
      if (struct.streamMetric != null) {
        oprot.writeFieldBegin(STREAM_METRIC_FIELD_DESC);
        struct.streamMetric.write(oprot);
        oprot.writeFieldEnd();
      }
      if (struct.nettyMetric != null) {
        oprot.writeFieldBegin(NETTY_METRIC_FIELD_DESC);
        struct.nettyMetric.write(oprot);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class TopologyMetricTupleSchemeFactory implements SchemeFactory {
    public TopologyMetricTupleScheme getScheme() {
      return new TopologyMetricTupleScheme();
    }
  }

  private static class TopologyMetricTupleScheme extends TupleScheme<TopologyMetric> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, TopologyMetric struct) throws TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      struct.topologyMetric.write(oprot);
      struct.componentMetric.write(oprot);
      struct.workerMetric.write(oprot);
      struct.taskMetric.write(oprot);
      struct.streamMetric.write(oprot);
      struct.nettyMetric.write(oprot);
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, TopologyMetric struct) throws TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.topologyMetric = new MetricInfo();
      struct.topologyMetric.read(iprot);
      struct.set_topologyMetric_isSet(true);
      struct.componentMetric = new MetricInfo();
      struct.componentMetric.read(iprot);
      struct.set_componentMetric_isSet(true);
      struct.workerMetric = new MetricInfo();
      struct.workerMetric.read(iprot);
      struct.set_workerMetric_isSet(true);
      struct.taskMetric = new MetricInfo();
      struct.taskMetric.read(iprot);
      struct.set_taskMetric_isSet(true);
      struct.streamMetric = new MetricInfo();
      struct.streamMetric.read(iprot);
      struct.set_streamMetric_isSet(true);
      struct.nettyMetric = new MetricInfo();
      struct.nettyMetric.read(iprot);
      struct.set_nettyMetric_isSet(true);
    }
  }

}

