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

  private static final org.apache.storm.thrift.protocol.TField TIME_SECS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("time_secs", org.apache.storm.thrift.protocol.TType.I64, (short)1);
  private static final org.apache.storm.thrift.protocol.TField HOSTNAME_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("hostname", org.apache.storm.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.storm.thrift.protocol.TField ASSIGNMENT_ID_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("assignment_id", org.apache.storm.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.storm.thrift.protocol.TField USED_PORTS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("used_ports", org.apache.storm.thrift.protocol.TType.LIST, (short)4);
  private static final org.apache.storm.thrift.protocol.TField META_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("meta", org.apache.storm.thrift.protocol.TType.LIST, (short)5);
  private static final org.apache.storm.thrift.protocol.TField SCHEDULER_META_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("scheduler_meta", org.apache.storm.thrift.protocol.TType.MAP, (short)6);
  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.I64, (short)7);
  private static final org.apache.storm.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("version", org.apache.storm.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.storm.thrift.protocol.TField RESOURCES_MAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("resources_map", org.apache.storm.thrift.protocol.TType.MAP, (short)9);
  private static final org.apache.storm.thrift.protocol.TField SERVER_PORT_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("server_port", org.apache.storm.thrift.protocol.TType.I32, (short)10);

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

  private long time_secs; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String hostname; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String assignment_id; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> used_ports; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> meta; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.String> scheduler_meta; // optional
  private long uptime_secs; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String version; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Double> resources_map; // optional
  private int server_port; // 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 {
    TIME_SECS((short)1, "time_secs"),
    HOSTNAME((short)2, "hostname"),
    ASSIGNMENT_ID((short)3, "assignment_id"),
    USED_PORTS((short)4, "used_ports"),
    META((short)5, "meta"),
    SCHEDULER_META((short)6, "scheduler_meta"),
    UPTIME_SECS((short)7, "uptime_secs"),
    VERSION((short)8, "version"),
    RESOURCES_MAP((short)9, "resources_map"),
    SERVER_PORT((short)10, "server_port");

    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: // TIME_SECS
          return TIME_SECS;
        case 2: // HOSTNAME
          return HOSTNAME;
        case 3: // ASSIGNMENT_ID
          return ASSIGNMENT_ID;
        case 4: // USED_PORTS
          return USED_PORTS;
        case 5: // META
          return META;
        case 6: // SCHEDULER_META
          return SCHEDULER_META;
        case 7: // UPTIME_SECS
          return UPTIME_SECS;
        case 8: // VERSION
          return VERSION;
        case 9: // RESOURCES_MAP
          return RESOURCES_MAP;
        case 10: // SERVER_PORT
          return SERVER_PORT;
        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 __TIME_SECS_ISSET_ID = 0;
  private static final int __UPTIME_SECS_ISSET_ID = 1;
  private static final int __SERVER_PORT_ISSET_ID = 2;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.ASSIGNMENT_ID,_Fields.USED_PORTS,_Fields.META,_Fields.SCHEDULER_META,_Fields.UPTIME_SECS,_Fields.VERSION,_Fields.RESOURCES_MAP,_Fields.SERVER_PORT};
  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.TIME_SECS, new org.apache.storm.thrift.meta_data.FieldMetaData("time_secs", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.HOSTNAME, new org.apache.storm.thrift.meta_data.FieldMetaData("hostname", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.ASSIGNMENT_ID, new org.apache.storm.thrift.meta_data.FieldMetaData("assignment_id", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.USED_PORTS, new org.apache.storm.thrift.meta_data.FieldMetaData("used_ports", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64))));
    tmpMap.put(_Fields.META, new org.apache.storm.thrift.meta_data.FieldMetaData("meta", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64))));
    tmpMap.put(_Fields.SCHEDULER_META, new org.apache.storm.thrift.meta_data.FieldMetaData("scheduler_meta", 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.STRING))));
    tmpMap.put(_Fields.UPTIME_SECS, new org.apache.storm.thrift.meta_data.FieldMetaData("uptime_secs", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.VERSION, new org.apache.storm.thrift.meta_data.FieldMetaData("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.RESOURCES_MAP, new org.apache.storm.thrift.meta_data.FieldMetaData("resources_map", 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.DOUBLE))));
    tmpMap.put(_Fields.SERVER_PORT, new org.apache.storm.thrift.meta_data.FieldMetaData("server_port", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SupervisorInfo.class, metaDataMap);
  }

  public SupervisorInfo() {
  }

  public SupervisorInfo(
    long time_secs,
    java.lang.String hostname)
  {
    this();
    this.time_secs = time_secs;
    set_time_secs_isSet(true);
    this.hostname = hostname;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public SupervisorInfo(SupervisorInfo other) {
    __isset_bitfield = other.__isset_bitfield;
    this.time_secs = other.time_secs;
    if (other.is_set_hostname()) {
      this.hostname = other.hostname;
    }
    if (other.is_set_assignment_id()) {
      this.assignment_id = other.assignment_id;
    }
    if (other.is_set_used_ports()) {
      java.util.List<java.lang.Long> __this__used_ports = new java.util.ArrayList<java.lang.Long>(other.used_ports);
      this.used_ports = __this__used_ports;
    }
    if (other.is_set_meta()) {
      java.util.List<java.lang.Long> __this__meta = new java.util.ArrayList<java.lang.Long>(other.meta);
      this.meta = __this__meta;
    }
    if (other.is_set_scheduler_meta()) {
      java.util.Map<java.lang.String,java.lang.String> __this__scheduler_meta = new java.util.HashMap<java.lang.String,java.lang.String>(other.scheduler_meta);
      this.scheduler_meta = __this__scheduler_meta;
    }
    this.uptime_secs = other.uptime_secs;
    if (other.is_set_version()) {
      this.version = other.version;
    }
    if (other.is_set_resources_map()) {
      java.util.Map<java.lang.String,java.lang.Double> __this__resources_map = new java.util.HashMap<java.lang.String,java.lang.Double>(other.resources_map);
      this.resources_map = __this__resources_map;
    }
    this.server_port = other.server_port;
  }

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

  @Override
  public void clear() {
    set_time_secs_isSet(false);
    this.time_secs = 0;
    this.hostname = null;
    this.assignment_id = null;
    this.used_ports = null;
    this.meta = null;
    this.scheduler_meta = null;
    set_uptime_secs_isSet(false);
    this.uptime_secs = 0;
    this.version = null;
    this.resources_map = null;
    set_server_port_isSet(false);
    this.server_port = 0;
  }

  public long get_time_secs() {
    return this.time_secs;
  }

  public void set_time_secs(long time_secs) {
    this.time_secs = time_secs;
    set_time_secs_isSet(true);
  }

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

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

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

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

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

  public void unset_hostname() {
    this.hostname = null;
  }

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

  public void set_hostname_isSet(boolean value) {
    if (!value) {
      this.hostname = null;
    }
  }

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

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

  public void unset_assignment_id() {
    this.assignment_id = null;
  }

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

  public void set_assignment_id_isSet(boolean value) {
    if (!value) {
      this.assignment_id = null;
    }
  }

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

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Iterator<java.lang.Long> get_used_ports_iterator() {
    return (this.used_ports == null) ? null : this.used_ports.iterator();
  }

  public void add_to_used_ports(long elem) {
    if (this.used_ports == null) {
      this.used_ports = new java.util.ArrayList<java.lang.Long>();
    }
    this.used_ports.add(elem);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.List<java.lang.Long> get_used_ports() {
    return this.used_ports;
  }

  public void set_used_ports(@org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> used_ports) {
    this.used_ports = used_ports;
  }

  public void unset_used_ports() {
    this.used_ports = null;
  }

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

  public void set_used_ports_isSet(boolean value) {
    if (!value) {
      this.used_ports = null;
    }
  }

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

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Iterator<java.lang.Long> get_meta_iterator() {
    return (this.meta == null) ? null : this.meta.iterator();
  }

  public void add_to_meta(long elem) {
    if (this.meta == null) {
      this.meta = new java.util.ArrayList<java.lang.Long>();
    }
    this.meta.add(elem);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.List<java.lang.Long> get_meta() {
    return this.meta;
  }

  public void set_meta(@org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> meta) {
    this.meta = meta;
  }

  public void unset_meta() {
    this.meta = null;
  }

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

  public void set_meta_isSet(boolean value) {
    if (!value) {
      this.meta = null;
    }
  }

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

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

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

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

  public void unset_scheduler_meta() {
    this.scheduler_meta = null;
  }

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

  public void set_scheduler_meta_isSet(boolean value) {
    if (!value) {
      this.scheduler_meta = null;
    }
  }

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

  public void set_uptime_secs(long 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);
  }

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

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

  public void unset_version() {
    this.version = null;
  }

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

  public void set_version_isSet(boolean value) {
    if (!value) {
      this.version = null;
    }
  }

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

  public void put_to_resources_map(java.lang.String key, double val) {
    if (this.resources_map == null) {
      this.resources_map = new java.util.HashMap<java.lang.String,java.lang.Double>();
    }
    this.resources_map.put(key, val);
  }

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

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

  public void unset_resources_map() {
    this.resources_map = null;
  }

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

  public void set_resources_map_isSet(boolean value) {
    if (!value) {
      this.resources_map = null;
    }
  }

  public int get_server_port() {
    return this.server_port;
  }

  public void set_server_port(int server_port) {
    this.server_port = server_port;
    set_server_port_isSet(true);
  }

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

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

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

  public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case TIME_SECS:
      if (value == null) {
        unset_time_secs();
      } else {
        set_time_secs((java.lang.Long)value);
      }
      break;

    case HOSTNAME:
      if (value == null) {
        unset_hostname();
      } else {
        set_hostname((java.lang.String)value);
      }
      break;

    case ASSIGNMENT_ID:
      if (value == null) {
        unset_assignment_id();
      } else {
        set_assignment_id((java.lang.String)value);
      }
      break;

    case USED_PORTS:
      if (value == null) {
        unset_used_ports();
      } else {
        set_used_ports((java.util.List<java.lang.Long>)value);
      }
      break;

    case META:
      if (value == null) {
        unset_meta();
      } else {
        set_meta((java.util.List<java.lang.Long>)value);
      }
      break;

    case SCHEDULER_META:
      if (value == null) {
        unset_scheduler_meta();
      } else {
        set_scheduler_meta((java.util.Map<java.lang.String,java.lang.String>)value);
      }
      break;

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

    case VERSION:
      if (value == null) {
        unset_version();
      } else {
        set_version((java.lang.String)value);
      }
      break;

    case RESOURCES_MAP:
      if (value == null) {
        unset_resources_map();
      } else {
        set_resources_map((java.util.Map<java.lang.String,java.lang.Double>)value);
      }
      break;

    case SERVER_PORT:
      if (value == null) {
        unset_server_port();
      } else {
        set_server_port((java.lang.Integer)value);
      }
      break;

    }
  }

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

    case HOSTNAME:
      return get_hostname();

    case ASSIGNMENT_ID:
      return get_assignment_id();

    case USED_PORTS:
      return get_used_ports();

    case META:
      return get_meta();

    case SCHEDULER_META:
      return get_scheduler_meta();

    case UPTIME_SECS:
      return get_uptime_secs();

    case VERSION:
      return get_version();

    case RESOURCES_MAP:
      return get_resources_map();

    case SERVER_PORT:
      return get_server_port();

    }
    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 TIME_SECS:
      return is_set_time_secs();
    case HOSTNAME:
      return is_set_hostname();
    case ASSIGNMENT_ID:
      return is_set_assignment_id();
    case USED_PORTS:
      return is_set_used_ports();
    case META:
      return is_set_meta();
    case SCHEDULER_META:
      return is_set_scheduler_meta();
    case UPTIME_SECS:
      return is_set_uptime_secs();
    case VERSION:
      return is_set_version();
    case RESOURCES_MAP:
      return is_set_resources_map();
    case SERVER_PORT:
      return is_set_server_port();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_time_secs = true;
    boolean that_present_time_secs = true;
    if (this_present_time_secs || that_present_time_secs) {
      if (!(this_present_time_secs && that_present_time_secs))
        return false;
      if (this.time_secs != that.time_secs)
        return false;
    }

    boolean this_present_hostname = true && this.is_set_hostname();
    boolean that_present_hostname = true && that.is_set_hostname();
    if (this_present_hostname || that_present_hostname) {
      if (!(this_present_hostname && that_present_hostname))
        return false;
      if (!this.hostname.equals(that.hostname))
        return false;
    }

    boolean this_present_assignment_id = true && this.is_set_assignment_id();
    boolean that_present_assignment_id = true && that.is_set_assignment_id();
    if (this_present_assignment_id || that_present_assignment_id) {
      if (!(this_present_assignment_id && that_present_assignment_id))
        return false;
      if (!this.assignment_id.equals(that.assignment_id))
        return false;
    }

    boolean this_present_used_ports = true && this.is_set_used_ports();
    boolean that_present_used_ports = true && that.is_set_used_ports();
    if (this_present_used_ports || that_present_used_ports) {
      if (!(this_present_used_ports && that_present_used_ports))
        return false;
      if (!this.used_ports.equals(that.used_ports))
        return false;
    }

    boolean this_present_meta = true && this.is_set_meta();
    boolean that_present_meta = true && that.is_set_meta();
    if (this_present_meta || that_present_meta) {
      if (!(this_present_meta && that_present_meta))
        return false;
      if (!this.meta.equals(that.meta))
        return false;
    }

    boolean this_present_scheduler_meta = true && this.is_set_scheduler_meta();
    boolean that_present_scheduler_meta = true && that.is_set_scheduler_meta();
    if (this_present_scheduler_meta || that_present_scheduler_meta) {
      if (!(this_present_scheduler_meta && that_present_scheduler_meta))
        return false;
      if (!this.scheduler_meta.equals(that.scheduler_meta))
        return false;
    }

    boolean this_present_uptime_secs = true && this.is_set_uptime_secs();
    boolean that_present_uptime_secs = true && that.is_set_uptime_secs();
    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_version = true && this.is_set_version();
    boolean that_present_version = true && that.is_set_version();
    if (this_present_version || that_present_version) {
      if (!(this_present_version && that_present_version))
        return false;
      if (!this.version.equals(that.version))
        return false;
    }

    boolean this_present_resources_map = true && this.is_set_resources_map();
    boolean that_present_resources_map = true && that.is_set_resources_map();
    if (this_present_resources_map || that_present_resources_map) {
      if (!(this_present_resources_map && that_present_resources_map))
        return false;
      if (!this.resources_map.equals(that.resources_map))
        return false;
    }

    boolean this_present_server_port = true && this.is_set_server_port();
    boolean that_present_server_port = true && that.is_set_server_port();
    if (this_present_server_port || that_present_server_port) {
      if (!(this_present_server_port && that_present_server_port))
        return false;
      if (this.server_port != that.server_port)
        return false;
    }

    return true;
  }

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

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

    hashCode = hashCode * 8191 + ((is_set_hostname()) ? 131071 : 524287);
    if (is_set_hostname())
      hashCode = hashCode * 8191 + hostname.hashCode();

    hashCode = hashCode * 8191 + ((is_set_assignment_id()) ? 131071 : 524287);
    if (is_set_assignment_id())
      hashCode = hashCode * 8191 + assignment_id.hashCode();

    hashCode = hashCode * 8191 + ((is_set_used_ports()) ? 131071 : 524287);
    if (is_set_used_ports())
      hashCode = hashCode * 8191 + used_ports.hashCode();

    hashCode = hashCode * 8191 + ((is_set_meta()) ? 131071 : 524287);
    if (is_set_meta())
      hashCode = hashCode * 8191 + meta.hashCode();

    hashCode = hashCode * 8191 + ((is_set_scheduler_meta()) ? 131071 : 524287);
    if (is_set_scheduler_meta())
      hashCode = hashCode * 8191 + scheduler_meta.hashCode();

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

    hashCode = hashCode * 8191 + ((is_set_version()) ? 131071 : 524287);
    if (is_set_version())
      hashCode = hashCode * 8191 + version.hashCode();

    hashCode = hashCode * 8191 + ((is_set_resources_map()) ? 131071 : 524287);
    if (is_set_resources_map())
      hashCode = hashCode * 8191 + resources_map.hashCode();

    hashCode = hashCode * 8191 + ((is_set_server_port()) ? 131071 : 524287);
    if (is_set_server_port())
      hashCode = hashCode * 8191 + server_port;

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(is_set_time_secs()).compareTo(other.is_set_time_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_time_secs()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.time_secs, other.time_secs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_hostname()).compareTo(other.is_set_hostname());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_hostname()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.hostname, other.hostname);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_assignment_id()).compareTo(other.is_set_assignment_id());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_assignment_id()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.assignment_id, other.assignment_id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_used_ports()).compareTo(other.is_set_used_ports());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_used_ports()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.used_ports, other.used_ports);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_meta()).compareTo(other.is_set_meta());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_meta()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.meta, other.meta);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_scheduler_meta()).compareTo(other.is_set_scheduler_meta());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_scheduler_meta()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.scheduler_meta, other.scheduler_meta);
      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_version()).compareTo(other.is_set_version());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_version()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.version, other.version);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_resources_map()).compareTo(other.is_set_resources_map());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_resources_map()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.resources_map, other.resources_map);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_server_port()).compareTo(other.is_set_server_port());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_server_port()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.server_port, other.server_port);
      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("SupervisorInfo(");
    boolean first = true;

    sb.append("time_secs:");
    sb.append(this.time_secs);
    first = false;
    if (!first) sb.append(", ");
    sb.append("hostname:");
    if (this.hostname == null) {
      sb.append("null");
    } else {
      sb.append(this.hostname);
    }
    first = false;
    if (is_set_assignment_id()) {
      if (!first) sb.append(", ");
      sb.append("assignment_id:");
      if (this.assignment_id == null) {
        sb.append("null");
      } else {
        sb.append(this.assignment_id);
      }
      first = false;
    }
    if (is_set_used_ports()) {
      if (!first) sb.append(", ");
      sb.append("used_ports:");
      if (this.used_ports == null) {
        sb.append("null");
      } else {
        sb.append(this.used_ports);
      }
      first = false;
    }
    if (is_set_meta()) {
      if (!first) sb.append(", ");
      sb.append("meta:");
      if (this.meta == null) {
        sb.append("null");
      } else {
        sb.append(this.meta);
      }
      first = false;
    }
    if (is_set_scheduler_meta()) {
      if (!first) sb.append(", ");
      sb.append("scheduler_meta:");
      if (this.scheduler_meta == null) {
        sb.append("null");
      } else {
        sb.append(this.scheduler_meta);
      }
      first = false;
    }
    if (is_set_uptime_secs()) {
      if (!first) sb.append(", ");
      sb.append("uptime_secs:");
      sb.append(this.uptime_secs);
      first = false;
    }
    if (is_set_version()) {
      if (!first) sb.append(", ");
      sb.append("version:");
      if (this.version == null) {
        sb.append("null");
      } else {
        sb.append(this.version);
      }
      first = false;
    }
    if (is_set_resources_map()) {
      if (!first) sb.append(", ");
      sb.append("resources_map:");
      if (this.resources_map == null) {
        sb.append("null");
      } else {
        sb.append(this.resources_map);
      }
      first = false;
    }
    if (is_set_server_port()) {
      if (!first) sb.append(", ");
      sb.append("server_port:");
      sb.append(this.server_port);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

  private static class SupervisorInfoStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<SupervisorInfo> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, SupervisorInfo 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: // TIME_SECS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I64) {
              struct.time_secs = iprot.readI64();
              struct.set_time_secs_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // HOSTNAME
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.hostname = iprot.readString();
              struct.set_hostname_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // ASSIGNMENT_ID
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.assignment_id = iprot.readString();
              struct.set_assignment_id_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // USED_PORTS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.LIST) {
              {
                org.apache.storm.thrift.protocol.TList _list672 = iprot.readListBegin();
                struct.used_ports = new java.util.ArrayList<java.lang.Long>(_list672.size);
                long _elem673;
                for (int _i674 = 0; _i674 < _list672.size; ++_i674)
                {
                  _elem673 = iprot.readI64();
                  struct.used_ports.add(_elem673);
                }
                iprot.readListEnd();
              }
              struct.set_used_ports_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // META
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.LIST) {
              {
                org.apache.storm.thrift.protocol.TList _list675 = iprot.readListBegin();
                struct.meta = new java.util.ArrayList<java.lang.Long>(_list675.size);
                long _elem676;
                for (int _i677 = 0; _i677 < _list675.size; ++_i677)
                {
                  _elem676 = iprot.readI64();
                  struct.meta.add(_elem676);
                }
                iprot.readListEnd();
              }
              struct.set_meta_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // SCHEDULER_META
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map678 = iprot.readMapBegin();
                struct.scheduler_meta = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map678.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key679;
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _val680;
                for (int _i681 = 0; _i681 < _map678.size; ++_i681)
                {
                  _key679 = iprot.readString();
                  _val680 = iprot.readString();
                  struct.scheduler_meta.put(_key679, _val680);
                }
                iprot.readMapEnd();
              }
              struct.set_scheduler_meta_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // UPTIME_SECS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I64) {
              struct.uptime_secs = iprot.readI64();
              struct.set_uptime_secs_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // VERSION
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.version = iprot.readString();
              struct.set_version_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // RESOURCES_MAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map682 = iprot.readMapBegin();
                struct.resources_map = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map682.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key683;
                double _val684;
                for (int _i685 = 0; _i685 < _map682.size; ++_i685)
                {
                  _key683 = iprot.readString();
                  _val684 = iprot.readDouble();
                  struct.resources_map.put(_key683, _val684);
                }
                iprot.readMapEnd();
              }
              struct.set_resources_map_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // SERVER_PORT
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.server_port = iprot.readI32();
              struct.set_server_port_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, SupervisorInfo struct) throws org.apache.storm.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      oprot.writeFieldBegin(TIME_SECS_FIELD_DESC);
      oprot.writeI64(struct.time_secs);
      oprot.writeFieldEnd();
      if (struct.hostname != null) {
        oprot.writeFieldBegin(HOSTNAME_FIELD_DESC);
        oprot.writeString(struct.hostname);
        oprot.writeFieldEnd();
      }
      if (struct.assignment_id != null) {
        if (struct.is_set_assignment_id()) {
          oprot.writeFieldBegin(ASSIGNMENT_ID_FIELD_DESC);
          oprot.writeString(struct.assignment_id);
          oprot.writeFieldEnd();
        }
      }
      if (struct.used_ports != null) {
        if (struct.is_set_used_ports()) {
          oprot.writeFieldBegin(USED_PORTS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.I64, struct.used_ports.size()));
            for (long _iter686 : struct.used_ports)
            {
              oprot.writeI64(_iter686);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.meta != null) {
        if (struct.is_set_meta()) {
          oprot.writeFieldBegin(META_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.I64, struct.meta.size()));
            for (long _iter687 : struct.meta)
            {
              oprot.writeI64(_iter687);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.scheduler_meta != null) {
        if (struct.is_set_scheduler_meta()) {
          oprot.writeFieldBegin(SCHEDULER_META_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRING, struct.scheduler_meta.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter688 : struct.scheduler_meta.entrySet())
            {
              oprot.writeString(_iter688.getKey());
              oprot.writeString(_iter688.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_uptime_secs()) {
        oprot.writeFieldBegin(UPTIME_SECS_FIELD_DESC);
        oprot.writeI64(struct.uptime_secs);
        oprot.writeFieldEnd();
      }
      if (struct.version != null) {
        if (struct.is_set_version()) {
          oprot.writeFieldBegin(VERSION_FIELD_DESC);
          oprot.writeString(struct.version);
          oprot.writeFieldEnd();
        }
      }
      if (struct.resources_map != null) {
        if (struct.is_set_resources_map()) {
          oprot.writeFieldBegin(RESOURCES_MAP_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, struct.resources_map.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter689 : struct.resources_map.entrySet())
            {
              oprot.writeString(_iter689.getKey());
              oprot.writeDouble(_iter689.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_server_port()) {
        oprot.writeFieldBegin(SERVER_PORT_FIELD_DESC);
        oprot.writeI32(struct.server_port);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class SupervisorInfoTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<SupervisorInfo> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, SupervisorInfo struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      oprot.writeI64(struct.time_secs);
      oprot.writeString(struct.hostname);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.is_set_assignment_id()) {
        optionals.set(0);
      }
      if (struct.is_set_used_ports()) {
        optionals.set(1);
      }
      if (struct.is_set_meta()) {
        optionals.set(2);
      }
      if (struct.is_set_scheduler_meta()) {
        optionals.set(3);
      }
      if (struct.is_set_uptime_secs()) {
        optionals.set(4);
      }
      if (struct.is_set_version()) {
        optionals.set(5);
      }
      if (struct.is_set_resources_map()) {
        optionals.set(6);
      }
      if (struct.is_set_server_port()) {
        optionals.set(7);
      }
      oprot.writeBitSet(optionals, 8);
      if (struct.is_set_assignment_id()) {
        oprot.writeString(struct.assignment_id);
      }
      if (struct.is_set_used_ports()) {
        {
          oprot.writeI32(struct.used_ports.size());
          for (long _iter690 : struct.used_ports)
          {
            oprot.writeI64(_iter690);
          }
        }
      }
      if (struct.is_set_meta()) {
        {
          oprot.writeI32(struct.meta.size());
          for (long _iter691 : struct.meta)
          {
            oprot.writeI64(_iter691);
          }
        }
      }
      if (struct.is_set_scheduler_meta()) {
        {
          oprot.writeI32(struct.scheduler_meta.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter692 : struct.scheduler_meta.entrySet())
          {
            oprot.writeString(_iter692.getKey());
            oprot.writeString(_iter692.getValue());
          }
        }
      }
      if (struct.is_set_uptime_secs()) {
        oprot.writeI64(struct.uptime_secs);
      }
      if (struct.is_set_version()) {
        oprot.writeString(struct.version);
      }
      if (struct.is_set_resources_map()) {
        {
          oprot.writeI32(struct.resources_map.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter693 : struct.resources_map.entrySet())
          {
            oprot.writeString(_iter693.getKey());
            oprot.writeDouble(_iter693.getValue());
          }
        }
      }
      if (struct.is_set_server_port()) {
        oprot.writeI32(struct.server_port);
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, SupervisorInfo struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      struct.time_secs = iprot.readI64();
      struct.set_time_secs_isSet(true);
      struct.hostname = iprot.readString();
      struct.set_hostname_isSet(true);
      java.util.BitSet incoming = iprot.readBitSet(8);
      if (incoming.get(0)) {
        struct.assignment_id = iprot.readString();
        struct.set_assignment_id_isSet(true);
      }
      if (incoming.get(1)) {
        {
          org.apache.storm.thrift.protocol.TList _list694 = new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
          struct.used_ports = new java.util.ArrayList<java.lang.Long>(_list694.size);
          long _elem695;
          for (int _i696 = 0; _i696 < _list694.size; ++_i696)
          {
            _elem695 = iprot.readI64();
            struct.used_ports.add(_elem695);
          }
        }
        struct.set_used_ports_isSet(true);
      }
      if (incoming.get(2)) {
        {
          org.apache.storm.thrift.protocol.TList _list697 = new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
          struct.meta = new java.util.ArrayList<java.lang.Long>(_list697.size);
          long _elem698;
          for (int _i699 = 0; _i699 < _list697.size; ++_i699)
          {
            _elem698 = iprot.readI64();
            struct.meta.add(_elem698);
          }
        }
        struct.set_meta_isSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.storm.thrift.protocol.TMap _map700 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRING, iprot.readI32());
          struct.scheduler_meta = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map700.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key701;
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _val702;
          for (int _i703 = 0; _i703 < _map700.size; ++_i703)
          {
            _key701 = iprot.readString();
            _val702 = iprot.readString();
            struct.scheduler_meta.put(_key701, _val702);
          }
        }
        struct.set_scheduler_meta_isSet(true);
      }
      if (incoming.get(4)) {
        struct.uptime_secs = iprot.readI64();
        struct.set_uptime_secs_isSet(true);
      }
      if (incoming.get(5)) {
        struct.version = iprot.readString();
        struct.set_version_isSet(true);
      }
      if (incoming.get(6)) {
        {
          org.apache.storm.thrift.protocol.TMap _map704 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
          struct.resources_map = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map704.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key705;
          double _val706;
          for (int _i707 = 0; _i707 < _map704.size; ++_i707)
          {
            _key705 = iprot.readString();
            _val706 = iprot.readDouble();
            struct.resources_map.put(_key705, _val706);
          }
        }
        struct.set_resources_map_isSet(true);
      }
      if (incoming.get(7)) {
        struct.server_port = iprot.readI32();
        struct.set_server_port_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();
  }
}

