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

import org.apache.commons.lang.builder.HashCodeBuilder;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.thrift.*;
import org.apache.thrift.async.*;
import org.apache.thrift.meta_data.*;
import org.apache.thrift.transport.*;
import org.apache.thrift.protocol.*;

public class TaskSummary implements TBase<TaskSummary, TaskSummary._Fields>, java.io.Serializable, Cloneable {
  private static final TStruct STRUCT_DESC = new TStruct("TaskSummary");

  private static final TField TASK_ID_FIELD_DESC = new TField("task_id", TType.I32, (short)1);
  private static final TField COMPONENT_ID_FIELD_DESC = new TField("component_id", TType.I32, (short)2);
  private static final TField HOST_FIELD_DESC = new TField("host", TType.STRING, (short)3);
  private static final TField PORT_FIELD_DESC = new TField("port", TType.I32, (short)4);
  private static final TField UPTIME_SECS_FIELD_DESC = new TField("uptime_secs", TType.I32, (short)5);
  private static final TField ERRORS_FIELD_DESC = new TField("errors", TType.LIST, (short)6);
  private static final TField STATS_FIELD_DESC = new TField("stats", TType.STRUCT, (short)7);

  private int task_id;
  private int component_id;
  private String host;
  private int port;
  private int uptime_secs;
  private List<ErrorInfo> errors;
  private TaskStats stats;

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements TFieldIdEnum {
    TASK_ID((short)1, "task_id"),
    COMPONENT_ID((short)2, "component_id"),
    HOST((short)3, "host"),
    PORT((short)4, "port"),
    UPTIME_SECS((short)5, "uptime_secs"),
    ERRORS((short)6, "errors"),
    STATS((short)7, "stats");

    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

    static {
      for (_Fields field : EnumSet.allOf(_Fields.class)) {
        byName.put(field.getFieldName(), field);
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // TASK_ID
          return TASK_ID;
        case 2: // COMPONENT_ID
          return COMPONENT_ID;
        case 3: // HOST
          return HOST;
        case 4: // PORT
          return PORT;
        case 5: // UPTIME_SECS
          return UPTIME_SECS;
        case 6: // ERRORS
          return ERRORS;
        case 7: // STATS
          return STATS;
        default:
          return null;
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, throwing an exception
     * if it is not found.
     */
    public static _Fields findByThriftIdOrThrow(int fieldId) {
      _Fields fields = findByThriftId(fieldId);
      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    public static _Fields findByName(String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final String _fieldName;

    _Fields(short thriftId, String fieldName) {
      _thriftId = thriftId;
      _fieldName = fieldName;
    }

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __TASK_ID_ISSET_ID = 0;
  private static final int __COMPONENT_ID_ISSET_ID = 1;
  private static final int __PORT_ISSET_ID = 2;
  private static final int __UPTIME_SECS_ISSET_ID = 3;
  private BitSet __isset_bit_vector = new BitSet(4);

  public static final Map<_Fields, FieldMetaData> metaDataMap;
  static {
    Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.TASK_ID, new FieldMetaData("task_id", TFieldRequirementType.REQUIRED, 
        new FieldValueMetaData(TType.I32)));
    tmpMap.put(_Fields.COMPONENT_ID, new FieldMetaData("component_id", TFieldRequirementType.REQUIRED, 
        new FieldValueMetaData(TType.I32)));
    tmpMap.put(_Fields.HOST, new FieldMetaData("host", TFieldRequirementType.REQUIRED, 
        new FieldValueMetaData(TType.STRING)));
    tmpMap.put(_Fields.PORT, new FieldMetaData("port", TFieldRequirementType.REQUIRED, 
        new FieldValueMetaData(TType.I32)));
    tmpMap.put(_Fields.UPTIME_SECS, new FieldMetaData("uptime_secs", TFieldRequirementType.REQUIRED, 
        new FieldValueMetaData(TType.I32)));
    tmpMap.put(_Fields.ERRORS, new FieldMetaData("errors", TFieldRequirementType.REQUIRED, 
        new ListMetaData(TType.LIST, 
            new StructMetaData(TType.STRUCT, ErrorInfo.class))));
    tmpMap.put(_Fields.STATS, new FieldMetaData("stats", TFieldRequirementType.OPTIONAL, 
        new StructMetaData(TType.STRUCT, TaskStats.class)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    FieldMetaData.addStructMetaDataMap(TaskSummary.class, metaDataMap);
  }

  public TaskSummary() {
  }

  public TaskSummary(
    int task_id,
    int component_id,
    String host,
    int port,
    int uptime_secs,
    List<ErrorInfo> errors)
  {
    this();
    this.task_id = task_id;
    set_task_id_isSet(true);
    this.component_id = component_id;
    set_component_id_isSet(true);
    this.host = host;
    this.port = port;
    set_port_isSet(true);
    this.uptime_secs = uptime_secs;
    set_uptime_secs_isSet(true);
    this.errors = errors;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TaskSummary(TaskSummary other) {
    __isset_bit_vector.clear();
    __isset_bit_vector.or(other.__isset_bit_vector);
    this.task_id = other.task_id;
    this.component_id = other.component_id;
    if (other.is_set_host()) {
      this.host = other.host;
    }
    this.port = other.port;
    this.uptime_secs = other.uptime_secs;
    if (other.is_set_errors()) {
      List<ErrorInfo> __this__errors = new ArrayList<ErrorInfo>();
      for (ErrorInfo other_element : other.errors) {
        __this__errors.add(new ErrorInfo(other_element));
      }
      this.errors = __this__errors;
    }
    if (other.is_set_stats()) {
      this.stats = new TaskStats(other.stats);
    }
  }

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

  @Deprecated
  public TaskSummary clone() {
    return new TaskSummary(this);
  }

  public int get_task_id() {
    return this.task_id;
  }

  public void set_task_id(int task_id) {
    this.task_id = task_id;
    set_task_id_isSet(true);
  }

  public void unset_task_id() {
    __isset_bit_vector.clear(__TASK_ID_ISSET_ID);
  }

  /** Returns true if field task_id is set (has been asigned a value) and false otherwise */
  public boolean is_set_task_id() {
    return __isset_bit_vector.get(__TASK_ID_ISSET_ID);
  }

  public void set_task_id_isSet(boolean value) {
    __isset_bit_vector.set(__TASK_ID_ISSET_ID, value);
  }

  public int get_component_id() {
    return this.component_id;
  }

  public void set_component_id(int component_id) {
    this.component_id = component_id;
    set_component_id_isSet(true);
  }

  public void unset_component_id() {
    __isset_bit_vector.clear(__COMPONENT_ID_ISSET_ID);
  }

  /** Returns true if field component_id is set (has been asigned a value) and false otherwise */
  public boolean is_set_component_id() {
    return __isset_bit_vector.get(__COMPONENT_ID_ISSET_ID);
  }

  public void set_component_id_isSet(boolean value) {
    __isset_bit_vector.set(__COMPONENT_ID_ISSET_ID, value);
  }

  public String get_host() {
    return this.host;
  }

  public void set_host(String host) {
    this.host = host;
  }

  public void unset_host() {
    this.host = null;
  }

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

  public void set_host_isSet(boolean value) {
    if (!value) {
      this.host = null;
    }
  }

  public int get_port() {
    return this.port;
  }

  public void set_port(int port) {
    this.port = port;
    set_port_isSet(true);
  }

  public void unset_port() {
    __isset_bit_vector.clear(__PORT_ISSET_ID);
  }

  /** Returns true if field port is set (has been asigned a value) and false otherwise */
  public boolean is_set_port() {
    return __isset_bit_vector.get(__PORT_ISSET_ID);
  }

  public void set_port_isSet(boolean value) {
    __isset_bit_vector.set(__PORT_ISSET_ID, value);
  }

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

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

  public void unset_uptime_secs() {
    __isset_bit_vector.clear(__UPTIME_SECS_ISSET_ID);
  }

  /** Returns true if field uptime_secs is set (has been asigned a value) and false otherwise */
  public boolean is_set_uptime_secs() {
    return __isset_bit_vector.get(__UPTIME_SECS_ISSET_ID);
  }

  public void set_uptime_secs_isSet(boolean value) {
    __isset_bit_vector.set(__UPTIME_SECS_ISSET_ID, value);
  }

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

  public java.util.Iterator<ErrorInfo> get_errors_iterator() {
    return (this.errors == null) ? null : this.errors.iterator();
  }

  public void add_to_errors(ErrorInfo elem) {
    if (this.errors == null) {
      this.errors = new ArrayList<ErrorInfo>();
    }
    this.errors.add(elem);
  }

  public List<ErrorInfo> get_errors() {
    return this.errors;
  }

  public void set_errors(List<ErrorInfo> errors) {
    this.errors = errors;
  }

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

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

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

  public TaskStats get_stats() {
    return this.stats;
  }

  public void set_stats(TaskStats stats) {
    this.stats = stats;
  }

  public void unset_stats() {
    this.stats = null;
  }

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

  public void set_stats_isSet(boolean value) {
    if (!value) {
      this.stats = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case TASK_ID:
      if (value == null) {
        unset_task_id();
      } else {
        set_task_id((Integer)value);
      }
      break;

    case COMPONENT_ID:
      if (value == null) {
        unset_component_id();
      } else {
        set_component_id((Integer)value);
      }
      break;

    case HOST:
      if (value == null) {
        unset_host();
      } else {
        set_host((String)value);
      }
      break;

    case PORT:
      if (value == null) {
        unset_port();
      } else {
        set_port((Integer)value);
      }
      break;

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

    case ERRORS:
      if (value == null) {
        unset_errors();
      } else {
        set_errors((List<ErrorInfo>)value);
      }
      break;

    case STATS:
      if (value == null) {
        unset_stats();
      } else {
        set_stats((TaskStats)value);
      }
      break;

    }
  }

  public void setFieldValue(int fieldID, Object value) {
    setFieldValue(_Fields.findByThriftIdOrThrow(fieldID), value);
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case TASK_ID:
      return new Integer(get_task_id());

    case COMPONENT_ID:
      return new Integer(get_component_id());

    case HOST:
      return get_host();

    case PORT:
      return new Integer(get_port());

    case UPTIME_SECS:
      return new Integer(get_uptime_secs());

    case ERRORS:
      return get_errors();

    case STATS:
      return get_stats();

    }
    throw new IllegalStateException();
  }

  public Object getFieldValue(int fieldId) {
    return getFieldValue(_Fields.findByThriftIdOrThrow(fieldId));
  }

  /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */
  public boolean isSet(_Fields field) {
    switch (field) {
    case TASK_ID:
      return is_set_task_id();
    case COMPONENT_ID:
      return is_set_component_id();
    case HOST:
      return is_set_host();
    case PORT:
      return is_set_port();
    case UPTIME_SECS:
      return is_set_uptime_secs();
    case ERRORS:
      return is_set_errors();
    case STATS:
      return is_set_stats();
    }
    throw new IllegalStateException();
  }

  public boolean isSet(int fieldID) {
    return isSet(_Fields.findByThriftIdOrThrow(fieldID));
  }

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

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

    boolean this_present_task_id = true;
    boolean that_present_task_id = true;
    if (this_present_task_id || that_present_task_id) {
      if (!(this_present_task_id && that_present_task_id))
        return false;
      if (this.task_id != that.task_id)
        return false;
    }

    boolean this_present_component_id = true;
    boolean that_present_component_id = true;
    if (this_present_component_id || that_present_component_id) {
      if (!(this_present_component_id && that_present_component_id))
        return false;
      if (this.component_id != that.component_id)
        return false;
    }

    boolean this_present_host = true && this.is_set_host();
    boolean that_present_host = true && that.is_set_host();
    if (this_present_host || that_present_host) {
      if (!(this_present_host && that_present_host))
        return false;
      if (!this.host.equals(that.host))
        return false;
    }

    boolean this_present_port = true;
    boolean that_present_port = true;
    if (this_present_port || that_present_port) {
      if (!(this_present_port && that_present_port))
        return false;
      if (this.port != that.port)
        return false;
    }

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

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

    boolean this_present_stats = true && this.is_set_stats();
    boolean that_present_stats = true && that.is_set_stats();
    if (this_present_stats || that_present_stats) {
      if (!(this_present_stats && that_present_stats))
        return false;
      if (!this.stats.equals(that.stats))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    HashCodeBuilder builder = new HashCodeBuilder();

    boolean present_task_id = true;
    builder.append(present_task_id);
    if (present_task_id)
      builder.append(task_id);

    boolean present_component_id = true;
    builder.append(present_component_id);
    if (present_component_id)
      builder.append(component_id);

    boolean present_host = true && (is_set_host());
    builder.append(present_host);
    if (present_host)
      builder.append(host);

    boolean present_port = true;
    builder.append(present_port);
    if (present_port)
      builder.append(port);

    boolean present_uptime_secs = true;
    builder.append(present_uptime_secs);
    if (present_uptime_secs)
      builder.append(uptime_secs);

    boolean present_errors = true && (is_set_errors());
    builder.append(present_errors);
    if (present_errors)
      builder.append(errors);

    boolean present_stats = true && (is_set_stats());
    builder.append(present_stats);
    if (present_stats)
      builder.append(stats);

    return builder.toHashCode();
  }

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

    int lastComparison = 0;
    TaskSummary typedOther = (TaskSummary)other;

    lastComparison = Boolean.valueOf(is_set_task_id()).compareTo(typedOther.is_set_task_id());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_task_id()) {      lastComparison = TBaseHelper.compareTo(this.task_id, typedOther.task_id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_component_id()).compareTo(typedOther.is_set_component_id());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_component_id()) {      lastComparison = TBaseHelper.compareTo(this.component_id, typedOther.component_id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_host()).compareTo(typedOther.is_set_host());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_host()) {      lastComparison = TBaseHelper.compareTo(this.host, typedOther.host);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_port()).compareTo(typedOther.is_set_port());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_port()) {      lastComparison = TBaseHelper.compareTo(this.port, typedOther.port);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_uptime_secs()).compareTo(typedOther.is_set_uptime_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_uptime_secs()) {      lastComparison = TBaseHelper.compareTo(this.uptime_secs, typedOther.uptime_secs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_errors()).compareTo(typedOther.is_set_errors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_errors()) {      lastComparison = TBaseHelper.compareTo(this.errors, typedOther.errors);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(is_set_stats()).compareTo(typedOther.is_set_stats());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_stats()) {      lastComparison = TBaseHelper.compareTo(this.stats, typedOther.stats);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  public void read(TProtocol iprot) throws TException {
    TField field;
    iprot.readStructBegin();
    while (true)
    {
      field = iprot.readFieldBegin();
      if (field.type == TType.STOP) { 
        break;
      }
      switch (field.id) {
        case 1: // TASK_ID
          if (field.type == TType.I32) {
            this.task_id = iprot.readI32();
            set_task_id_isSet(true);
          } else { 
            TProtocolUtil.skip(iprot, field.type);
          }
          break;
        case 2: // COMPONENT_ID
          if (field.type == TType.I32) {
            this.component_id = iprot.readI32();
            set_component_id_isSet(true);
          } else { 
            TProtocolUtil.skip(iprot, field.type);
          }
          break;
        case 3: // HOST
          if (field.type == TType.STRING) {
            this.host = iprot.readString();
          } else { 
            TProtocolUtil.skip(iprot, field.type);
          }
          break;
        case 4: // PORT
          if (field.type == TType.I32) {
            this.port = iprot.readI32();
            set_port_isSet(true);
          } else { 
            TProtocolUtil.skip(iprot, field.type);
          }
          break;
        case 5: // UPTIME_SECS
          if (field.type == TType.I32) {
            this.uptime_secs = iprot.readI32();
            set_uptime_secs_isSet(true);
          } else { 
            TProtocolUtil.skip(iprot, field.type);
          }
          break;
        case 6: // ERRORS
          if (field.type == TType.LIST) {
            {
              TList _list121 = iprot.readListBegin();
              this.errors = new ArrayList<ErrorInfo>(_list121.size);
              for (int _i122 = 0; _i122 < _list121.size; ++_i122)
              {
                ErrorInfo _elem123;
                _elem123 = new ErrorInfo();
                _elem123.read(iprot);
                this.errors.add(_elem123);
              }
              iprot.readListEnd();
            }
          } else { 
            TProtocolUtil.skip(iprot, field.type);
          }
          break;
        case 7: // STATS
          if (field.type == TType.STRUCT) {
            this.stats = new TaskStats();
            this.stats.read(iprot);
          } else { 
            TProtocolUtil.skip(iprot, field.type);
          }
          break;
        default:
          TProtocolUtil.skip(iprot, field.type);
      }
      iprot.readFieldEnd();
    }
    iprot.readStructEnd();
    validate();
  }

  public void write(TProtocol oprot) throws TException {
    validate();

    oprot.writeStructBegin(STRUCT_DESC);
    oprot.writeFieldBegin(TASK_ID_FIELD_DESC);
    oprot.writeI32(this.task_id);
    oprot.writeFieldEnd();
    oprot.writeFieldBegin(COMPONENT_ID_FIELD_DESC);
    oprot.writeI32(this.component_id);
    oprot.writeFieldEnd();
    if (this.host != null) {
      oprot.writeFieldBegin(HOST_FIELD_DESC);
      oprot.writeString(this.host);
      oprot.writeFieldEnd();
    }
    oprot.writeFieldBegin(PORT_FIELD_DESC);
    oprot.writeI32(this.port);
    oprot.writeFieldEnd();
    oprot.writeFieldBegin(UPTIME_SECS_FIELD_DESC);
    oprot.writeI32(this.uptime_secs);
    oprot.writeFieldEnd();
    if (this.errors != null) {
      oprot.writeFieldBegin(ERRORS_FIELD_DESC);
      {
        oprot.writeListBegin(new TList(TType.STRUCT, this.errors.size()));
        for (ErrorInfo _iter124 : this.errors)
        {
          _iter124.write(oprot);
        }
        oprot.writeListEnd();
      }
      oprot.writeFieldEnd();
    }
    if (this.stats != null) {
      if (is_set_stats()) {
        oprot.writeFieldBegin(STATS_FIELD_DESC);
        this.stats.write(oprot);
        oprot.writeFieldEnd();
      }
    }
    oprot.writeFieldStop();
    oprot.writeStructEnd();
  }

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

    sb.append("task_id:");
    sb.append(this.task_id);
    first = false;
    if (!first) sb.append(", ");
    sb.append("component_id:");
    sb.append(this.component_id);
    first = false;
    if (!first) sb.append(", ");
    sb.append("host:");
    if (this.host == null) {
      sb.append("null");
    } else {
      sb.append(this.host);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("port:");
    sb.append(this.port);
    first = false;
    if (!first) sb.append(", ");
    sb.append("uptime_secs:");
    sb.append(this.uptime_secs);
    first = false;
    if (!first) sb.append(", ");
    sb.append("errors:");
    if (this.errors == null) {
      sb.append("null");
    } else {
      sb.append(this.errors);
    }
    first = false;
    if (is_set_stats()) {
      if (!first) sb.append(", ");
      sb.append("stats:");
      if (this.stats == null) {
        sb.append("null");
      } else {
        sb.append(this.stats);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

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

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

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

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

  }

}

