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

  private static final org.apache.storm.thrift.protocol.TField METRIC_NAME_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("metricName", org.apache.storm.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.storm.thrift.protocol.TField TIMESTAMP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("timestamp", org.apache.storm.thrift.protocol.TType.I64, (short)2);
  private static final org.apache.storm.thrift.protocol.TField METRIC_VALUE_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("metricValue", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)3);
  private static final org.apache.storm.thrift.protocol.TField COMPONENT_ID_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("componentId", org.apache.storm.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.storm.thrift.protocol.TField EXECUTOR_ID_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("executorId", org.apache.storm.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.storm.thrift.protocol.TField STREAM_ID_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("streamId", org.apache.storm.thrift.protocol.TType.STRING, (short)6);

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

  private @org.apache.storm.thrift.annotation.Nullable java.lang.String metricName; // required
  private long timestamp; // required
  private double metricValue; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String componentId; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String executorId; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String streamId; // 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 {
    METRIC_NAME((short)1, "metricName"),
    TIMESTAMP((short)2, "timestamp"),
    METRIC_VALUE((short)3, "metricValue"),
    COMPONENT_ID((short)4, "componentId"),
    EXECUTOR_ID((short)5, "executorId"),
    STREAM_ID((short)6, "streamId");

    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: // METRIC_NAME
          return METRIC_NAME;
        case 2: // TIMESTAMP
          return TIMESTAMP;
        case 3: // METRIC_VALUE
          return METRIC_VALUE;
        case 4: // COMPONENT_ID
          return COMPONENT_ID;
        case 5: // EXECUTOR_ID
          return EXECUTOR_ID;
        case 6: // 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 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
  private static final int __TIMESTAMP_ISSET_ID = 0;
  private static final int __METRICVALUE_ISSET_ID = 1;
  private byte __isset_bitfield = 0;
  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.METRIC_NAME, new org.apache.storm.thrift.meta_data.FieldMetaData("metricName", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TIMESTAMP, new org.apache.storm.thrift.meta_data.FieldMetaData("timestamp", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.METRIC_VALUE, new org.apache.storm.thrift.meta_data.FieldMetaData("metricValue", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.COMPONENT_ID, new org.apache.storm.thrift.meta_data.FieldMetaData("componentId", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.EXECUTOR_ID, new org.apache.storm.thrift.meta_data.FieldMetaData("executorId", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.STREAM_ID, new org.apache.storm.thrift.meta_data.FieldMetaData("streamId", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(WorkerMetricPoint.class, metaDataMap);
  }

  public WorkerMetricPoint() {
  }

  public WorkerMetricPoint(
    java.lang.String metricName,
    long timestamp,
    double metricValue,
    java.lang.String componentId,
    java.lang.String executorId,
    java.lang.String streamId)
  {
    this();
    this.metricName = metricName;
    this.timestamp = timestamp;
    set_timestamp_isSet(true);
    this.metricValue = metricValue;
    set_metricValue_isSet(true);
    this.componentId = componentId;
    this.executorId = executorId;
    this.streamId = streamId;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public WorkerMetricPoint(WorkerMetricPoint other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.is_set_metricName()) {
      this.metricName = other.metricName;
    }
    this.timestamp = other.timestamp;
    this.metricValue = other.metricValue;
    if (other.is_set_componentId()) {
      this.componentId = other.componentId;
    }
    if (other.is_set_executorId()) {
      this.executorId = other.executorId;
    }
    if (other.is_set_streamId()) {
      this.streamId = other.streamId;
    }
  }

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

  @Override
  public void clear() {
    this.metricName = null;
    set_timestamp_isSet(false);
    this.timestamp = 0;
    set_metricValue_isSet(false);
    this.metricValue = 0.0;
    this.componentId = null;
    this.executorId = null;
    this.streamId = null;
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.lang.String get_metricName() {
    return this.metricName;
  }

  public void set_metricName(@org.apache.storm.thrift.annotation.Nullable java.lang.String metricName) {
    this.metricName = metricName;
  }

  public void unset_metricName() {
    this.metricName = null;
  }

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

  public void set_metricName_isSet(boolean value) {
    if (!value) {
      this.metricName = null;
    }
  }

  public long get_timestamp() {
    return this.timestamp;
  }

  public void set_timestamp(long timestamp) {
    this.timestamp = timestamp;
    set_timestamp_isSet(true);
  }

  public void unset_timestamp() {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.clearBit(__isset_bitfield, __TIMESTAMP_ISSET_ID);
  }

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

  public void set_timestamp_isSet(boolean value) {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.setBit(__isset_bitfield, __TIMESTAMP_ISSET_ID, value);
  }

  public double get_metricValue() {
    return this.metricValue;
  }

  public void set_metricValue(double metricValue) {
    this.metricValue = metricValue;
    set_metricValue_isSet(true);
  }

  public void unset_metricValue() {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.clearBit(__isset_bitfield, __METRICVALUE_ISSET_ID);
  }

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

  public void set_metricValue_isSet(boolean value) {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.setBit(__isset_bitfield, __METRICVALUE_ISSET_ID, value);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.lang.String get_componentId() {
    return this.componentId;
  }

  public void set_componentId(@org.apache.storm.thrift.annotation.Nullable java.lang.String componentId) {
    this.componentId = componentId;
  }

  public void unset_componentId() {
    this.componentId = null;
  }

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

  public void set_componentId_isSet(boolean value) {
    if (!value) {
      this.componentId = null;
    }
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.lang.String get_executorId() {
    return this.executorId;
  }

  public void set_executorId(@org.apache.storm.thrift.annotation.Nullable java.lang.String executorId) {
    this.executorId = executorId;
  }

  public void unset_executorId() {
    this.executorId = null;
  }

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

  public void set_executorId_isSet(boolean value) {
    if (!value) {
      this.executorId = null;
    }
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.lang.String get_streamId() {
    return this.streamId;
  }

  public void set_streamId(@org.apache.storm.thrift.annotation.Nullable java.lang.String streamId) {
    this.streamId = streamId;
  }

  public void unset_streamId() {
    this.streamId = null;
  }

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

  public void set_streamId_isSet(boolean value) {
    if (!value) {
      this.streamId = null;
    }
  }

  public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case METRIC_NAME:
      if (value == null) {
        unset_metricName();
      } else {
        set_metricName((java.lang.String)value);
      }
      break;

    case TIMESTAMP:
      if (value == null) {
        unset_timestamp();
      } else {
        set_timestamp((java.lang.Long)value);
      }
      break;

    case METRIC_VALUE:
      if (value == null) {
        unset_metricValue();
      } else {
        set_metricValue((java.lang.Double)value);
      }
      break;

    case COMPONENT_ID:
      if (value == null) {
        unset_componentId();
      } else {
        set_componentId((java.lang.String)value);
      }
      break;

    case EXECUTOR_ID:
      if (value == null) {
        unset_executorId();
      } else {
        set_executorId((java.lang.String)value);
      }
      break;

    case STREAM_ID:
      if (value == null) {
        unset_streamId();
      } else {
        set_streamId((java.lang.String)value);
      }
      break;

    }
  }

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

    case TIMESTAMP:
      return get_timestamp();

    case METRIC_VALUE:
      return get_metricValue();

    case COMPONENT_ID:
      return get_componentId();

    case EXECUTOR_ID:
      return get_executorId();

    case STREAM_ID:
      return get_streamId();

    }
    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 METRIC_NAME:
      return is_set_metricName();
    case TIMESTAMP:
      return is_set_timestamp();
    case METRIC_VALUE:
      return is_set_metricValue();
    case COMPONENT_ID:
      return is_set_componentId();
    case EXECUTOR_ID:
      return is_set_executorId();
    case STREAM_ID:
      return is_set_streamId();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_metricName = true && this.is_set_metricName();
    boolean that_present_metricName = true && that.is_set_metricName();
    if (this_present_metricName || that_present_metricName) {
      if (!(this_present_metricName && that_present_metricName))
        return false;
      if (!this.metricName.equals(that.metricName))
        return false;
    }

    boolean this_present_timestamp = true;
    boolean that_present_timestamp = true;
    if (this_present_timestamp || that_present_timestamp) {
      if (!(this_present_timestamp && that_present_timestamp))
        return false;
      if (this.timestamp != that.timestamp)
        return false;
    }

    boolean this_present_metricValue = true;
    boolean that_present_metricValue = true;
    if (this_present_metricValue || that_present_metricValue) {
      if (!(this_present_metricValue && that_present_metricValue))
        return false;
      if (this.metricValue != that.metricValue)
        return false;
    }

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

    boolean this_present_executorId = true && this.is_set_executorId();
    boolean that_present_executorId = true && that.is_set_executorId();
    if (this_present_executorId || that_present_executorId) {
      if (!(this_present_executorId && that_present_executorId))
        return false;
      if (!this.executorId.equals(that.executorId))
        return false;
    }

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

    return true;
  }

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

    hashCode = hashCode * 8191 + ((is_set_metricName()) ? 131071 : 524287);
    if (is_set_metricName())
      hashCode = hashCode * 8191 + metricName.hashCode();

    hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(timestamp);

    hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(metricValue);

    hashCode = hashCode * 8191 + ((is_set_componentId()) ? 131071 : 524287);
    if (is_set_componentId())
      hashCode = hashCode * 8191 + componentId.hashCode();

    hashCode = hashCode * 8191 + ((is_set_executorId()) ? 131071 : 524287);
    if (is_set_executorId())
      hashCode = hashCode * 8191 + executorId.hashCode();

    hashCode = hashCode * 8191 + ((is_set_streamId()) ? 131071 : 524287);
    if (is_set_streamId())
      hashCode = hashCode * 8191 + streamId.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(is_set_metricName()).compareTo(other.is_set_metricName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_metricName()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.metricName, other.metricName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_timestamp()).compareTo(other.is_set_timestamp());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_timestamp()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.timestamp, other.timestamp);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_metricValue()).compareTo(other.is_set_metricValue());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_metricValue()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.metricValue, other.metricValue);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_componentId()).compareTo(other.is_set_componentId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_componentId()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.componentId, other.componentId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_executorId()).compareTo(other.is_set_executorId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_executorId()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.executorId, other.executorId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_streamId()).compareTo(other.is_set_streamId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_streamId()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.streamId, other.streamId);
      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("WorkerMetricPoint(");
    boolean first = true;

    sb.append("metricName:");
    if (this.metricName == null) {
      sb.append("null");
    } else {
      sb.append(this.metricName);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("timestamp:");
    sb.append(this.timestamp);
    first = false;
    if (!first) sb.append(", ");
    sb.append("metricValue:");
    sb.append(this.metricValue);
    first = false;
    if (!first) sb.append(", ");
    sb.append("componentId:");
    if (this.componentId == null) {
      sb.append("null");
    } else {
      sb.append(this.componentId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("executorId:");
    if (this.executorId == null) {
      sb.append("null");
    } else {
      sb.append(this.executorId);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("streamId:");
    if (this.streamId == null) {
      sb.append("null");
    } else {
      sb.append(this.streamId);
    }
    first = false;
    sb.append(")");
    return sb.toString();
  }

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

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

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

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

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

    if (!is_set_streamId()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'streamId' 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 {
      // 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.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 WorkerMetricPointStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public WorkerMetricPointStandardScheme getScheme() {
      return new WorkerMetricPointStandardScheme();
    }
  }

  private static class WorkerMetricPointStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<WorkerMetricPoint> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, WorkerMetricPoint 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: // METRIC_NAME
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.metricName = iprot.readString();
              struct.set_metricName_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // TIMESTAMP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I64) {
              struct.timestamp = iprot.readI64();
              struct.set_timestamp_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // METRIC_VALUE
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.metricValue = iprot.readDouble();
              struct.set_metricValue_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // COMPONENT_ID
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.componentId = iprot.readString();
              struct.set_componentId_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // EXECUTOR_ID
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.executorId = iprot.readString();
              struct.set_executorId_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // STREAM_ID
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.streamId = iprot.readString();
              struct.set_streamId_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, WorkerMetricPoint struct) throws org.apache.storm.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.metricName != null) {
        oprot.writeFieldBegin(METRIC_NAME_FIELD_DESC);
        oprot.writeString(struct.metricName);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(TIMESTAMP_FIELD_DESC);
      oprot.writeI64(struct.timestamp);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(METRIC_VALUE_FIELD_DESC);
      oprot.writeDouble(struct.metricValue);
      oprot.writeFieldEnd();
      if (struct.componentId != null) {
        oprot.writeFieldBegin(COMPONENT_ID_FIELD_DESC);
        oprot.writeString(struct.componentId);
        oprot.writeFieldEnd();
      }
      if (struct.executorId != null) {
        oprot.writeFieldBegin(EXECUTOR_ID_FIELD_DESC);
        oprot.writeString(struct.executorId);
        oprot.writeFieldEnd();
      }
      if (struct.streamId != null) {
        oprot.writeFieldBegin(STREAM_ID_FIELD_DESC);
        oprot.writeString(struct.streamId);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class WorkerMetricPointTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<WorkerMetricPoint> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, WorkerMetricPoint struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.metricName);
      oprot.writeI64(struct.timestamp);
      oprot.writeDouble(struct.metricValue);
      oprot.writeString(struct.componentId);
      oprot.writeString(struct.executorId);
      oprot.writeString(struct.streamId);
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, WorkerMetricPoint struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      struct.metricName = iprot.readString();
      struct.set_metricName_isSet(true);
      struct.timestamp = iprot.readI64();
      struct.set_timestamp_isSet(true);
      struct.metricValue = iprot.readDouble();
      struct.set_metricValue_isSet(true);
      struct.componentId = iprot.readString();
      struct.set_componentId_isSet(true);
      struct.executorId = iprot.readString();
      struct.set_executorId_isSet(true);
      struct.streamId = iprot.readString();
      struct.set_streamId_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();
  }
}

