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

  private static final org.apache.storm.thrift.protocol.TField ID_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("id", org.apache.storm.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.storm.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("name", org.apache.storm.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.storm.thrift.protocol.TField UPTIME_SECS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("uptime_secs", org.apache.storm.thrift.protocol.TType.I32, (short)3);
  private static final org.apache.storm.thrift.protocol.TField EXECUTORS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("executors", org.apache.storm.thrift.protocol.TType.LIST, (short)4);
  private static final org.apache.storm.thrift.protocol.TField STATUS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("status", org.apache.storm.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.storm.thrift.protocol.TField ERRORS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("errors", org.apache.storm.thrift.protocol.TType.MAP, (short)6);
  private static final org.apache.storm.thrift.protocol.TField COMPONENT_DEBUG_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("component_debug", org.apache.storm.thrift.protocol.TType.MAP, (short)7);
  private static final org.apache.storm.thrift.protocol.TField STORM_VERSION_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("storm_version", org.apache.storm.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.storm.thrift.protocol.TField SCHED_STATUS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("sched_status", org.apache.storm.thrift.protocol.TType.STRING, (short)513);
  private static final org.apache.storm.thrift.protocol.TField OWNER_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("owner", org.apache.storm.thrift.protocol.TType.STRING, (short)514);
  private static final org.apache.storm.thrift.protocol.TField REPLICATION_COUNT_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("replication_count", org.apache.storm.thrift.protocol.TType.I32, (short)515);
  private static final org.apache.storm.thrift.protocol.TField REQUESTED_MEMONHEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("requested_memonheap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)521);
  private static final org.apache.storm.thrift.protocol.TField REQUESTED_MEMOFFHEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("requested_memoffheap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)522);
  private static final org.apache.storm.thrift.protocol.TField REQUESTED_CPU_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("requested_cpu", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)523);
  private static final org.apache.storm.thrift.protocol.TField ASSIGNED_MEMONHEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("assigned_memonheap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)524);
  private static final org.apache.storm.thrift.protocol.TField ASSIGNED_MEMOFFHEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("assigned_memoffheap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)525);
  private static final org.apache.storm.thrift.protocol.TField ASSIGNED_CPU_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("assigned_cpu", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)526);

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

  private @org.apache.storm.thrift.annotation.Nullable java.lang.String id; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String name; // required
  private int uptime_secs; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.List<ExecutorSummary> executors; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String status; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.util.List<ErrorInfo>> errors; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,DebugOptions> component_debug; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String storm_version; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String sched_status; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String owner; // optional
  private int replication_count; // optional
  private double requested_memonheap; // optional
  private double requested_memoffheap; // optional
  private double requested_cpu; // optional
  private double assigned_memonheap; // optional
  private double assigned_memoffheap; // optional
  private double assigned_cpu; // optional

  /** 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 {
    ID((short)1, "id"),
    NAME((short)2, "name"),
    UPTIME_SECS((short)3, "uptime_secs"),
    EXECUTORS((short)4, "executors"),
    STATUS((short)5, "status"),
    ERRORS((short)6, "errors"),
    COMPONENT_DEBUG((short)7, "component_debug"),
    STORM_VERSION((short)8, "storm_version"),
    SCHED_STATUS((short)513, "sched_status"),
    OWNER((short)514, "owner"),
    REPLICATION_COUNT((short)515, "replication_count"),
    REQUESTED_MEMONHEAP((short)521, "requested_memonheap"),
    REQUESTED_MEMOFFHEAP((short)522, "requested_memoffheap"),
    REQUESTED_CPU((short)523, "requested_cpu"),
    ASSIGNED_MEMONHEAP((short)524, "assigned_memonheap"),
    ASSIGNED_MEMOFFHEAP((short)525, "assigned_memoffheap"),
    ASSIGNED_CPU((short)526, "assigned_cpu");

    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: // ID
          return ID;
        case 2: // NAME
          return NAME;
        case 3: // UPTIME_SECS
          return UPTIME_SECS;
        case 4: // EXECUTORS
          return EXECUTORS;
        case 5: // STATUS
          return STATUS;
        case 6: // ERRORS
          return ERRORS;
        case 7: // COMPONENT_DEBUG
          return COMPONENT_DEBUG;
        case 8: // STORM_VERSION
          return STORM_VERSION;
        case 513: // SCHED_STATUS
          return SCHED_STATUS;
        case 514: // OWNER
          return OWNER;
        case 515: // REPLICATION_COUNT
          return REPLICATION_COUNT;
        case 521: // REQUESTED_MEMONHEAP
          return REQUESTED_MEMONHEAP;
        case 522: // REQUESTED_MEMOFFHEAP
          return REQUESTED_MEMOFFHEAP;
        case 523: // REQUESTED_CPU
          return REQUESTED_CPU;
        case 524: // ASSIGNED_MEMONHEAP
          return ASSIGNED_MEMONHEAP;
        case 525: // ASSIGNED_MEMOFFHEAP
          return ASSIGNED_MEMOFFHEAP;
        case 526: // ASSIGNED_CPU
          return ASSIGNED_CPU;
        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 __UPTIME_SECS_ISSET_ID = 0;
  private static final int __REPLICATION_COUNT_ISSET_ID = 1;
  private static final int __REQUESTED_MEMONHEAP_ISSET_ID = 2;
  private static final int __REQUESTED_MEMOFFHEAP_ISSET_ID = 3;
  private static final int __REQUESTED_CPU_ISSET_ID = 4;
  private static final int __ASSIGNED_MEMONHEAP_ISSET_ID = 5;
  private static final int __ASSIGNED_MEMOFFHEAP_ISSET_ID = 6;
  private static final int __ASSIGNED_CPU_ISSET_ID = 7;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.COMPONENT_DEBUG,_Fields.STORM_VERSION,_Fields.SCHED_STATUS,_Fields.OWNER,_Fields.REPLICATION_COUNT,_Fields.REQUESTED_MEMONHEAP,_Fields.REQUESTED_MEMOFFHEAP,_Fields.REQUESTED_CPU,_Fields.ASSIGNED_MEMONHEAP,_Fields.ASSIGNED_MEMOFFHEAP,_Fields.ASSIGNED_CPU};
  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.ID, new org.apache.storm.thrift.meta_data.FieldMetaData("id", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.NAME, new org.apache.storm.thrift.meta_data.FieldMetaData("name", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.UPTIME_SECS, new org.apache.storm.thrift.meta_data.FieldMetaData("uptime_secs", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.EXECUTORS, new org.apache.storm.thrift.meta_data.FieldMetaData("executors", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
            new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, ExecutorSummary.class))));
    tmpMap.put(_Fields.STATUS, new org.apache.storm.thrift.meta_data.FieldMetaData("status", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.ERRORS, new org.apache.storm.thrift.meta_data.FieldMetaData("errors", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
            new org.apache.storm.thrift.meta_data.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
                new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, ErrorInfo.class)))));
    tmpMap.put(_Fields.COMPONENT_DEBUG, new org.apache.storm.thrift.meta_data.FieldMetaData("component_debug", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
            new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, DebugOptions.class))));
    tmpMap.put(_Fields.STORM_VERSION, new org.apache.storm.thrift.meta_data.FieldMetaData("storm_version", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.SCHED_STATUS, new org.apache.storm.thrift.meta_data.FieldMetaData("sched_status", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.OWNER, new org.apache.storm.thrift.meta_data.FieldMetaData("owner", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.REPLICATION_COUNT, new org.apache.storm.thrift.meta_data.FieldMetaData("replication_count", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.REQUESTED_MEMONHEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("requested_memonheap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.REQUESTED_MEMOFFHEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("requested_memoffheap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.REQUESTED_CPU, new org.apache.storm.thrift.meta_data.FieldMetaData("requested_cpu", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.ASSIGNED_MEMONHEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("assigned_memonheap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.ASSIGNED_MEMOFFHEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("assigned_memoffheap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.ASSIGNED_CPU, new org.apache.storm.thrift.meta_data.FieldMetaData("assigned_cpu", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TopologyInfo.class, metaDataMap);
  }

  public TopologyInfo() {
  }

  public TopologyInfo(
    java.lang.String id,
    java.lang.String name,
    int uptime_secs,
    java.util.List<ExecutorSummary> executors,
    java.lang.String status,
    java.util.Map<java.lang.String,java.util.List<ErrorInfo>> errors)
  {
    this();
    this.id = id;
    this.name = name;
    this.uptime_secs = uptime_secs;
    set_uptime_secs_isSet(true);
    this.executors = executors;
    this.status = status;
    this.errors = errors;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TopologyInfo(TopologyInfo other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.is_set_id()) {
      this.id = other.id;
    }
    if (other.is_set_name()) {
      this.name = other.name;
    }
    this.uptime_secs = other.uptime_secs;
    if (other.is_set_executors()) {
      java.util.List<ExecutorSummary> __this__executors = new java.util.ArrayList<ExecutorSummary>(other.executors.size());
      for (ExecutorSummary other_element : other.executors) {
        __this__executors.add(new ExecutorSummary(other_element));
      }
      this.executors = __this__executors;
    }
    if (other.is_set_status()) {
      this.status = other.status;
    }
    if (other.is_set_errors()) {
      java.util.Map<java.lang.String,java.util.List<ErrorInfo>> __this__errors = new java.util.HashMap<java.lang.String,java.util.List<ErrorInfo>>(other.errors.size());
      for (java.util.Map.Entry<java.lang.String, java.util.List<ErrorInfo>> other_element : other.errors.entrySet()) {

        java.lang.String other_element_key = other_element.getKey();
        java.util.List<ErrorInfo> other_element_value = other_element.getValue();

        java.lang.String __this__errors_copy_key = other_element_key;

        java.util.List<ErrorInfo> __this__errors_copy_value = new java.util.ArrayList<ErrorInfo>(other_element_value.size());
        for (ErrorInfo other_element_value_element : other_element_value) {
          __this__errors_copy_value.add(new ErrorInfo(other_element_value_element));
        }

        __this__errors.put(__this__errors_copy_key, __this__errors_copy_value);
      }
      this.errors = __this__errors;
    }
    if (other.is_set_component_debug()) {
      java.util.Map<java.lang.String,DebugOptions> __this__component_debug = new java.util.HashMap<java.lang.String,DebugOptions>(other.component_debug.size());
      for (java.util.Map.Entry<java.lang.String, DebugOptions> other_element : other.component_debug.entrySet()) {

        java.lang.String other_element_key = other_element.getKey();
        DebugOptions other_element_value = other_element.getValue();

        java.lang.String __this__component_debug_copy_key = other_element_key;

        DebugOptions __this__component_debug_copy_value = new DebugOptions(other_element_value);

        __this__component_debug.put(__this__component_debug_copy_key, __this__component_debug_copy_value);
      }
      this.component_debug = __this__component_debug;
    }
    if (other.is_set_storm_version()) {
      this.storm_version = other.storm_version;
    }
    if (other.is_set_sched_status()) {
      this.sched_status = other.sched_status;
    }
    if (other.is_set_owner()) {
      this.owner = other.owner;
    }
    this.replication_count = other.replication_count;
    this.requested_memonheap = other.requested_memonheap;
    this.requested_memoffheap = other.requested_memoffheap;
    this.requested_cpu = other.requested_cpu;
    this.assigned_memonheap = other.assigned_memonheap;
    this.assigned_memoffheap = other.assigned_memoffheap;
    this.assigned_cpu = other.assigned_cpu;
  }

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

  @Override
  public void clear() {
    this.id = null;
    this.name = null;
    set_uptime_secs_isSet(false);
    this.uptime_secs = 0;
    this.executors = null;
    this.status = null;
    this.errors = null;
    this.component_debug = null;
    this.storm_version = null;
    this.sched_status = null;
    this.owner = null;
    set_replication_count_isSet(false);
    this.replication_count = 0;
    set_requested_memonheap_isSet(false);
    this.requested_memonheap = 0.0;
    set_requested_memoffheap_isSet(false);
    this.requested_memoffheap = 0.0;
    set_requested_cpu_isSet(false);
    this.requested_cpu = 0.0;
    set_assigned_memonheap_isSet(false);
    this.assigned_memonheap = 0.0;
    set_assigned_memoffheap_isSet(false);
    this.assigned_memoffheap = 0.0;
    set_assigned_cpu_isSet(false);
    this.assigned_cpu = 0.0;
  }

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

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

  public void unset_id() {
    this.id = null;
  }

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

  public void set_id_isSet(boolean value) {
    if (!value) {
      this.id = null;
    }
  }

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

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

  public void unset_name() {
    this.name = null;
  }

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

  public void set_name_isSet(boolean value) {
    if (!value) {
      this.name = null;
    }
  }

  public int get_uptime_secs() {
    return this.uptime_secs;
  }

  public void set_uptime_secs(int uptime_secs) {
    this.uptime_secs = uptime_secs;
    set_uptime_secs_isSet(true);
  }

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

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

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

  public int get_executors_size() {
    return (this.executors == null) ? 0 : this.executors.size();
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Iterator<ExecutorSummary> get_executors_iterator() {
    return (this.executors == null) ? null : this.executors.iterator();
  }

  public void add_to_executors(ExecutorSummary elem) {
    if (this.executors == null) {
      this.executors = new java.util.ArrayList<ExecutorSummary>();
    }
    this.executors.add(elem);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.List<ExecutorSummary> get_executors() {
    return this.executors;
  }

  public void set_executors(@org.apache.storm.thrift.annotation.Nullable java.util.List<ExecutorSummary> executors) {
    this.executors = executors;
  }

  public void unset_executors() {
    this.executors = null;
  }

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

  public void set_executors_isSet(boolean value) {
    if (!value) {
      this.executors = null;
    }
  }

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

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

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

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

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

  public int get_errors_size() {
    return (this.errors == null) ? 0 : this.errors.size();
  }

  public void put_to_errors(java.lang.String key, java.util.List<ErrorInfo> val) {
    if (this.errors == null) {
      this.errors = new java.util.HashMap<java.lang.String,java.util.List<ErrorInfo>>();
    }
    this.errors.put(key, val);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Map<java.lang.String,java.util.List<ErrorInfo>> get_errors() {
    return this.errors;
  }

  public void set_errors(@org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.util.List<ErrorInfo>> errors) {
    this.errors = errors;
  }

  public void unset_errors() {
    this.errors = null;
  }

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

  public void set_errors_isSet(boolean value) {
    if (!value) {
      this.errors = null;
    }
  }

  public int get_component_debug_size() {
    return (this.component_debug == null) ? 0 : this.component_debug.size();
  }

  public void put_to_component_debug(java.lang.String key, DebugOptions val) {
    if (this.component_debug == null) {
      this.component_debug = new java.util.HashMap<java.lang.String,DebugOptions>();
    }
    this.component_debug.put(key, val);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Map<java.lang.String,DebugOptions> get_component_debug() {
    return this.component_debug;
  }

  public void set_component_debug(@org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,DebugOptions> component_debug) {
    this.component_debug = component_debug;
  }

  public void unset_component_debug() {
    this.component_debug = null;
  }

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

  public void set_component_debug_isSet(boolean value) {
    if (!value) {
      this.component_debug = null;
    }
  }

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

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

  public void unset_storm_version() {
    this.storm_version = null;
  }

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

  public void set_storm_version_isSet(boolean value) {
    if (!value) {
      this.storm_version = null;
    }
  }

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

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

  public void unset_sched_status() {
    this.sched_status = null;
  }

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

  public void set_sched_status_isSet(boolean value) {
    if (!value) {
      this.sched_status = null;
    }
  }

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

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

  public void unset_owner() {
    this.owner = null;
  }

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

  public void set_owner_isSet(boolean value) {
    if (!value) {
      this.owner = null;
    }
  }

  public int get_replication_count() {
    return this.replication_count;
  }

  public void set_replication_count(int replication_count) {
    this.replication_count = replication_count;
    set_replication_count_isSet(true);
  }

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

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

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

  public double get_requested_memonheap() {
    return this.requested_memonheap;
  }

  public void set_requested_memonheap(double requested_memonheap) {
    this.requested_memonheap = requested_memonheap;
    set_requested_memonheap_isSet(true);
  }

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

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

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

  public double get_requested_memoffheap() {
    return this.requested_memoffheap;
  }

  public void set_requested_memoffheap(double requested_memoffheap) {
    this.requested_memoffheap = requested_memoffheap;
    set_requested_memoffheap_isSet(true);
  }

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

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

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

  public double get_requested_cpu() {
    return this.requested_cpu;
  }

  public void set_requested_cpu(double requested_cpu) {
    this.requested_cpu = requested_cpu;
    set_requested_cpu_isSet(true);
  }

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

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

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

  public double get_assigned_memonheap() {
    return this.assigned_memonheap;
  }

  public void set_assigned_memonheap(double assigned_memonheap) {
    this.assigned_memonheap = assigned_memonheap;
    set_assigned_memonheap_isSet(true);
  }

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

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

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

  public double get_assigned_memoffheap() {
    return this.assigned_memoffheap;
  }

  public void set_assigned_memoffheap(double assigned_memoffheap) {
    this.assigned_memoffheap = assigned_memoffheap;
    set_assigned_memoffheap_isSet(true);
  }

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

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

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

  public double get_assigned_cpu() {
    return this.assigned_cpu;
  }

  public void set_assigned_cpu(double assigned_cpu) {
    this.assigned_cpu = assigned_cpu;
    set_assigned_cpu_isSet(true);
  }

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

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

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

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

    case NAME:
      if (value == null) {
        unset_name();
      } else {
        set_name((java.lang.String)value);
      }
      break;

    case UPTIME_SECS:
      if (value == null) {
        unset_uptime_secs();
      } else {
        set_uptime_secs((java.lang.Integer)value);
      }
      break;

    case EXECUTORS:
      if (value == null) {
        unset_executors();
      } else {
        set_executors((java.util.List<ExecutorSummary>)value);
      }
      break;

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

    case ERRORS:
      if (value == null) {
        unset_errors();
      } else {
        set_errors((java.util.Map<java.lang.String,java.util.List<ErrorInfo>>)value);
      }
      break;

    case COMPONENT_DEBUG:
      if (value == null) {
        unset_component_debug();
      } else {
        set_component_debug((java.util.Map<java.lang.String,DebugOptions>)value);
      }
      break;

    case STORM_VERSION:
      if (value == null) {
        unset_storm_version();
      } else {
        set_storm_version((java.lang.String)value);
      }
      break;

    case SCHED_STATUS:
      if (value == null) {
        unset_sched_status();
      } else {
        set_sched_status((java.lang.String)value);
      }
      break;

    case OWNER:
      if (value == null) {
        unset_owner();
      } else {
        set_owner((java.lang.String)value);
      }
      break;

    case REPLICATION_COUNT:
      if (value == null) {
        unset_replication_count();
      } else {
        set_replication_count((java.lang.Integer)value);
      }
      break;

    case REQUESTED_MEMONHEAP:
      if (value == null) {
        unset_requested_memonheap();
      } else {
        set_requested_memonheap((java.lang.Double)value);
      }
      break;

    case REQUESTED_MEMOFFHEAP:
      if (value == null) {
        unset_requested_memoffheap();
      } else {
        set_requested_memoffheap((java.lang.Double)value);
      }
      break;

    case REQUESTED_CPU:
      if (value == null) {
        unset_requested_cpu();
      } else {
        set_requested_cpu((java.lang.Double)value);
      }
      break;

    case ASSIGNED_MEMONHEAP:
      if (value == null) {
        unset_assigned_memonheap();
      } else {
        set_assigned_memonheap((java.lang.Double)value);
      }
      break;

    case ASSIGNED_MEMOFFHEAP:
      if (value == null) {
        unset_assigned_memoffheap();
      } else {
        set_assigned_memoffheap((java.lang.Double)value);
      }
      break;

    case ASSIGNED_CPU:
      if (value == null) {
        unset_assigned_cpu();
      } else {
        set_assigned_cpu((java.lang.Double)value);
      }
      break;

    }
  }

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

    case NAME:
      return get_name();

    case UPTIME_SECS:
      return get_uptime_secs();

    case EXECUTORS:
      return get_executors();

    case STATUS:
      return get_status();

    case ERRORS:
      return get_errors();

    case COMPONENT_DEBUG:
      return get_component_debug();

    case STORM_VERSION:
      return get_storm_version();

    case SCHED_STATUS:
      return get_sched_status();

    case OWNER:
      return get_owner();

    case REPLICATION_COUNT:
      return get_replication_count();

    case REQUESTED_MEMONHEAP:
      return get_requested_memonheap();

    case REQUESTED_MEMOFFHEAP:
      return get_requested_memoffheap();

    case REQUESTED_CPU:
      return get_requested_cpu();

    case ASSIGNED_MEMONHEAP:
      return get_assigned_memonheap();

    case ASSIGNED_MEMOFFHEAP:
      return get_assigned_memoffheap();

    case ASSIGNED_CPU:
      return get_assigned_cpu();

    }
    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 ID:
      return is_set_id();
    case NAME:
      return is_set_name();
    case UPTIME_SECS:
      return is_set_uptime_secs();
    case EXECUTORS:
      return is_set_executors();
    case STATUS:
      return is_set_status();
    case ERRORS:
      return is_set_errors();
    case COMPONENT_DEBUG:
      return is_set_component_debug();
    case STORM_VERSION:
      return is_set_storm_version();
    case SCHED_STATUS:
      return is_set_sched_status();
    case OWNER:
      return is_set_owner();
    case REPLICATION_COUNT:
      return is_set_replication_count();
    case REQUESTED_MEMONHEAP:
      return is_set_requested_memonheap();
    case REQUESTED_MEMOFFHEAP:
      return is_set_requested_memoffheap();
    case REQUESTED_CPU:
      return is_set_requested_cpu();
    case ASSIGNED_MEMONHEAP:
      return is_set_assigned_memonheap();
    case ASSIGNED_MEMOFFHEAP:
      return is_set_assigned_memoffheap();
    case ASSIGNED_CPU:
      return is_set_assigned_cpu();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_id = true && this.is_set_id();
    boolean that_present_id = true && that.is_set_id();
    if (this_present_id || that_present_id) {
      if (!(this_present_id && that_present_id))
        return false;
      if (!this.id.equals(that.id))
        return false;
    }

    boolean this_present_name = true && this.is_set_name();
    boolean that_present_name = true && that.is_set_name();
    if (this_present_name || that_present_name) {
      if (!(this_present_name && that_present_name))
        return false;
      if (!this.name.equals(that.name))
        return false;
    }

    boolean this_present_uptime_secs = true;
    boolean that_present_uptime_secs = true;
    if (this_present_uptime_secs || that_present_uptime_secs) {
      if (!(this_present_uptime_secs && that_present_uptime_secs))
        return false;
      if (this.uptime_secs != that.uptime_secs)
        return false;
    }

    boolean this_present_executors = true && this.is_set_executors();
    boolean that_present_executors = true && that.is_set_executors();
    if (this_present_executors || that_present_executors) {
      if (!(this_present_executors && that_present_executors))
        return false;
      if (!this.executors.equals(that.executors))
        return false;
    }

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

    boolean this_present_errors = true && this.is_set_errors();
    boolean that_present_errors = true && that.is_set_errors();
    if (this_present_errors || that_present_errors) {
      if (!(this_present_errors && that_present_errors))
        return false;
      if (!this.errors.equals(that.errors))
        return false;
    }

    boolean this_present_component_debug = true && this.is_set_component_debug();
    boolean that_present_component_debug = true && that.is_set_component_debug();
    if (this_present_component_debug || that_present_component_debug) {
      if (!(this_present_component_debug && that_present_component_debug))
        return false;
      if (!this.component_debug.equals(that.component_debug))
        return false;
    }

    boolean this_present_storm_version = true && this.is_set_storm_version();
    boolean that_present_storm_version = true && that.is_set_storm_version();
    if (this_present_storm_version || that_present_storm_version) {
      if (!(this_present_storm_version && that_present_storm_version))
        return false;
      if (!this.storm_version.equals(that.storm_version))
        return false;
    }

    boolean this_present_sched_status = true && this.is_set_sched_status();
    boolean that_present_sched_status = true && that.is_set_sched_status();
    if (this_present_sched_status || that_present_sched_status) {
      if (!(this_present_sched_status && that_present_sched_status))
        return false;
      if (!this.sched_status.equals(that.sched_status))
        return false;
    }

    boolean this_present_owner = true && this.is_set_owner();
    boolean that_present_owner = true && that.is_set_owner();
    if (this_present_owner || that_present_owner) {
      if (!(this_present_owner && that_present_owner))
        return false;
      if (!this.owner.equals(that.owner))
        return false;
    }

    boolean this_present_replication_count = true && this.is_set_replication_count();
    boolean that_present_replication_count = true && that.is_set_replication_count();
    if (this_present_replication_count || that_present_replication_count) {
      if (!(this_present_replication_count && that_present_replication_count))
        return false;
      if (this.replication_count != that.replication_count)
        return false;
    }

    boolean this_present_requested_memonheap = true && this.is_set_requested_memonheap();
    boolean that_present_requested_memonheap = true && that.is_set_requested_memonheap();
    if (this_present_requested_memonheap || that_present_requested_memonheap) {
      if (!(this_present_requested_memonheap && that_present_requested_memonheap))
        return false;
      if (this.requested_memonheap != that.requested_memonheap)
        return false;
    }

    boolean this_present_requested_memoffheap = true && this.is_set_requested_memoffheap();
    boolean that_present_requested_memoffheap = true && that.is_set_requested_memoffheap();
    if (this_present_requested_memoffheap || that_present_requested_memoffheap) {
      if (!(this_present_requested_memoffheap && that_present_requested_memoffheap))
        return false;
      if (this.requested_memoffheap != that.requested_memoffheap)
        return false;
    }

    boolean this_present_requested_cpu = true && this.is_set_requested_cpu();
    boolean that_present_requested_cpu = true && that.is_set_requested_cpu();
    if (this_present_requested_cpu || that_present_requested_cpu) {
      if (!(this_present_requested_cpu && that_present_requested_cpu))
        return false;
      if (this.requested_cpu != that.requested_cpu)
        return false;
    }

    boolean this_present_assigned_memonheap = true && this.is_set_assigned_memonheap();
    boolean that_present_assigned_memonheap = true && that.is_set_assigned_memonheap();
    if (this_present_assigned_memonheap || that_present_assigned_memonheap) {
      if (!(this_present_assigned_memonheap && that_present_assigned_memonheap))
        return false;
      if (this.assigned_memonheap != that.assigned_memonheap)
        return false;
    }

    boolean this_present_assigned_memoffheap = true && this.is_set_assigned_memoffheap();
    boolean that_present_assigned_memoffheap = true && that.is_set_assigned_memoffheap();
    if (this_present_assigned_memoffheap || that_present_assigned_memoffheap) {
      if (!(this_present_assigned_memoffheap && that_present_assigned_memoffheap))
        return false;
      if (this.assigned_memoffheap != that.assigned_memoffheap)
        return false;
    }

    boolean this_present_assigned_cpu = true && this.is_set_assigned_cpu();
    boolean that_present_assigned_cpu = true && that.is_set_assigned_cpu();
    if (this_present_assigned_cpu || that_present_assigned_cpu) {
      if (!(this_present_assigned_cpu && that_present_assigned_cpu))
        return false;
      if (this.assigned_cpu != that.assigned_cpu)
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((is_set_id()) ? 131071 : 524287);
    if (is_set_id())
      hashCode = hashCode * 8191 + id.hashCode();

    hashCode = hashCode * 8191 + ((is_set_name()) ? 131071 : 524287);
    if (is_set_name())
      hashCode = hashCode * 8191 + name.hashCode();

    hashCode = hashCode * 8191 + uptime_secs;

    hashCode = hashCode * 8191 + ((is_set_executors()) ? 131071 : 524287);
    if (is_set_executors())
      hashCode = hashCode * 8191 + executors.hashCode();

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

    hashCode = hashCode * 8191 + ((is_set_errors()) ? 131071 : 524287);
    if (is_set_errors())
      hashCode = hashCode * 8191 + errors.hashCode();

    hashCode = hashCode * 8191 + ((is_set_component_debug()) ? 131071 : 524287);
    if (is_set_component_debug())
      hashCode = hashCode * 8191 + component_debug.hashCode();

    hashCode = hashCode * 8191 + ((is_set_storm_version()) ? 131071 : 524287);
    if (is_set_storm_version())
      hashCode = hashCode * 8191 + storm_version.hashCode();

    hashCode = hashCode * 8191 + ((is_set_sched_status()) ? 131071 : 524287);
    if (is_set_sched_status())
      hashCode = hashCode * 8191 + sched_status.hashCode();

    hashCode = hashCode * 8191 + ((is_set_owner()) ? 131071 : 524287);
    if (is_set_owner())
      hashCode = hashCode * 8191 + owner.hashCode();

    hashCode = hashCode * 8191 + ((is_set_replication_count()) ? 131071 : 524287);
    if (is_set_replication_count())
      hashCode = hashCode * 8191 + replication_count;

    hashCode = hashCode * 8191 + ((is_set_requested_memonheap()) ? 131071 : 524287);
    if (is_set_requested_memonheap())
      hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(requested_memonheap);

    hashCode = hashCode * 8191 + ((is_set_requested_memoffheap()) ? 131071 : 524287);
    if (is_set_requested_memoffheap())
      hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(requested_memoffheap);

    hashCode = hashCode * 8191 + ((is_set_requested_cpu()) ? 131071 : 524287);
    if (is_set_requested_cpu())
      hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(requested_cpu);

    hashCode = hashCode * 8191 + ((is_set_assigned_memonheap()) ? 131071 : 524287);
    if (is_set_assigned_memonheap())
      hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(assigned_memonheap);

    hashCode = hashCode * 8191 + ((is_set_assigned_memoffheap()) ? 131071 : 524287);
    if (is_set_assigned_memoffheap())
      hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(assigned_memoffheap);

    hashCode = hashCode * 8191 + ((is_set_assigned_cpu()) ? 131071 : 524287);
    if (is_set_assigned_cpu())
      hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(assigned_cpu);

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(is_set_id()).compareTo(other.is_set_id());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_id()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.id, other.id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_name()).compareTo(other.is_set_name());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_name()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.name, other.name);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_uptime_secs()).compareTo(other.is_set_uptime_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_uptime_secs()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.uptime_secs, other.uptime_secs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_executors()).compareTo(other.is_set_executors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_executors()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.executors, other.executors);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_status()).compareTo(other.is_set_status());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_status()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.status, other.status);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_errors()).compareTo(other.is_set_errors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_errors()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.errors, other.errors);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_component_debug()).compareTo(other.is_set_component_debug());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_component_debug()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.component_debug, other.component_debug);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_storm_version()).compareTo(other.is_set_storm_version());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_storm_version()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.storm_version, other.storm_version);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_sched_status()).compareTo(other.is_set_sched_status());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_sched_status()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.sched_status, other.sched_status);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_owner()).compareTo(other.is_set_owner());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_owner()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.owner, other.owner);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_replication_count()).compareTo(other.is_set_replication_count());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_replication_count()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.replication_count, other.replication_count);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_requested_memonheap()).compareTo(other.is_set_requested_memonheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_requested_memonheap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.requested_memonheap, other.requested_memonheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_requested_memoffheap()).compareTo(other.is_set_requested_memoffheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_requested_memoffheap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.requested_memoffheap, other.requested_memoffheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_requested_cpu()).compareTo(other.is_set_requested_cpu());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_requested_cpu()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.requested_cpu, other.requested_cpu);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_assigned_memonheap()).compareTo(other.is_set_assigned_memonheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_assigned_memonheap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.assigned_memonheap, other.assigned_memonheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_assigned_memoffheap()).compareTo(other.is_set_assigned_memoffheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_assigned_memoffheap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.assigned_memoffheap, other.assigned_memoffheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_assigned_cpu()).compareTo(other.is_set_assigned_cpu());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_assigned_cpu()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.assigned_cpu, other.assigned_cpu);
      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("TopologyInfo(");
    boolean first = true;

    sb.append("id:");
    if (this.id == null) {
      sb.append("null");
    } else {
      sb.append(this.id);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("name:");
    if (this.name == null) {
      sb.append("null");
    } else {
      sb.append(this.name);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("uptime_secs:");
    sb.append(this.uptime_secs);
    first = false;
    if (!first) sb.append(", ");
    sb.append("executors:");
    if (this.executors == null) {
      sb.append("null");
    } else {
      sb.append(this.executors);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("status:");
    if (this.status == null) {
      sb.append("null");
    } else {
      sb.append(this.status);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("errors:");
    if (this.errors == null) {
      sb.append("null");
    } else {
      sb.append(this.errors);
    }
    first = false;
    if (is_set_component_debug()) {
      if (!first) sb.append(", ");
      sb.append("component_debug:");
      if (this.component_debug == null) {
        sb.append("null");
      } else {
        sb.append(this.component_debug);
      }
      first = false;
    }
    if (is_set_storm_version()) {
      if (!first) sb.append(", ");
      sb.append("storm_version:");
      if (this.storm_version == null) {
        sb.append("null");
      } else {
        sb.append(this.storm_version);
      }
      first = false;
    }
    if (is_set_sched_status()) {
      if (!first) sb.append(", ");
      sb.append("sched_status:");
      if (this.sched_status == null) {
        sb.append("null");
      } else {
        sb.append(this.sched_status);
      }
      first = false;
    }
    if (is_set_owner()) {
      if (!first) sb.append(", ");
      sb.append("owner:");
      if (this.owner == null) {
        sb.append("null");
      } else {
        sb.append(this.owner);
      }
      first = false;
    }
    if (is_set_replication_count()) {
      if (!first) sb.append(", ");
      sb.append("replication_count:");
      sb.append(this.replication_count);
      first = false;
    }
    if (is_set_requested_memonheap()) {
      if (!first) sb.append(", ");
      sb.append("requested_memonheap:");
      sb.append(this.requested_memonheap);
      first = false;
    }
    if (is_set_requested_memoffheap()) {
      if (!first) sb.append(", ");
      sb.append("requested_memoffheap:");
      sb.append(this.requested_memoffheap);
      first = false;
    }
    if (is_set_requested_cpu()) {
      if (!first) sb.append(", ");
      sb.append("requested_cpu:");
      sb.append(this.requested_cpu);
      first = false;
    }
    if (is_set_assigned_memonheap()) {
      if (!first) sb.append(", ");
      sb.append("assigned_memonheap:");
      sb.append(this.assigned_memonheap);
      first = false;
    }
    if (is_set_assigned_memoffheap()) {
      if (!first) sb.append(", ");
      sb.append("assigned_memoffheap:");
      sb.append(this.assigned_memoffheap);
      first = false;
    }
    if (is_set_assigned_cpu()) {
      if (!first) sb.append(", ");
      sb.append("assigned_cpu:");
      sb.append(this.assigned_cpu);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

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

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

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

    if (!is_set_errors()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'errors' 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 TopologyInfoStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public TopologyInfoStandardScheme getScheme() {
      return new TopologyInfoStandardScheme();
    }
  }

  private static class TopologyInfoStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<TopologyInfo> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, TopologyInfo 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: // ID
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.id = iprot.readString();
              struct.set_id_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // NAME
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.name = iprot.readString();
              struct.set_name_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // UPTIME_SECS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.uptime_secs = iprot.readI32();
              struct.set_uptime_secs_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // EXECUTORS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.LIST) {
              {
                org.apache.storm.thrift.protocol.TList _list390 = iprot.readListBegin();
                struct.executors = new java.util.ArrayList<ExecutorSummary>(_list390.size);
                @org.apache.storm.thrift.annotation.Nullable ExecutorSummary _elem391;
                for (int _i392 = 0; _i392 < _list390.size; ++_i392)
                {
                  _elem391 = new ExecutorSummary();
                  _elem391.read(iprot);
                  struct.executors.add(_elem391);
                }
                iprot.readListEnd();
              }
              struct.set_executors_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // STATUS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.status = iprot.readString();
              struct.set_status_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // ERRORS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map393 = iprot.readMapBegin();
                struct.errors = new java.util.HashMap<java.lang.String,java.util.List<ErrorInfo>>(2*_map393.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key394;
                @org.apache.storm.thrift.annotation.Nullable java.util.List<ErrorInfo> _val395;
                for (int _i396 = 0; _i396 < _map393.size; ++_i396)
                {
                  _key394 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TList _list397 = iprot.readListBegin();
                    _val395 = new java.util.ArrayList<ErrorInfo>(_list397.size);
                    @org.apache.storm.thrift.annotation.Nullable ErrorInfo _elem398;
                    for (int _i399 = 0; _i399 < _list397.size; ++_i399)
                    {
                      _elem398 = new ErrorInfo();
                      _elem398.read(iprot);
                      _val395.add(_elem398);
                    }
                    iprot.readListEnd();
                  }
                  struct.errors.put(_key394, _val395);
                }
                iprot.readMapEnd();
              }
              struct.set_errors_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // COMPONENT_DEBUG
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map400 = iprot.readMapBegin();
                struct.component_debug = new java.util.HashMap<java.lang.String,DebugOptions>(2*_map400.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key401;
                @org.apache.storm.thrift.annotation.Nullable DebugOptions _val402;
                for (int _i403 = 0; _i403 < _map400.size; ++_i403)
                {
                  _key401 = iprot.readString();
                  _val402 = new DebugOptions();
                  _val402.read(iprot);
                  struct.component_debug.put(_key401, _val402);
                }
                iprot.readMapEnd();
              }
              struct.set_component_debug_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // STORM_VERSION
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.storm_version = iprot.readString();
              struct.set_storm_version_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 513: // SCHED_STATUS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.sched_status = iprot.readString();
              struct.set_sched_status_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 514: // OWNER
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.owner = iprot.readString();
              struct.set_owner_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 515: // REPLICATION_COUNT
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.replication_count = iprot.readI32();
              struct.set_replication_count_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 521: // REQUESTED_MEMONHEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.requested_memonheap = iprot.readDouble();
              struct.set_requested_memonheap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 522: // REQUESTED_MEMOFFHEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.requested_memoffheap = iprot.readDouble();
              struct.set_requested_memoffheap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 523: // REQUESTED_CPU
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.requested_cpu = iprot.readDouble();
              struct.set_requested_cpu_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 524: // ASSIGNED_MEMONHEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.assigned_memonheap = iprot.readDouble();
              struct.set_assigned_memonheap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 525: // ASSIGNED_MEMOFFHEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.assigned_memoffheap = iprot.readDouble();
              struct.set_assigned_memoffheap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 526: // ASSIGNED_CPU
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.assigned_cpu = iprot.readDouble();
              struct.set_assigned_cpu_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, TopologyInfo struct) throws org.apache.storm.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.id != null) {
        oprot.writeFieldBegin(ID_FIELD_DESC);
        oprot.writeString(struct.id);
        oprot.writeFieldEnd();
      }
      if (struct.name != null) {
        oprot.writeFieldBegin(NAME_FIELD_DESC);
        oprot.writeString(struct.name);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(UPTIME_SECS_FIELD_DESC);
      oprot.writeI32(struct.uptime_secs);
      oprot.writeFieldEnd();
      if (struct.executors != null) {
        oprot.writeFieldBegin(EXECUTORS_FIELD_DESC);
        {
          oprot.writeListBegin(new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRUCT, struct.executors.size()));
          for (ExecutorSummary _iter404 : struct.executors)
          {
            _iter404.write(oprot);
          }
          oprot.writeListEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.status != null) {
        oprot.writeFieldBegin(STATUS_FIELD_DESC);
        oprot.writeString(struct.status);
        oprot.writeFieldEnd();
      }
      if (struct.errors != null) {
        oprot.writeFieldBegin(ERRORS_FIELD_DESC);
        {
          oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.LIST, struct.errors.size()));
          for (java.util.Map.Entry<java.lang.String, java.util.List<ErrorInfo>> _iter405 : struct.errors.entrySet())
          {
            oprot.writeString(_iter405.getKey());
            {
              oprot.writeListBegin(new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRUCT, _iter405.getValue().size()));
              for (ErrorInfo _iter406 : _iter405.getValue())
              {
                _iter406.write(oprot);
              }
              oprot.writeListEnd();
            }
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.component_debug != null) {
        if (struct.is_set_component_debug()) {
          oprot.writeFieldBegin(COMPONENT_DEBUG_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRUCT, struct.component_debug.size()));
            for (java.util.Map.Entry<java.lang.String, DebugOptions> _iter407 : struct.component_debug.entrySet())
            {
              oprot.writeString(_iter407.getKey());
              _iter407.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.storm_version != null) {
        if (struct.is_set_storm_version()) {
          oprot.writeFieldBegin(STORM_VERSION_FIELD_DESC);
          oprot.writeString(struct.storm_version);
          oprot.writeFieldEnd();
        }
      }
      if (struct.sched_status != null) {
        if (struct.is_set_sched_status()) {
          oprot.writeFieldBegin(SCHED_STATUS_FIELD_DESC);
          oprot.writeString(struct.sched_status);
          oprot.writeFieldEnd();
        }
      }
      if (struct.owner != null) {
        if (struct.is_set_owner()) {
          oprot.writeFieldBegin(OWNER_FIELD_DESC);
          oprot.writeString(struct.owner);
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_replication_count()) {
        oprot.writeFieldBegin(REPLICATION_COUNT_FIELD_DESC);
        oprot.writeI32(struct.replication_count);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_requested_memonheap()) {
        oprot.writeFieldBegin(REQUESTED_MEMONHEAP_FIELD_DESC);
        oprot.writeDouble(struct.requested_memonheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_requested_memoffheap()) {
        oprot.writeFieldBegin(REQUESTED_MEMOFFHEAP_FIELD_DESC);
        oprot.writeDouble(struct.requested_memoffheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_requested_cpu()) {
        oprot.writeFieldBegin(REQUESTED_CPU_FIELD_DESC);
        oprot.writeDouble(struct.requested_cpu);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_assigned_memonheap()) {
        oprot.writeFieldBegin(ASSIGNED_MEMONHEAP_FIELD_DESC);
        oprot.writeDouble(struct.assigned_memonheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_assigned_memoffheap()) {
        oprot.writeFieldBegin(ASSIGNED_MEMOFFHEAP_FIELD_DESC);
        oprot.writeDouble(struct.assigned_memoffheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_assigned_cpu()) {
        oprot.writeFieldBegin(ASSIGNED_CPU_FIELD_DESC);
        oprot.writeDouble(struct.assigned_cpu);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class TopologyInfoTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<TopologyInfo> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, TopologyInfo struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.id);
      oprot.writeString(struct.name);
      oprot.writeI32(struct.uptime_secs);
      {
        oprot.writeI32(struct.executors.size());
        for (ExecutorSummary _iter408 : struct.executors)
        {
          _iter408.write(oprot);
        }
      }
      oprot.writeString(struct.status);
      {
        oprot.writeI32(struct.errors.size());
        for (java.util.Map.Entry<java.lang.String, java.util.List<ErrorInfo>> _iter409 : struct.errors.entrySet())
        {
          oprot.writeString(_iter409.getKey());
          {
            oprot.writeI32(_iter409.getValue().size());
            for (ErrorInfo _iter410 : _iter409.getValue())
            {
              _iter410.write(oprot);
            }
          }
        }
      }
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.is_set_component_debug()) {
        optionals.set(0);
      }
      if (struct.is_set_storm_version()) {
        optionals.set(1);
      }
      if (struct.is_set_sched_status()) {
        optionals.set(2);
      }
      if (struct.is_set_owner()) {
        optionals.set(3);
      }
      if (struct.is_set_replication_count()) {
        optionals.set(4);
      }
      if (struct.is_set_requested_memonheap()) {
        optionals.set(5);
      }
      if (struct.is_set_requested_memoffheap()) {
        optionals.set(6);
      }
      if (struct.is_set_requested_cpu()) {
        optionals.set(7);
      }
      if (struct.is_set_assigned_memonheap()) {
        optionals.set(8);
      }
      if (struct.is_set_assigned_memoffheap()) {
        optionals.set(9);
      }
      if (struct.is_set_assigned_cpu()) {
        optionals.set(10);
      }
      oprot.writeBitSet(optionals, 11);
      if (struct.is_set_component_debug()) {
        {
          oprot.writeI32(struct.component_debug.size());
          for (java.util.Map.Entry<java.lang.String, DebugOptions> _iter411 : struct.component_debug.entrySet())
          {
            oprot.writeString(_iter411.getKey());
            _iter411.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_storm_version()) {
        oprot.writeString(struct.storm_version);
      }
      if (struct.is_set_sched_status()) {
        oprot.writeString(struct.sched_status);
      }
      if (struct.is_set_owner()) {
        oprot.writeString(struct.owner);
      }
      if (struct.is_set_replication_count()) {
        oprot.writeI32(struct.replication_count);
      }
      if (struct.is_set_requested_memonheap()) {
        oprot.writeDouble(struct.requested_memonheap);
      }
      if (struct.is_set_requested_memoffheap()) {
        oprot.writeDouble(struct.requested_memoffheap);
      }
      if (struct.is_set_requested_cpu()) {
        oprot.writeDouble(struct.requested_cpu);
      }
      if (struct.is_set_assigned_memonheap()) {
        oprot.writeDouble(struct.assigned_memonheap);
      }
      if (struct.is_set_assigned_memoffheap()) {
        oprot.writeDouble(struct.assigned_memoffheap);
      }
      if (struct.is_set_assigned_cpu()) {
        oprot.writeDouble(struct.assigned_cpu);
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, TopologyInfo struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      struct.id = iprot.readString();
      struct.set_id_isSet(true);
      struct.name = iprot.readString();
      struct.set_name_isSet(true);
      struct.uptime_secs = iprot.readI32();
      struct.set_uptime_secs_isSet(true);
      {
        org.apache.storm.thrift.protocol.TList _list412 = new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
        struct.executors = new java.util.ArrayList<ExecutorSummary>(_list412.size);
        @org.apache.storm.thrift.annotation.Nullable ExecutorSummary _elem413;
        for (int _i414 = 0; _i414 < _list412.size; ++_i414)
        {
          _elem413 = new ExecutorSummary();
          _elem413.read(iprot);
          struct.executors.add(_elem413);
        }
      }
      struct.set_executors_isSet(true);
      struct.status = iprot.readString();
      struct.set_status_isSet(true);
      {
        org.apache.storm.thrift.protocol.TMap _map415 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.LIST, iprot.readI32());
        struct.errors = new java.util.HashMap<java.lang.String,java.util.List<ErrorInfo>>(2*_map415.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key416;
        @org.apache.storm.thrift.annotation.Nullable java.util.List<ErrorInfo> _val417;
        for (int _i418 = 0; _i418 < _map415.size; ++_i418)
        {
          _key416 = iprot.readString();
          {
            org.apache.storm.thrift.protocol.TList _list419 = new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
            _val417 = new java.util.ArrayList<ErrorInfo>(_list419.size);
            @org.apache.storm.thrift.annotation.Nullable ErrorInfo _elem420;
            for (int _i421 = 0; _i421 < _list419.size; ++_i421)
            {
              _elem420 = new ErrorInfo();
              _elem420.read(iprot);
              _val417.add(_elem420);
            }
          }
          struct.errors.put(_key416, _val417);
        }
      }
      struct.set_errors_isSet(true);
      java.util.BitSet incoming = iprot.readBitSet(11);
      if (incoming.get(0)) {
        {
          org.apache.storm.thrift.protocol.TMap _map422 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.component_debug = new java.util.HashMap<java.lang.String,DebugOptions>(2*_map422.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key423;
          @org.apache.storm.thrift.annotation.Nullable DebugOptions _val424;
          for (int _i425 = 0; _i425 < _map422.size; ++_i425)
          {
            _key423 = iprot.readString();
            _val424 = new DebugOptions();
            _val424.read(iprot);
            struct.component_debug.put(_key423, _val424);
          }
        }
        struct.set_component_debug_isSet(true);
      }
      if (incoming.get(1)) {
        struct.storm_version = iprot.readString();
        struct.set_storm_version_isSet(true);
      }
      if (incoming.get(2)) {
        struct.sched_status = iprot.readString();
        struct.set_sched_status_isSet(true);
      }
      if (incoming.get(3)) {
        struct.owner = iprot.readString();
        struct.set_owner_isSet(true);
      }
      if (incoming.get(4)) {
        struct.replication_count = iprot.readI32();
        struct.set_replication_count_isSet(true);
      }
      if (incoming.get(5)) {
        struct.requested_memonheap = iprot.readDouble();
        struct.set_requested_memonheap_isSet(true);
      }
      if (incoming.get(6)) {
        struct.requested_memoffheap = iprot.readDouble();
        struct.set_requested_memoffheap_isSet(true);
      }
      if (incoming.get(7)) {
        struct.requested_cpu = iprot.readDouble();
        struct.set_requested_cpu_isSet(true);
      }
      if (incoming.get(8)) {
        struct.assigned_memonheap = iprot.readDouble();
        struct.set_assigned_memonheap_isSet(true);
      }
      if (incoming.get(9)) {
        struct.assigned_memoffheap = iprot.readDouble();
        struct.set_assigned_memoffheap_isSet(true);
      }
      if (incoming.get(10)) {
        struct.assigned_cpu = iprot.readDouble();
        struct.set_assigned_cpu_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();
  }
}

