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

  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)1);
  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.I32, (short)2);
  private static final org.apache.storm.thrift.protocol.TField NUM_WORKERS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("num_workers", org.apache.storm.thrift.protocol.TType.I32, (short)3);
  private static final org.apache.storm.thrift.protocol.TField COMPONENT_EXECUTORS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("component_executors", org.apache.storm.thrift.protocol.TType.MAP, (short)4);
  private static final org.apache.storm.thrift.protocol.TField LAUNCH_TIME_SECS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("launch_time_secs", org.apache.storm.thrift.protocol.TType.I32, (short)5);
  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)6);
  private static final org.apache.storm.thrift.protocol.TField TOPOLOGY_ACTION_OPTIONS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("topology_action_options", org.apache.storm.thrift.protocol.TType.STRUCT, (short)7);
  private static final org.apache.storm.thrift.protocol.TField PREV_STATUS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("prev_status", org.apache.storm.thrift.protocol.TType.I32, (short)8);
  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)9);
  private static final org.apache.storm.thrift.protocol.TField PRINCIPAL_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("principal", org.apache.storm.thrift.protocol.TType.STRING, (short)10);
  private static final org.apache.storm.thrift.protocol.TField TOPOLOGY_VERSION_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("topology_version", org.apache.storm.thrift.protocol.TType.STRING, (short)11);

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

  private @org.apache.storm.thrift.annotation.Nullable java.lang.String name; // required
  private @org.apache.storm.thrift.annotation.Nullable TopologyStatus status; // required
  private int num_workers; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Integer> component_executors; // optional
  private int launch_time_secs; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String owner; // optional
  private @org.apache.storm.thrift.annotation.Nullable TopologyActionOptions topology_action_options; // optional
  private @org.apache.storm.thrift.annotation.Nullable TopologyStatus prev_status; // optional
  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 principal; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String topology_version; // 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 {
    NAME((short)1, "name"),
    /**
     * 
     * @see TopologyStatus
     */
    STATUS((short)2, "status"),
    NUM_WORKERS((short)3, "num_workers"),
    COMPONENT_EXECUTORS((short)4, "component_executors"),
    LAUNCH_TIME_SECS((short)5, "launch_time_secs"),
    OWNER((short)6, "owner"),
    TOPOLOGY_ACTION_OPTIONS((short)7, "topology_action_options"),
    /**
     * 
     * @see TopologyStatus
     */
    PREV_STATUS((short)8, "prev_status"),
    COMPONENT_DEBUG((short)9, "component_debug"),
    PRINCIPAL((short)10, "principal"),
    TOPOLOGY_VERSION((short)11, "topology_version");

    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: // NAME
          return NAME;
        case 2: // STATUS
          return STATUS;
        case 3: // NUM_WORKERS
          return NUM_WORKERS;
        case 4: // COMPONENT_EXECUTORS
          return COMPONENT_EXECUTORS;
        case 5: // LAUNCH_TIME_SECS
          return LAUNCH_TIME_SECS;
        case 6: // OWNER
          return OWNER;
        case 7: // TOPOLOGY_ACTION_OPTIONS
          return TOPOLOGY_ACTION_OPTIONS;
        case 8: // PREV_STATUS
          return PREV_STATUS;
        case 9: // COMPONENT_DEBUG
          return COMPONENT_DEBUG;
        case 10: // PRINCIPAL
          return PRINCIPAL;
        case 11: // TOPOLOGY_VERSION
          return TOPOLOGY_VERSION;
        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 __NUM_WORKERS_ISSET_ID = 0;
  private static final int __LAUNCH_TIME_SECS_ISSET_ID = 1;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.COMPONENT_EXECUTORS,_Fields.LAUNCH_TIME_SECS,_Fields.OWNER,_Fields.TOPOLOGY_ACTION_OPTIONS,_Fields.PREV_STATUS,_Fields.COMPONENT_DEBUG,_Fields.PRINCIPAL,_Fields.TOPOLOGY_VERSION};
  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.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.STATUS, new org.apache.storm.thrift.meta_data.FieldMetaData("status", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.EnumMetaData(org.apache.storm.thrift.protocol.TType.ENUM, TopologyStatus.class)));
    tmpMap.put(_Fields.NUM_WORKERS, new org.apache.storm.thrift.meta_data.FieldMetaData("num_workers", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.COMPONENT_EXECUTORS, new org.apache.storm.thrift.meta_data.FieldMetaData("component_executors", 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.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32))));
    tmpMap.put(_Fields.LAUNCH_TIME_SECS, new org.apache.storm.thrift.meta_data.FieldMetaData("launch_time_secs", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    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.TOPOLOGY_ACTION_OPTIONS, new org.apache.storm.thrift.meta_data.FieldMetaData("topology_action_options", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, TopologyActionOptions.class)));
    tmpMap.put(_Fields.PREV_STATUS, new org.apache.storm.thrift.meta_data.FieldMetaData("prev_status", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.EnumMetaData(org.apache.storm.thrift.protocol.TType.ENUM, TopologyStatus.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.PRINCIPAL, new org.apache.storm.thrift.meta_data.FieldMetaData("principal", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TOPOLOGY_VERSION, new org.apache.storm.thrift.meta_data.FieldMetaData("topology_version", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        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(StormBase.class, metaDataMap);
  }

  public StormBase() {
  }

  public StormBase(
    java.lang.String name,
    TopologyStatus status,
    int num_workers)
  {
    this();
    this.name = name;
    this.status = status;
    this.num_workers = num_workers;
    set_num_workers_isSet(true);
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public StormBase(StormBase other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.is_set_name()) {
      this.name = other.name;
    }
    if (other.is_set_status()) {
      this.status = other.status;
    }
    this.num_workers = other.num_workers;
    if (other.is_set_component_executors()) {
      java.util.Map<java.lang.String,java.lang.Integer> __this__component_executors = new java.util.HashMap<java.lang.String,java.lang.Integer>(other.component_executors);
      this.component_executors = __this__component_executors;
    }
    this.launch_time_secs = other.launch_time_secs;
    if (other.is_set_owner()) {
      this.owner = other.owner;
    }
    if (other.is_set_topology_action_options()) {
      this.topology_action_options = new TopologyActionOptions(other.topology_action_options);
    }
    if (other.is_set_prev_status()) {
      this.prev_status = other.prev_status;
    }
    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_principal()) {
      this.principal = other.principal;
    }
    if (other.is_set_topology_version()) {
      this.topology_version = other.topology_version;
    }
  }

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

  @Override
  public void clear() {
    this.name = null;
    this.status = null;
    set_num_workers_isSet(false);
    this.num_workers = 0;
    this.component_executors = null;
    set_launch_time_secs_isSet(false);
    this.launch_time_secs = 0;
    this.owner = null;
    this.topology_action_options = null;
    this.prev_status = null;
    this.component_debug = null;
    this.principal = null;
    this.topology_version = 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;
    }
  }

  /**
   * 
   * @see TopologyStatus
   */
  @org.apache.storm.thrift.annotation.Nullable
  public TopologyStatus get_status() {
    return this.status;
  }

  /**
   * 
   * @see TopologyStatus
   */
  public void set_status(@org.apache.storm.thrift.annotation.Nullable TopologyStatus 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_num_workers() {
    return this.num_workers;
  }

  public void set_num_workers(int num_workers) {
    this.num_workers = num_workers;
    set_num_workers_isSet(true);
  }

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

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

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

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

  public void put_to_component_executors(java.lang.String key, int val) {
    if (this.component_executors == null) {
      this.component_executors = new java.util.HashMap<java.lang.String,java.lang.Integer>();
    }
    this.component_executors.put(key, val);
  }

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

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

  public void unset_component_executors() {
    this.component_executors = null;
  }

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

  public void set_component_executors_isSet(boolean value) {
    if (!value) {
      this.component_executors = null;
    }
  }

  public int get_launch_time_secs() {
    return this.launch_time_secs;
  }

  public void set_launch_time_secs(int launch_time_secs) {
    this.launch_time_secs = launch_time_secs;
    set_launch_time_secs_isSet(true);
  }

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

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

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

  @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;
    }
  }

  @org.apache.storm.thrift.annotation.Nullable
  public TopologyActionOptions get_topology_action_options() {
    return this.topology_action_options;
  }

  public void set_topology_action_options(@org.apache.storm.thrift.annotation.Nullable TopologyActionOptions topology_action_options) {
    this.topology_action_options = topology_action_options;
  }

  public void unset_topology_action_options() {
    this.topology_action_options = null;
  }

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

  public void set_topology_action_options_isSet(boolean value) {
    if (!value) {
      this.topology_action_options = null;
    }
  }

  /**
   * 
   * @see TopologyStatus
   */
  @org.apache.storm.thrift.annotation.Nullable
  public TopologyStatus get_prev_status() {
    return this.prev_status;
  }

  /**
   * 
   * @see TopologyStatus
   */
  public void set_prev_status(@org.apache.storm.thrift.annotation.Nullable TopologyStatus prev_status) {
    this.prev_status = prev_status;
  }

  public void unset_prev_status() {
    this.prev_status = null;
  }

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

  public void set_prev_status_isSet(boolean value) {
    if (!value) {
      this.prev_status = 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_principal() {
    return this.principal;
  }

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

  public void unset_principal() {
    this.principal = null;
  }

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

  public void set_principal_isSet(boolean value) {
    if (!value) {
      this.principal = null;
    }
  }

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

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

  public void unset_topology_version() {
    this.topology_version = null;
  }

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

  public void set_topology_version_isSet(boolean value) {
    if (!value) {
      this.topology_version = null;
    }
  }

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

    case STATUS:
      if (value == null) {
        unset_status();
      } else {
        set_status((TopologyStatus)value);
      }
      break;

    case NUM_WORKERS:
      if (value == null) {
        unset_num_workers();
      } else {
        set_num_workers((java.lang.Integer)value);
      }
      break;

    case COMPONENT_EXECUTORS:
      if (value == null) {
        unset_component_executors();
      } else {
        set_component_executors((java.util.Map<java.lang.String,java.lang.Integer>)value);
      }
      break;

    case LAUNCH_TIME_SECS:
      if (value == null) {
        unset_launch_time_secs();
      } else {
        set_launch_time_secs((java.lang.Integer)value);
      }
      break;

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

    case TOPOLOGY_ACTION_OPTIONS:
      if (value == null) {
        unset_topology_action_options();
      } else {
        set_topology_action_options((TopologyActionOptions)value);
      }
      break;

    case PREV_STATUS:
      if (value == null) {
        unset_prev_status();
      } else {
        set_prev_status((TopologyStatus)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 PRINCIPAL:
      if (value == null) {
        unset_principal();
      } else {
        set_principal((java.lang.String)value);
      }
      break;

    case TOPOLOGY_VERSION:
      if (value == null) {
        unset_topology_version();
      } else {
        set_topology_version((java.lang.String)value);
      }
      break;

    }
  }

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

    case STATUS:
      return get_status();

    case NUM_WORKERS:
      return get_num_workers();

    case COMPONENT_EXECUTORS:
      return get_component_executors();

    case LAUNCH_TIME_SECS:
      return get_launch_time_secs();

    case OWNER:
      return get_owner();

    case TOPOLOGY_ACTION_OPTIONS:
      return get_topology_action_options();

    case PREV_STATUS:
      return get_prev_status();

    case COMPONENT_DEBUG:
      return get_component_debug();

    case PRINCIPAL:
      return get_principal();

    case TOPOLOGY_VERSION:
      return get_topology_version();

    }
    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 NAME:
      return is_set_name();
    case STATUS:
      return is_set_status();
    case NUM_WORKERS:
      return is_set_num_workers();
    case COMPONENT_EXECUTORS:
      return is_set_component_executors();
    case LAUNCH_TIME_SECS:
      return is_set_launch_time_secs();
    case OWNER:
      return is_set_owner();
    case TOPOLOGY_ACTION_OPTIONS:
      return is_set_topology_action_options();
    case PREV_STATUS:
      return is_set_prev_status();
    case COMPONENT_DEBUG:
      return is_set_component_debug();
    case PRINCIPAL:
      return is_set_principal();
    case TOPOLOGY_VERSION:
      return is_set_topology_version();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    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_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_num_workers = true;
    boolean that_present_num_workers = true;
    if (this_present_num_workers || that_present_num_workers) {
      if (!(this_present_num_workers && that_present_num_workers))
        return false;
      if (this.num_workers != that.num_workers)
        return false;
    }

    boolean this_present_component_executors = true && this.is_set_component_executors();
    boolean that_present_component_executors = true && that.is_set_component_executors();
    if (this_present_component_executors || that_present_component_executors) {
      if (!(this_present_component_executors && that_present_component_executors))
        return false;
      if (!this.component_executors.equals(that.component_executors))
        return false;
    }

    boolean this_present_launch_time_secs = true && this.is_set_launch_time_secs();
    boolean that_present_launch_time_secs = true && that.is_set_launch_time_secs();
    if (this_present_launch_time_secs || that_present_launch_time_secs) {
      if (!(this_present_launch_time_secs && that_present_launch_time_secs))
        return false;
      if (this.launch_time_secs != that.launch_time_secs)
        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_topology_action_options = true && this.is_set_topology_action_options();
    boolean that_present_topology_action_options = true && that.is_set_topology_action_options();
    if (this_present_topology_action_options || that_present_topology_action_options) {
      if (!(this_present_topology_action_options && that_present_topology_action_options))
        return false;
      if (!this.topology_action_options.equals(that.topology_action_options))
        return false;
    }

    boolean this_present_prev_status = true && this.is_set_prev_status();
    boolean that_present_prev_status = true && that.is_set_prev_status();
    if (this_present_prev_status || that_present_prev_status) {
      if (!(this_present_prev_status && that_present_prev_status))
        return false;
      if (!this.prev_status.equals(that.prev_status))
        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_principal = true && this.is_set_principal();
    boolean that_present_principal = true && that.is_set_principal();
    if (this_present_principal || that_present_principal) {
      if (!(this_present_principal && that_present_principal))
        return false;
      if (!this.principal.equals(that.principal))
        return false;
    }

    boolean this_present_topology_version = true && this.is_set_topology_version();
    boolean that_present_topology_version = true && that.is_set_topology_version();
    if (this_present_topology_version || that_present_topology_version) {
      if (!(this_present_topology_version && that_present_topology_version))
        return false;
      if (!this.topology_version.equals(that.topology_version))
        return false;
    }

    return true;
  }

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

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

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

    hashCode = hashCode * 8191 + num_workers;

    hashCode = hashCode * 8191 + ((is_set_component_executors()) ? 131071 : 524287);
    if (is_set_component_executors())
      hashCode = hashCode * 8191 + component_executors.hashCode();

    hashCode = hashCode * 8191 + ((is_set_launch_time_secs()) ? 131071 : 524287);
    if (is_set_launch_time_secs())
      hashCode = hashCode * 8191 + launch_time_secs;

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

    hashCode = hashCode * 8191 + ((is_set_topology_action_options()) ? 131071 : 524287);
    if (is_set_topology_action_options())
      hashCode = hashCode * 8191 + topology_action_options.hashCode();

    hashCode = hashCode * 8191 + ((is_set_prev_status()) ? 131071 : 524287);
    if (is_set_prev_status())
      hashCode = hashCode * 8191 + prev_status.getValue();

    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_principal()) ? 131071 : 524287);
    if (is_set_principal())
      hashCode = hashCode * 8191 + principal.hashCode();

    hashCode = hashCode * 8191 + ((is_set_topology_version()) ? 131071 : 524287);
    if (is_set_topology_version())
      hashCode = hashCode * 8191 + topology_version.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    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_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_num_workers()).compareTo(other.is_set_num_workers());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_num_workers()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.num_workers, other.num_workers);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_component_executors()).compareTo(other.is_set_component_executors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_component_executors()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.component_executors, other.component_executors);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_launch_time_secs()).compareTo(other.is_set_launch_time_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_launch_time_secs()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.launch_time_secs, other.launch_time_secs);
      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_topology_action_options()).compareTo(other.is_set_topology_action_options());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topology_action_options()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.topology_action_options, other.topology_action_options);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_prev_status()).compareTo(other.is_set_prev_status());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_prev_status()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.prev_status, other.prev_status);
      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_principal()).compareTo(other.is_set_principal());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_principal()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.principal, other.principal);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_topology_version()).compareTo(other.is_set_topology_version());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topology_version()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.topology_version, other.topology_version);
      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("StormBase(");
    boolean first = true;

    sb.append("name:");
    if (this.name == null) {
      sb.append("null");
    } else {
      sb.append(this.name);
    }
    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("num_workers:");
    sb.append(this.num_workers);
    first = false;
    if (is_set_component_executors()) {
      if (!first) sb.append(", ");
      sb.append("component_executors:");
      if (this.component_executors == null) {
        sb.append("null");
      } else {
        sb.append(this.component_executors);
      }
      first = false;
    }
    if (is_set_launch_time_secs()) {
      if (!first) sb.append(", ");
      sb.append("launch_time_secs:");
      sb.append(this.launch_time_secs);
      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_topology_action_options()) {
      if (!first) sb.append(", ");
      sb.append("topology_action_options:");
      if (this.topology_action_options == null) {
        sb.append("null");
      } else {
        sb.append(this.topology_action_options);
      }
      first = false;
    }
    if (is_set_prev_status()) {
      if (!first) sb.append(", ");
      sb.append("prev_status:");
      if (this.prev_status == null) {
        sb.append("null");
      } else {
        sb.append(this.prev_status);
      }
      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_principal()) {
      if (!first) sb.append(", ");
      sb.append("principal:");
      if (this.principal == null) {
        sb.append("null");
      } else {
        sb.append(this.principal);
      }
      first = false;
    }
    if (is_set_topology_version()) {
      if (!first) sb.append(", ");
      sb.append("topology_version:");
      if (this.topology_version == null) {
        sb.append("null");
      } else {
        sb.append(this.topology_version);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.storm.thrift.TException {
    // check for required fields
    if (!is_set_name()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'name' 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_num_workers()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'num_workers' 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 StormBaseStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public StormBaseStandardScheme getScheme() {
      return new StormBaseStandardScheme();
    }
  }

  private static class StormBaseStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<StormBase> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, StormBase 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: // 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 2: // STATUS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.status = org.apache.storm.generated.TopologyStatus.findByValue(iprot.readI32());
              struct.set_status_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // NUM_WORKERS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.num_workers = iprot.readI32();
              struct.set_num_workers_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // COMPONENT_EXECUTORS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map802 = iprot.readMapBegin();
                struct.component_executors = new java.util.HashMap<java.lang.String,java.lang.Integer>(2*_map802.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key803;
                int _val804;
                for (int _i805 = 0; _i805 < _map802.size; ++_i805)
                {
                  _key803 = iprot.readString();
                  _val804 = iprot.readI32();
                  struct.component_executors.put(_key803, _val804);
                }
                iprot.readMapEnd();
              }
              struct.set_component_executors_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // LAUNCH_TIME_SECS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.launch_time_secs = iprot.readI32();
              struct.set_launch_time_secs_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // 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 7: // TOPOLOGY_ACTION_OPTIONS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRUCT) {
              struct.topology_action_options = new TopologyActionOptions();
              struct.topology_action_options.read(iprot);
              struct.set_topology_action_options_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // PREV_STATUS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.prev_status = org.apache.storm.generated.TopologyStatus.findByValue(iprot.readI32());
              struct.set_prev_status_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // COMPONENT_DEBUG
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map806 = iprot.readMapBegin();
                struct.component_debug = new java.util.HashMap<java.lang.String,DebugOptions>(2*_map806.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key807;
                @org.apache.storm.thrift.annotation.Nullable DebugOptions _val808;
                for (int _i809 = 0; _i809 < _map806.size; ++_i809)
                {
                  _key807 = iprot.readString();
                  _val808 = new DebugOptions();
                  _val808.read(iprot);
                  struct.component_debug.put(_key807, _val808);
                }
                iprot.readMapEnd();
              }
              struct.set_component_debug_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // PRINCIPAL
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.principal = iprot.readString();
              struct.set_principal_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // TOPOLOGY_VERSION
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.topology_version = iprot.readString();
              struct.set_topology_version_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, StormBase struct) throws org.apache.storm.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.name != null) {
        oprot.writeFieldBegin(NAME_FIELD_DESC);
        oprot.writeString(struct.name);
        oprot.writeFieldEnd();
      }
      if (struct.status != null) {
        oprot.writeFieldBegin(STATUS_FIELD_DESC);
        oprot.writeI32(struct.status.getValue());
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(NUM_WORKERS_FIELD_DESC);
      oprot.writeI32(struct.num_workers);
      oprot.writeFieldEnd();
      if (struct.component_executors != null) {
        if (struct.is_set_component_executors()) {
          oprot.writeFieldBegin(COMPONENT_EXECUTORS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.I32, struct.component_executors.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter810 : struct.component_executors.entrySet())
            {
              oprot.writeString(_iter810.getKey());
              oprot.writeI32(_iter810.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_launch_time_secs()) {
        oprot.writeFieldBegin(LAUNCH_TIME_SECS_FIELD_DESC);
        oprot.writeI32(struct.launch_time_secs);
        oprot.writeFieldEnd();
      }
      if (struct.owner != null) {
        if (struct.is_set_owner()) {
          oprot.writeFieldBegin(OWNER_FIELD_DESC);
          oprot.writeString(struct.owner);
          oprot.writeFieldEnd();
        }
      }
      if (struct.topology_action_options != null) {
        if (struct.is_set_topology_action_options()) {
          oprot.writeFieldBegin(TOPOLOGY_ACTION_OPTIONS_FIELD_DESC);
          struct.topology_action_options.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.prev_status != null) {
        if (struct.is_set_prev_status()) {
          oprot.writeFieldBegin(PREV_STATUS_FIELD_DESC);
          oprot.writeI32(struct.prev_status.getValue());
          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> _iter811 : struct.component_debug.entrySet())
            {
              oprot.writeString(_iter811.getKey());
              _iter811.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.principal != null) {
        if (struct.is_set_principal()) {
          oprot.writeFieldBegin(PRINCIPAL_FIELD_DESC);
          oprot.writeString(struct.principal);
          oprot.writeFieldEnd();
        }
      }
      if (struct.topology_version != null) {
        if (struct.is_set_topology_version()) {
          oprot.writeFieldBegin(TOPOLOGY_VERSION_FIELD_DESC);
          oprot.writeString(struct.topology_version);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class StormBaseTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<StormBase> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, StormBase struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.name);
      oprot.writeI32(struct.status.getValue());
      oprot.writeI32(struct.num_workers);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.is_set_component_executors()) {
        optionals.set(0);
      }
      if (struct.is_set_launch_time_secs()) {
        optionals.set(1);
      }
      if (struct.is_set_owner()) {
        optionals.set(2);
      }
      if (struct.is_set_topology_action_options()) {
        optionals.set(3);
      }
      if (struct.is_set_prev_status()) {
        optionals.set(4);
      }
      if (struct.is_set_component_debug()) {
        optionals.set(5);
      }
      if (struct.is_set_principal()) {
        optionals.set(6);
      }
      if (struct.is_set_topology_version()) {
        optionals.set(7);
      }
      oprot.writeBitSet(optionals, 8);
      if (struct.is_set_component_executors()) {
        {
          oprot.writeI32(struct.component_executors.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter812 : struct.component_executors.entrySet())
          {
            oprot.writeString(_iter812.getKey());
            oprot.writeI32(_iter812.getValue());
          }
        }
      }
      if (struct.is_set_launch_time_secs()) {
        oprot.writeI32(struct.launch_time_secs);
      }
      if (struct.is_set_owner()) {
        oprot.writeString(struct.owner);
      }
      if (struct.is_set_topology_action_options()) {
        struct.topology_action_options.write(oprot);
      }
      if (struct.is_set_prev_status()) {
        oprot.writeI32(struct.prev_status.getValue());
      }
      if (struct.is_set_component_debug()) {
        {
          oprot.writeI32(struct.component_debug.size());
          for (java.util.Map.Entry<java.lang.String, DebugOptions> _iter813 : struct.component_debug.entrySet())
          {
            oprot.writeString(_iter813.getKey());
            _iter813.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_principal()) {
        oprot.writeString(struct.principal);
      }
      if (struct.is_set_topology_version()) {
        oprot.writeString(struct.topology_version);
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, StormBase struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      struct.name = iprot.readString();
      struct.set_name_isSet(true);
      struct.status = org.apache.storm.generated.TopologyStatus.findByValue(iprot.readI32());
      struct.set_status_isSet(true);
      struct.num_workers = iprot.readI32();
      struct.set_num_workers_isSet(true);
      java.util.BitSet incoming = iprot.readBitSet(8);
      if (incoming.get(0)) {
        {
          org.apache.storm.thrift.protocol.TMap _map814 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.I32, iprot.readI32());
          struct.component_executors = new java.util.HashMap<java.lang.String,java.lang.Integer>(2*_map814.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key815;
          int _val816;
          for (int _i817 = 0; _i817 < _map814.size; ++_i817)
          {
            _key815 = iprot.readString();
            _val816 = iprot.readI32();
            struct.component_executors.put(_key815, _val816);
          }
        }
        struct.set_component_executors_isSet(true);
      }
      if (incoming.get(1)) {
        struct.launch_time_secs = iprot.readI32();
        struct.set_launch_time_secs_isSet(true);
      }
      if (incoming.get(2)) {
        struct.owner = iprot.readString();
        struct.set_owner_isSet(true);
      }
      if (incoming.get(3)) {
        struct.topology_action_options = new TopologyActionOptions();
        struct.topology_action_options.read(iprot);
        struct.set_topology_action_options_isSet(true);
      }
      if (incoming.get(4)) {
        struct.prev_status = org.apache.storm.generated.TopologyStatus.findByValue(iprot.readI32());
        struct.set_prev_status_isSet(true);
      }
      if (incoming.get(5)) {
        {
          org.apache.storm.thrift.protocol.TMap _map818 = 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*_map818.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key819;
          @org.apache.storm.thrift.annotation.Nullable DebugOptions _val820;
          for (int _i821 = 0; _i821 < _map818.size; ++_i821)
          {
            _key819 = iprot.readString();
            _val820 = new DebugOptions();
            _val820.read(iprot);
            struct.component_debug.put(_key819, _val820);
          }
        }
        struct.set_component_debug_isSet(true);
      }
      if (incoming.get(6)) {
        struct.principal = iprot.readString();
        struct.set_principal_isSet(true);
      }
      if (incoming.get(7)) {
        struct.topology_version = iprot.readString();
        struct.set_topology_version_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();
  }
}

