/**
 * Autogenerated by Thrift Compiler (0.14.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.hadoop.hbase.thrift2.generated;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
 * Used to perform Get operations on a single row.
 * 
 * The scope can be further narrowed down by specifying a list of
 * columns or column families.
 * 
 * To get everything for a row, instantiate a Get object with just the row to get.
 * To further define the scope of what to get you can add a timestamp or time range
 * with an optional maximum number of versions to return.
 * 
 * If you specify a time range and a timestamp the range is ignored.
 * Timestamps on TColumns are ignored.
 */
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.14.1)", date = "2021-07-19")
public class TGet implements org.apache.thrift.TBase<TGet, TGet._Fields>, java.io.Serializable, Cloneable, Comparable<TGet> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TGet");

  private static final org.apache.thrift.protocol.TField ROW_FIELD_DESC = new org.apache.thrift.protocol.TField("row", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField COLUMNS_FIELD_DESC = new org.apache.thrift.protocol.TField("columns", org.apache.thrift.protocol.TType.LIST, (short)2);
  private static final org.apache.thrift.protocol.TField TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("timestamp", org.apache.thrift.protocol.TType.I64, (short)3);
  private static final org.apache.thrift.protocol.TField TIME_RANGE_FIELD_DESC = new org.apache.thrift.protocol.TField("timeRange", org.apache.thrift.protocol.TType.STRUCT, (short)4);
  private static final org.apache.thrift.protocol.TField MAX_VERSIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("maxVersions", org.apache.thrift.protocol.TType.I32, (short)5);
  private static final org.apache.thrift.protocol.TField FILTER_STRING_FIELD_DESC = new org.apache.thrift.protocol.TField("filterString", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField ATTRIBUTES_FIELD_DESC = new org.apache.thrift.protocol.TField("attributes", org.apache.thrift.protocol.TType.MAP, (short)7);
  private static final org.apache.thrift.protocol.TField AUTHORIZATIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("authorizations", org.apache.thrift.protocol.TType.STRUCT, (short)8);
  private static final org.apache.thrift.protocol.TField CONSISTENCY_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency", org.apache.thrift.protocol.TType.I32, (short)9);
  private static final org.apache.thrift.protocol.TField TARGET_REPLICA_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("targetReplicaId", org.apache.thrift.protocol.TType.I32, (short)10);
  private static final org.apache.thrift.protocol.TField CACHE_BLOCKS_FIELD_DESC = new org.apache.thrift.protocol.TField("cacheBlocks", org.apache.thrift.protocol.TType.BOOL, (short)11);
  private static final org.apache.thrift.protocol.TField STORE_LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("storeLimit", org.apache.thrift.protocol.TType.I32, (short)12);
  private static final org.apache.thrift.protocol.TField STORE_OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("storeOffset", org.apache.thrift.protocol.TType.I32, (short)13);
  private static final org.apache.thrift.protocol.TField EXISTENCE_ONLY_FIELD_DESC = new org.apache.thrift.protocol.TField("existence_only", org.apache.thrift.protocol.TType.BOOL, (short)14);
  private static final org.apache.thrift.protocol.TField FILTER_BYTES_FIELD_DESC = new org.apache.thrift.protocol.TField("filterBytes", org.apache.thrift.protocol.TType.STRING, (short)15);

  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new TGetStandardSchemeFactory();
  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new TGetTupleSchemeFactory();

  public @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer row; // required
  public @org.apache.thrift.annotation.Nullable java.util.List<TColumn> columns; // optional
  public long timestamp; // optional
  public @org.apache.thrift.annotation.Nullable TTimeRange timeRange; // optional
  public int maxVersions; // optional
  public @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer filterString; // optional
  public @org.apache.thrift.annotation.Nullable java.util.Map<java.nio.ByteBuffer,java.nio.ByteBuffer> attributes; // optional
  public @org.apache.thrift.annotation.Nullable TAuthorization authorizations; // optional
  /**
   * 
   * @see TConsistency
   */
  public @org.apache.thrift.annotation.Nullable TConsistency consistency; // optional
  public int targetReplicaId; // optional
  public boolean cacheBlocks; // optional
  public int storeLimit; // optional
  public int storeOffset; // optional
  public boolean existence_only; // optional
  public @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer filterBytes; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    ROW((short)1, "row"),
    COLUMNS((short)2, "columns"),
    TIMESTAMP((short)3, "timestamp"),
    TIME_RANGE((short)4, "timeRange"),
    MAX_VERSIONS((short)5, "maxVersions"),
    FILTER_STRING((short)6, "filterString"),
    ATTRIBUTES((short)7, "attributes"),
    AUTHORIZATIONS((short)8, "authorizations"),
    /**
     * 
     * @see TConsistency
     */
    CONSISTENCY((short)9, "consistency"),
    TARGET_REPLICA_ID((short)10, "targetReplicaId"),
    CACHE_BLOCKS((short)11, "cacheBlocks"),
    STORE_LIMIT((short)12, "storeLimit"),
    STORE_OFFSET((short)13, "storeOffset"),
    EXISTENCE_ONLY((short)14, "existence_only"),
    FILTER_BYTES((short)15, "filterBytes");

    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.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // ROW
          return ROW;
        case 2: // COLUMNS
          return COLUMNS;
        case 3: // TIMESTAMP
          return TIMESTAMP;
        case 4: // TIME_RANGE
          return TIME_RANGE;
        case 5: // MAX_VERSIONS
          return MAX_VERSIONS;
        case 6: // FILTER_STRING
          return FILTER_STRING;
        case 7: // ATTRIBUTES
          return ATTRIBUTES;
        case 8: // AUTHORIZATIONS
          return AUTHORIZATIONS;
        case 9: // CONSISTENCY
          return CONSISTENCY;
        case 10: // TARGET_REPLICA_ID
          return TARGET_REPLICA_ID;
        case 11: // CACHE_BLOCKS
          return CACHE_BLOCKS;
        case 12: // STORE_LIMIT
          return STORE_LIMIT;
        case 13: // STORE_OFFSET
          return STORE_OFFSET;
        case 14: // EXISTENCE_ONLY
          return EXISTENCE_ONLY;
        case 15: // FILTER_BYTES
          return FILTER_BYTES;
        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.thrift.annotation.Nullable
    public static _Fields findByName(java.lang.String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final java.lang.String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public java.lang.String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __TIMESTAMP_ISSET_ID = 0;
  private static final int __MAXVERSIONS_ISSET_ID = 1;
  private static final int __TARGETREPLICAID_ISSET_ID = 2;
  private static final int __CACHEBLOCKS_ISSET_ID = 3;
  private static final int __STORELIMIT_ISSET_ID = 4;
  private static final int __STOREOFFSET_ISSET_ID = 5;
  private static final int __EXISTENCE_ONLY_ISSET_ID = 6;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.COLUMNS,_Fields.TIMESTAMP,_Fields.TIME_RANGE,_Fields.MAX_VERSIONS,_Fields.FILTER_STRING,_Fields.ATTRIBUTES,_Fields.AUTHORIZATIONS,_Fields.CONSISTENCY,_Fields.TARGET_REPLICA_ID,_Fields.CACHE_BLOCKS,_Fields.STORE_LIMIT,_Fields.STORE_OFFSET,_Fields.EXISTENCE_ONLY,_Fields.FILTER_BYTES};
  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.ROW, new org.apache.thrift.meta_data.FieldMetaData("row", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
    tmpMap.put(_Fields.COLUMNS, new org.apache.thrift.meta_data.FieldMetaData("columns", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TColumn.class))));
    tmpMap.put(_Fields.TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("timestamp", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.TIME_RANGE, new org.apache.thrift.meta_data.FieldMetaData("timeRange", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TTimeRange.class)));
    tmpMap.put(_Fields.MAX_VERSIONS, new org.apache.thrift.meta_data.FieldMetaData("maxVersions", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.FILTER_STRING, new org.apache.thrift.meta_data.FieldMetaData("filterString", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
    tmpMap.put(_Fields.ATTRIBUTES, new org.apache.thrift.meta_data.FieldMetaData("attributes", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING            , true), 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING            , true))));
    tmpMap.put(_Fields.AUTHORIZATIONS, new org.apache.thrift.meta_data.FieldMetaData("authorizations", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TAuthorization.class)));
    tmpMap.put(_Fields.CONSISTENCY, new org.apache.thrift.meta_data.FieldMetaData("consistency", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TConsistency.class)));
    tmpMap.put(_Fields.TARGET_REPLICA_ID, new org.apache.thrift.meta_data.FieldMetaData("targetReplicaId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.CACHE_BLOCKS, new org.apache.thrift.meta_data.FieldMetaData("cacheBlocks", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.STORE_LIMIT, new org.apache.thrift.meta_data.FieldMetaData("storeLimit", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.STORE_OFFSET, new org.apache.thrift.meta_data.FieldMetaData("storeOffset", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.EXISTENCE_ONLY, new org.apache.thrift.meta_data.FieldMetaData("existence_only", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.FILTER_BYTES, new org.apache.thrift.meta_data.FieldMetaData("filterBytes", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TGet.class, metaDataMap);
  }

  public TGet() {
  }

  public TGet(
    java.nio.ByteBuffer row)
  {
    this();
    this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TGet(TGet other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetRow()) {
      this.row = org.apache.thrift.TBaseHelper.copyBinary(other.row);
    }
    if (other.isSetColumns()) {
      java.util.List<TColumn> __this__columns = new java.util.ArrayList<TColumn>(other.columns.size());
      for (TColumn other_element : other.columns) {
        __this__columns.add(new TColumn(other_element));
      }
      this.columns = __this__columns;
    }
    this.timestamp = other.timestamp;
    if (other.isSetTimeRange()) {
      this.timeRange = new TTimeRange(other.timeRange);
    }
    this.maxVersions = other.maxVersions;
    if (other.isSetFilterString()) {
      this.filterString = org.apache.thrift.TBaseHelper.copyBinary(other.filterString);
    }
    if (other.isSetAttributes()) {
      java.util.Map<java.nio.ByteBuffer,java.nio.ByteBuffer> __this__attributes = new java.util.HashMap<java.nio.ByteBuffer,java.nio.ByteBuffer>(other.attributes);
      this.attributes = __this__attributes;
    }
    if (other.isSetAuthorizations()) {
      this.authorizations = new TAuthorization(other.authorizations);
    }
    if (other.isSetConsistency()) {
      this.consistency = other.consistency;
    }
    this.targetReplicaId = other.targetReplicaId;
    this.cacheBlocks = other.cacheBlocks;
    this.storeLimit = other.storeLimit;
    this.storeOffset = other.storeOffset;
    this.existence_only = other.existence_only;
    if (other.isSetFilterBytes()) {
      this.filterBytes = org.apache.thrift.TBaseHelper.copyBinary(other.filterBytes);
    }
  }

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

  @Override
  public void clear() {
    this.row = null;
    this.columns = null;
    setTimestampIsSet(false);
    this.timestamp = 0;
    this.timeRange = null;
    setMaxVersionsIsSet(false);
    this.maxVersions = 0;
    this.filterString = null;
    this.attributes = null;
    this.authorizations = null;
    this.consistency = null;
    setTargetReplicaIdIsSet(false);
    this.targetReplicaId = 0;
    setCacheBlocksIsSet(false);
    this.cacheBlocks = false;
    setStoreLimitIsSet(false);
    this.storeLimit = 0;
    setStoreOffsetIsSet(false);
    this.storeOffset = 0;
    setExistence_onlyIsSet(false);
    this.existence_only = false;
    this.filterBytes = null;
  }

  public byte[] getRow() {
    setRow(org.apache.thrift.TBaseHelper.rightSize(row));
    return row == null ? null : row.array();
  }

  public java.nio.ByteBuffer bufferForRow() {
    return org.apache.thrift.TBaseHelper.copyBinary(row);
  }

  public TGet setRow(byte[] row) {
    this.row = row == null ? (java.nio.ByteBuffer)null   : java.nio.ByteBuffer.wrap(row.clone());
    return this;
  }

  public TGet setRow(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer row) {
    this.row = org.apache.thrift.TBaseHelper.copyBinary(row);
    return this;
  }

  public void unsetRow() {
    this.row = null;
  }

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

  public void setRowIsSet(boolean value) {
    if (!value) {
      this.row = null;
    }
  }

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

  @org.apache.thrift.annotation.Nullable
  public java.util.Iterator<TColumn> getColumnsIterator() {
    return (this.columns == null) ? null : this.columns.iterator();
  }

  public void addToColumns(TColumn elem) {
    if (this.columns == null) {
      this.columns = new java.util.ArrayList<TColumn>();
    }
    this.columns.add(elem);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.List<TColumn> getColumns() {
    return this.columns;
  }

  public TGet setColumns(@org.apache.thrift.annotation.Nullable java.util.List<TColumn> columns) {
    this.columns = columns;
    return this;
  }

  public void unsetColumns() {
    this.columns = null;
  }

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

  public void setColumnsIsSet(boolean value) {
    if (!value) {
      this.columns = null;
    }
  }

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

  public TGet setTimestamp(long timestamp) {
    this.timestamp = timestamp;
    setTimestampIsSet(true);
    return this;
  }

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

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

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

  @org.apache.thrift.annotation.Nullable
  public TTimeRange getTimeRange() {
    return this.timeRange;
  }

  public TGet setTimeRange(@org.apache.thrift.annotation.Nullable TTimeRange timeRange) {
    this.timeRange = timeRange;
    return this;
  }

  public void unsetTimeRange() {
    this.timeRange = null;
  }

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

  public void setTimeRangeIsSet(boolean value) {
    if (!value) {
      this.timeRange = null;
    }
  }

  public int getMaxVersions() {
    return this.maxVersions;
  }

  public TGet setMaxVersions(int maxVersions) {
    this.maxVersions = maxVersions;
    setMaxVersionsIsSet(true);
    return this;
  }

  public void unsetMaxVersions() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __MAXVERSIONS_ISSET_ID);
  }

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

  public void setMaxVersionsIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __MAXVERSIONS_ISSET_ID, value);
  }

  public byte[] getFilterString() {
    setFilterString(org.apache.thrift.TBaseHelper.rightSize(filterString));
    return filterString == null ? null : filterString.array();
  }

  public java.nio.ByteBuffer bufferForFilterString() {
    return org.apache.thrift.TBaseHelper.copyBinary(filterString);
  }

  public TGet setFilterString(byte[] filterString) {
    this.filterString = filterString == null ? (java.nio.ByteBuffer)null   : java.nio.ByteBuffer.wrap(filterString.clone());
    return this;
  }

  public TGet setFilterString(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer filterString) {
    this.filterString = org.apache.thrift.TBaseHelper.copyBinary(filterString);
    return this;
  }

  public void unsetFilterString() {
    this.filterString = null;
  }

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

  public void setFilterStringIsSet(boolean value) {
    if (!value) {
      this.filterString = null;
    }
  }

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

  public void putToAttributes(java.nio.ByteBuffer key, java.nio.ByteBuffer val) {
    if (this.attributes == null) {
      this.attributes = new java.util.HashMap<java.nio.ByteBuffer,java.nio.ByteBuffer>();
    }
    this.attributes.put(key, val);
  }

  @org.apache.thrift.annotation.Nullable
  public java.util.Map<java.nio.ByteBuffer,java.nio.ByteBuffer> getAttributes() {
    return this.attributes;
  }

  public TGet setAttributes(@org.apache.thrift.annotation.Nullable java.util.Map<java.nio.ByteBuffer,java.nio.ByteBuffer> attributes) {
    this.attributes = attributes;
    return this;
  }

  public void unsetAttributes() {
    this.attributes = null;
  }

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

  public void setAttributesIsSet(boolean value) {
    if (!value) {
      this.attributes = null;
    }
  }

  @org.apache.thrift.annotation.Nullable
  public TAuthorization getAuthorizations() {
    return this.authorizations;
  }

  public TGet setAuthorizations(@org.apache.thrift.annotation.Nullable TAuthorization authorizations) {
    this.authorizations = authorizations;
    return this;
  }

  public void unsetAuthorizations() {
    this.authorizations = null;
  }

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

  public void setAuthorizationsIsSet(boolean value) {
    if (!value) {
      this.authorizations = null;
    }
  }

  /**
   * 
   * @see TConsistency
   */
  @org.apache.thrift.annotation.Nullable
  public TConsistency getConsistency() {
    return this.consistency;
  }

  /**
   * 
   * @see TConsistency
   */
  public TGet setConsistency(@org.apache.thrift.annotation.Nullable TConsistency consistency) {
    this.consistency = consistency;
    return this;
  }

  public void unsetConsistency() {
    this.consistency = null;
  }

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

  public void setConsistencyIsSet(boolean value) {
    if (!value) {
      this.consistency = null;
    }
  }

  public int getTargetReplicaId() {
    return this.targetReplicaId;
  }

  public TGet setTargetReplicaId(int targetReplicaId) {
    this.targetReplicaId = targetReplicaId;
    setTargetReplicaIdIsSet(true);
    return this;
  }

  public void unsetTargetReplicaId() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __TARGETREPLICAID_ISSET_ID);
  }

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

  public void setTargetReplicaIdIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __TARGETREPLICAID_ISSET_ID, value);
  }

  public boolean isCacheBlocks() {
    return this.cacheBlocks;
  }

  public TGet setCacheBlocks(boolean cacheBlocks) {
    this.cacheBlocks = cacheBlocks;
    setCacheBlocksIsSet(true);
    return this;
  }

  public void unsetCacheBlocks() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CACHEBLOCKS_ISSET_ID);
  }

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

  public void setCacheBlocksIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CACHEBLOCKS_ISSET_ID, value);
  }

  public int getStoreLimit() {
    return this.storeLimit;
  }

  public TGet setStoreLimit(int storeLimit) {
    this.storeLimit = storeLimit;
    setStoreLimitIsSet(true);
    return this;
  }

  public void unsetStoreLimit() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __STORELIMIT_ISSET_ID);
  }

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

  public void setStoreLimitIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __STORELIMIT_ISSET_ID, value);
  }

  public int getStoreOffset() {
    return this.storeOffset;
  }

  public TGet setStoreOffset(int storeOffset) {
    this.storeOffset = storeOffset;
    setStoreOffsetIsSet(true);
    return this;
  }

  public void unsetStoreOffset() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __STOREOFFSET_ISSET_ID);
  }

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

  public void setStoreOffsetIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __STOREOFFSET_ISSET_ID, value);
  }

  public boolean isExistence_only() {
    return this.existence_only;
  }

  public TGet setExistence_only(boolean existence_only) {
    this.existence_only = existence_only;
    setExistence_onlyIsSet(true);
    return this;
  }

  public void unsetExistence_only() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __EXISTENCE_ONLY_ISSET_ID);
  }

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

  public void setExistence_onlyIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __EXISTENCE_ONLY_ISSET_ID, value);
  }

  public byte[] getFilterBytes() {
    setFilterBytes(org.apache.thrift.TBaseHelper.rightSize(filterBytes));
    return filterBytes == null ? null : filterBytes.array();
  }

  public java.nio.ByteBuffer bufferForFilterBytes() {
    return org.apache.thrift.TBaseHelper.copyBinary(filterBytes);
  }

  public TGet setFilterBytes(byte[] filterBytes) {
    this.filterBytes = filterBytes == null ? (java.nio.ByteBuffer)null   : java.nio.ByteBuffer.wrap(filterBytes.clone());
    return this;
  }

  public TGet setFilterBytes(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer filterBytes) {
    this.filterBytes = org.apache.thrift.TBaseHelper.copyBinary(filterBytes);
    return this;
  }

  public void unsetFilterBytes() {
    this.filterBytes = null;
  }

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

  public void setFilterBytesIsSet(boolean value) {
    if (!value) {
      this.filterBytes = null;
    }
  }

  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case ROW:
      if (value == null) {
        unsetRow();
      } else {
        if (value instanceof byte[]) {
          setRow((byte[])value);
        } else {
          setRow((java.nio.ByteBuffer)value);
        }
      }
      break;

    case COLUMNS:
      if (value == null) {
        unsetColumns();
      } else {
        setColumns((java.util.List<TColumn>)value);
      }
      break;

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

    case TIME_RANGE:
      if (value == null) {
        unsetTimeRange();
      } else {
        setTimeRange((TTimeRange)value);
      }
      break;

    case MAX_VERSIONS:
      if (value == null) {
        unsetMaxVersions();
      } else {
        setMaxVersions((java.lang.Integer)value);
      }
      break;

    case FILTER_STRING:
      if (value == null) {
        unsetFilterString();
      } else {
        if (value instanceof byte[]) {
          setFilterString((byte[])value);
        } else {
          setFilterString((java.nio.ByteBuffer)value);
        }
      }
      break;

    case ATTRIBUTES:
      if (value == null) {
        unsetAttributes();
      } else {
        setAttributes((java.util.Map<java.nio.ByteBuffer,java.nio.ByteBuffer>)value);
      }
      break;

    case AUTHORIZATIONS:
      if (value == null) {
        unsetAuthorizations();
      } else {
        setAuthorizations((TAuthorization)value);
      }
      break;

    case CONSISTENCY:
      if (value == null) {
        unsetConsistency();
      } else {
        setConsistency((TConsistency)value);
      }
      break;

    case TARGET_REPLICA_ID:
      if (value == null) {
        unsetTargetReplicaId();
      } else {
        setTargetReplicaId((java.lang.Integer)value);
      }
      break;

    case CACHE_BLOCKS:
      if (value == null) {
        unsetCacheBlocks();
      } else {
        setCacheBlocks((java.lang.Boolean)value);
      }
      break;

    case STORE_LIMIT:
      if (value == null) {
        unsetStoreLimit();
      } else {
        setStoreLimit((java.lang.Integer)value);
      }
      break;

    case STORE_OFFSET:
      if (value == null) {
        unsetStoreOffset();
      } else {
        setStoreOffset((java.lang.Integer)value);
      }
      break;

    case EXISTENCE_ONLY:
      if (value == null) {
        unsetExistence_only();
      } else {
        setExistence_only((java.lang.Boolean)value);
      }
      break;

    case FILTER_BYTES:
      if (value == null) {
        unsetFilterBytes();
      } else {
        if (value instanceof byte[]) {
          setFilterBytes((byte[])value);
        } else {
          setFilterBytes((java.nio.ByteBuffer)value);
        }
      }
      break;

    }
  }

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

    case COLUMNS:
      return getColumns();

    case TIMESTAMP:
      return getTimestamp();

    case TIME_RANGE:
      return getTimeRange();

    case MAX_VERSIONS:
      return getMaxVersions();

    case FILTER_STRING:
      return getFilterString();

    case ATTRIBUTES:
      return getAttributes();

    case AUTHORIZATIONS:
      return getAuthorizations();

    case CONSISTENCY:
      return getConsistency();

    case TARGET_REPLICA_ID:
      return getTargetReplicaId();

    case CACHE_BLOCKS:
      return isCacheBlocks();

    case STORE_LIMIT:
      return getStoreLimit();

    case STORE_OFFSET:
      return getStoreOffset();

    case EXISTENCE_ONLY:
      return isExistence_only();

    case FILTER_BYTES:
      return getFilterBytes();

    }
    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 ROW:
      return isSetRow();
    case COLUMNS:
      return isSetColumns();
    case TIMESTAMP:
      return isSetTimestamp();
    case TIME_RANGE:
      return isSetTimeRange();
    case MAX_VERSIONS:
      return isSetMaxVersions();
    case FILTER_STRING:
      return isSetFilterString();
    case ATTRIBUTES:
      return isSetAttributes();
    case AUTHORIZATIONS:
      return isSetAuthorizations();
    case CONSISTENCY:
      return isSetConsistency();
    case TARGET_REPLICA_ID:
      return isSetTargetReplicaId();
    case CACHE_BLOCKS:
      return isSetCacheBlocks();
    case STORE_LIMIT:
      return isSetStoreLimit();
    case STORE_OFFSET:
      return isSetStoreOffset();
    case EXISTENCE_ONLY:
      return isSetExistence_only();
    case FILTER_BYTES:
      return isSetFilterBytes();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_row = true && this.isSetRow();
    boolean that_present_row = true && that.isSetRow();
    if (this_present_row || that_present_row) {
      if (!(this_present_row && that_present_row))
        return false;
      if (!this.row.equals(that.row))
        return false;
    }

    boolean this_present_columns = true && this.isSetColumns();
    boolean that_present_columns = true && that.isSetColumns();
    if (this_present_columns || that_present_columns) {
      if (!(this_present_columns && that_present_columns))
        return false;
      if (!this.columns.equals(that.columns))
        return false;
    }

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

    boolean this_present_timeRange = true && this.isSetTimeRange();
    boolean that_present_timeRange = true && that.isSetTimeRange();
    if (this_present_timeRange || that_present_timeRange) {
      if (!(this_present_timeRange && that_present_timeRange))
        return false;
      if (!this.timeRange.equals(that.timeRange))
        return false;
    }

    boolean this_present_maxVersions = true && this.isSetMaxVersions();
    boolean that_present_maxVersions = true && that.isSetMaxVersions();
    if (this_present_maxVersions || that_present_maxVersions) {
      if (!(this_present_maxVersions && that_present_maxVersions))
        return false;
      if (this.maxVersions != that.maxVersions)
        return false;
    }

    boolean this_present_filterString = true && this.isSetFilterString();
    boolean that_present_filterString = true && that.isSetFilterString();
    if (this_present_filterString || that_present_filterString) {
      if (!(this_present_filterString && that_present_filterString))
        return false;
      if (!this.filterString.equals(that.filterString))
        return false;
    }

    boolean this_present_attributes = true && this.isSetAttributes();
    boolean that_present_attributes = true && that.isSetAttributes();
    if (this_present_attributes || that_present_attributes) {
      if (!(this_present_attributes && that_present_attributes))
        return false;
      if (!this.attributes.equals(that.attributes))
        return false;
    }

    boolean this_present_authorizations = true && this.isSetAuthorizations();
    boolean that_present_authorizations = true && that.isSetAuthorizations();
    if (this_present_authorizations || that_present_authorizations) {
      if (!(this_present_authorizations && that_present_authorizations))
        return false;
      if (!this.authorizations.equals(that.authorizations))
        return false;
    }

    boolean this_present_consistency = true && this.isSetConsistency();
    boolean that_present_consistency = true && that.isSetConsistency();
    if (this_present_consistency || that_present_consistency) {
      if (!(this_present_consistency && that_present_consistency))
        return false;
      if (!this.consistency.equals(that.consistency))
        return false;
    }

    boolean this_present_targetReplicaId = true && this.isSetTargetReplicaId();
    boolean that_present_targetReplicaId = true && that.isSetTargetReplicaId();
    if (this_present_targetReplicaId || that_present_targetReplicaId) {
      if (!(this_present_targetReplicaId && that_present_targetReplicaId))
        return false;
      if (this.targetReplicaId != that.targetReplicaId)
        return false;
    }

    boolean this_present_cacheBlocks = true && this.isSetCacheBlocks();
    boolean that_present_cacheBlocks = true && that.isSetCacheBlocks();
    if (this_present_cacheBlocks || that_present_cacheBlocks) {
      if (!(this_present_cacheBlocks && that_present_cacheBlocks))
        return false;
      if (this.cacheBlocks != that.cacheBlocks)
        return false;
    }

    boolean this_present_storeLimit = true && this.isSetStoreLimit();
    boolean that_present_storeLimit = true && that.isSetStoreLimit();
    if (this_present_storeLimit || that_present_storeLimit) {
      if (!(this_present_storeLimit && that_present_storeLimit))
        return false;
      if (this.storeLimit != that.storeLimit)
        return false;
    }

    boolean this_present_storeOffset = true && this.isSetStoreOffset();
    boolean that_present_storeOffset = true && that.isSetStoreOffset();
    if (this_present_storeOffset || that_present_storeOffset) {
      if (!(this_present_storeOffset && that_present_storeOffset))
        return false;
      if (this.storeOffset != that.storeOffset)
        return false;
    }

    boolean this_present_existence_only = true && this.isSetExistence_only();
    boolean that_present_existence_only = true && that.isSetExistence_only();
    if (this_present_existence_only || that_present_existence_only) {
      if (!(this_present_existence_only && that_present_existence_only))
        return false;
      if (this.existence_only != that.existence_only)
        return false;
    }

    boolean this_present_filterBytes = true && this.isSetFilterBytes();
    boolean that_present_filterBytes = true && that.isSetFilterBytes();
    if (this_present_filterBytes || that_present_filterBytes) {
      if (!(this_present_filterBytes && that_present_filterBytes))
        return false;
      if (!this.filterBytes.equals(that.filterBytes))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((isSetRow()) ? 131071 : 524287);
    if (isSetRow())
      hashCode = hashCode * 8191 + row.hashCode();

    hashCode = hashCode * 8191 + ((isSetColumns()) ? 131071 : 524287);
    if (isSetColumns())
      hashCode = hashCode * 8191 + columns.hashCode();

    hashCode = hashCode * 8191 + ((isSetTimestamp()) ? 131071 : 524287);
    if (isSetTimestamp())
      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(timestamp);

    hashCode = hashCode * 8191 + ((isSetTimeRange()) ? 131071 : 524287);
    if (isSetTimeRange())
      hashCode = hashCode * 8191 + timeRange.hashCode();

    hashCode = hashCode * 8191 + ((isSetMaxVersions()) ? 131071 : 524287);
    if (isSetMaxVersions())
      hashCode = hashCode * 8191 + maxVersions;

    hashCode = hashCode * 8191 + ((isSetFilterString()) ? 131071 : 524287);
    if (isSetFilterString())
      hashCode = hashCode * 8191 + filterString.hashCode();

    hashCode = hashCode * 8191 + ((isSetAttributes()) ? 131071 : 524287);
    if (isSetAttributes())
      hashCode = hashCode * 8191 + attributes.hashCode();

    hashCode = hashCode * 8191 + ((isSetAuthorizations()) ? 131071 : 524287);
    if (isSetAuthorizations())
      hashCode = hashCode * 8191 + authorizations.hashCode();

    hashCode = hashCode * 8191 + ((isSetConsistency()) ? 131071 : 524287);
    if (isSetConsistency())
      hashCode = hashCode * 8191 + consistency.getValue();

    hashCode = hashCode * 8191 + ((isSetTargetReplicaId()) ? 131071 : 524287);
    if (isSetTargetReplicaId())
      hashCode = hashCode * 8191 + targetReplicaId;

    hashCode = hashCode * 8191 + ((isSetCacheBlocks()) ? 131071 : 524287);
    if (isSetCacheBlocks())
      hashCode = hashCode * 8191 + ((cacheBlocks) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((isSetStoreLimit()) ? 131071 : 524287);
    if (isSetStoreLimit())
      hashCode = hashCode * 8191 + storeLimit;

    hashCode = hashCode * 8191 + ((isSetStoreOffset()) ? 131071 : 524287);
    if (isSetStoreOffset())
      hashCode = hashCode * 8191 + storeOffset;

    hashCode = hashCode * 8191 + ((isSetExistence_only()) ? 131071 : 524287);
    if (isSetExistence_only())
      hashCode = hashCode * 8191 + ((existence_only) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((isSetFilterBytes()) ? 131071 : 524287);
    if (isSetFilterBytes())
      hashCode = hashCode * 8191 + filterBytes.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.compare(isSetRow(), other.isSetRow());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetRow()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.row, other.row);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetColumns(), other.isSetColumns());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetColumns()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.columns, other.columns);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetTimestamp(), other.isSetTimestamp());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTimestamp()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.timestamp, other.timestamp);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetTimeRange(), other.isSetTimeRange());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTimeRange()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.timeRange, other.timeRange);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetMaxVersions(), other.isSetMaxVersions());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetMaxVersions()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.maxVersions, other.maxVersions);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetFilterString(), other.isSetFilterString());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetFilterString()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.filterString, other.filterString);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetAttributes(), other.isSetAttributes());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAttributes()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.attributes, other.attributes);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetAuthorizations(), other.isSetAuthorizations());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAuthorizations()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authorizations, other.authorizations);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetConsistency(), other.isSetConsistency());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetConsistency()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency, other.consistency);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetTargetReplicaId(), other.isSetTargetReplicaId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTargetReplicaId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.targetReplicaId, other.targetReplicaId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetCacheBlocks(), other.isSetCacheBlocks());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCacheBlocks()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cacheBlocks, other.cacheBlocks);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetStoreLimit(), other.isSetStoreLimit());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStoreLimit()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storeLimit, other.storeLimit);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetStoreOffset(), other.isSetStoreOffset());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStoreOffset()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storeOffset, other.storeOffset);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetExistence_only(), other.isSetExistence_only());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetExistence_only()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.existence_only, other.existence_only);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetFilterBytes(), other.isSetFilterBytes());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetFilterBytes()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.filterBytes, other.filterBytes);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  @org.apache.thrift.annotation.Nullable
  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    scheme(iprot).read(iprot, this);
  }

  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    scheme(oprot).write(oprot, this);
  }

  @Override
  public java.lang.String toString() {
    java.lang.StringBuilder sb = new java.lang.StringBuilder("TGet(");
    boolean first = true;

    sb.append("row:");
    if (this.row == null) {
      sb.append("null");
    } else {
      org.apache.thrift.TBaseHelper.toString(this.row, sb);
    }
    first = false;
    if (isSetColumns()) {
      if (!first) sb.append(", ");
      sb.append("columns:");
      if (this.columns == null) {
        sb.append("null");
      } else {
        sb.append(this.columns);
      }
      first = false;
    }
    if (isSetTimestamp()) {
      if (!first) sb.append(", ");
      sb.append("timestamp:");
      sb.append(this.timestamp);
      first = false;
    }
    if (isSetTimeRange()) {
      if (!first) sb.append(", ");
      sb.append("timeRange:");
      if (this.timeRange == null) {
        sb.append("null");
      } else {
        sb.append(this.timeRange);
      }
      first = false;
    }
    if (isSetMaxVersions()) {
      if (!first) sb.append(", ");
      sb.append("maxVersions:");
      sb.append(this.maxVersions);
      first = false;
    }
    if (isSetFilterString()) {
      if (!first) sb.append(", ");
      sb.append("filterString:");
      if (this.filterString == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.filterString, sb);
      }
      first = false;
    }
    if (isSetAttributes()) {
      if (!first) sb.append(", ");
      sb.append("attributes:");
      if (this.attributes == null) {
        sb.append("null");
      } else {
        sb.append(this.attributes);
      }
      first = false;
    }
    if (isSetAuthorizations()) {
      if (!first) sb.append(", ");
      sb.append("authorizations:");
      if (this.authorizations == null) {
        sb.append("null");
      } else {
        sb.append(this.authorizations);
      }
      first = false;
    }
    if (isSetConsistency()) {
      if (!first) sb.append(", ");
      sb.append("consistency:");
      if (this.consistency == null) {
        sb.append("null");
      } else {
        sb.append(this.consistency);
      }
      first = false;
    }
    if (isSetTargetReplicaId()) {
      if (!first) sb.append(", ");
      sb.append("targetReplicaId:");
      sb.append(this.targetReplicaId);
      first = false;
    }
    if (isSetCacheBlocks()) {
      if (!first) sb.append(", ");
      sb.append("cacheBlocks:");
      sb.append(this.cacheBlocks);
      first = false;
    }
    if (isSetStoreLimit()) {
      if (!first) sb.append(", ");
      sb.append("storeLimit:");
      sb.append(this.storeLimit);
      first = false;
    }
    if (isSetStoreOffset()) {
      if (!first) sb.append(", ");
      sb.append("storeOffset:");
      sb.append(this.storeOffset);
      first = false;
    }
    if (isSetExistence_only()) {
      if (!first) sb.append(", ");
      sb.append("existence_only:");
      sb.append(this.existence_only);
      first = false;
    }
    if (isSetFilterBytes()) {
      if (!first) sb.append(", ");
      sb.append("filterBytes:");
      if (this.filterBytes == null) {
        sb.append("null");
      } else {
        org.apache.thrift.TBaseHelper.toString(this.filterBytes, sb);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    if (row == null) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'row' was not present! Struct: " + toString());
    }
    // check for sub-struct validity
    if (timeRange != null) {
      timeRange.validate();
    }
    if (authorizations != null) {
      authorizations.validate();
    }
  }

  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    try {
      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.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.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class TGetStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public TGetStandardScheme getScheme() {
      return new TGetStandardScheme();
    }
  }

  private static class TGetStandardScheme extends org.apache.thrift.scheme.StandardScheme<TGet> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, TGet struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // ROW
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.row = iprot.readBinary();
              struct.setRowIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // COLUMNS
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list16 = iprot.readListBegin();
                struct.columns = new java.util.ArrayList<TColumn>(_list16.size);
                @org.apache.thrift.annotation.Nullable TColumn _elem17;
                for (int _i18 = 0; _i18 < _list16.size; ++_i18)
                {
                  _elem17 = new TColumn();
                  _elem17.read(iprot);
                  struct.columns.add(_elem17);
                }
                iprot.readListEnd();
              }
              struct.setColumnsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // TIMESTAMP
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.timestamp = iprot.readI64();
              struct.setTimestampIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // TIME_RANGE
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.timeRange = new TTimeRange();
              struct.timeRange.read(iprot);
              struct.setTimeRangeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // MAX_VERSIONS
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.maxVersions = iprot.readI32();
              struct.setMaxVersionsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // FILTER_STRING
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.filterString = iprot.readBinary();
              struct.setFilterStringIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // ATTRIBUTES
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map19 = iprot.readMapBegin();
                struct.attributes = new java.util.HashMap<java.nio.ByteBuffer,java.nio.ByteBuffer>(2*_map19.size);
                @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer _key20;
                @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer _val21;
                for (int _i22 = 0; _i22 < _map19.size; ++_i22)
                {
                  _key20 = iprot.readBinary();
                  _val21 = iprot.readBinary();
                  struct.attributes.put(_key20, _val21);
                }
                iprot.readMapEnd();
              }
              struct.setAttributesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // AUTHORIZATIONS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.authorizations = new TAuthorization();
              struct.authorizations.read(iprot);
              struct.setAuthorizationsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // CONSISTENCY
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.consistency = org.apache.hadoop.hbase.thrift2.generated.TConsistency.findByValue(iprot.readI32());
              struct.setConsistencyIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // TARGET_REPLICA_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.targetReplicaId = iprot.readI32();
              struct.setTargetReplicaIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // CACHE_BLOCKS
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.cacheBlocks = iprot.readBool();
              struct.setCacheBlocksIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // STORE_LIMIT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.storeLimit = iprot.readI32();
              struct.setStoreLimitIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 13: // STORE_OFFSET
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.storeOffset = iprot.readI32();
              struct.setStoreOffsetIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 14: // EXISTENCE_ONLY
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.existence_only = iprot.readBool();
              struct.setExistence_onlyIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 15: // FILTER_BYTES
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.filterBytes = iprot.readBinary();
              struct.setFilterBytesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();

      // check for required fields of primitive type, which can't be checked in the validate method
      struct.validate();
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot, TGet struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.row != null) {
        oprot.writeFieldBegin(ROW_FIELD_DESC);
        oprot.writeBinary(struct.row);
        oprot.writeFieldEnd();
      }
      if (struct.columns != null) {
        if (struct.isSetColumns()) {
          oprot.writeFieldBegin(COLUMNS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.columns.size()));
            for (TColumn _iter23 : struct.columns)
            {
              _iter23.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetTimestamp()) {
        oprot.writeFieldBegin(TIMESTAMP_FIELD_DESC);
        oprot.writeI64(struct.timestamp);
        oprot.writeFieldEnd();
      }
      if (struct.timeRange != null) {
        if (struct.isSetTimeRange()) {
          oprot.writeFieldBegin(TIME_RANGE_FIELD_DESC);
          struct.timeRange.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetMaxVersions()) {
        oprot.writeFieldBegin(MAX_VERSIONS_FIELD_DESC);
        oprot.writeI32(struct.maxVersions);
        oprot.writeFieldEnd();
      }
      if (struct.filterString != null) {
        if (struct.isSetFilterString()) {
          oprot.writeFieldBegin(FILTER_STRING_FIELD_DESC);
          oprot.writeBinary(struct.filterString);
          oprot.writeFieldEnd();
        }
      }
      if (struct.attributes != null) {
        if (struct.isSetAttributes()) {
          oprot.writeFieldBegin(ATTRIBUTES_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.attributes.size()));
            for (java.util.Map.Entry<java.nio.ByteBuffer, java.nio.ByteBuffer> _iter24 : struct.attributes.entrySet())
            {
              oprot.writeBinary(_iter24.getKey());
              oprot.writeBinary(_iter24.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.authorizations != null) {
        if (struct.isSetAuthorizations()) {
          oprot.writeFieldBegin(AUTHORIZATIONS_FIELD_DESC);
          struct.authorizations.write(oprot);
          oprot.writeFieldEnd();
        }
      }
      if (struct.consistency != null) {
        if (struct.isSetConsistency()) {
          oprot.writeFieldBegin(CONSISTENCY_FIELD_DESC);
          oprot.writeI32(struct.consistency.getValue());
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetTargetReplicaId()) {
        oprot.writeFieldBegin(TARGET_REPLICA_ID_FIELD_DESC);
        oprot.writeI32(struct.targetReplicaId);
        oprot.writeFieldEnd();
      }
      if (struct.isSetCacheBlocks()) {
        oprot.writeFieldBegin(CACHE_BLOCKS_FIELD_DESC);
        oprot.writeBool(struct.cacheBlocks);
        oprot.writeFieldEnd();
      }
      if (struct.isSetStoreLimit()) {
        oprot.writeFieldBegin(STORE_LIMIT_FIELD_DESC);
        oprot.writeI32(struct.storeLimit);
        oprot.writeFieldEnd();
      }
      if (struct.isSetStoreOffset()) {
        oprot.writeFieldBegin(STORE_OFFSET_FIELD_DESC);
        oprot.writeI32(struct.storeOffset);
        oprot.writeFieldEnd();
      }
      if (struct.isSetExistence_only()) {
        oprot.writeFieldBegin(EXISTENCE_ONLY_FIELD_DESC);
        oprot.writeBool(struct.existence_only);
        oprot.writeFieldEnd();
      }
      if (struct.filterBytes != null) {
        if (struct.isSetFilterBytes()) {
          oprot.writeFieldBegin(FILTER_BYTES_FIELD_DESC);
          oprot.writeBinary(struct.filterBytes);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class TGetTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public TGetTupleScheme getScheme() {
      return new TGetTupleScheme();
    }
  }

  private static class TGetTupleScheme extends org.apache.thrift.scheme.TupleScheme<TGet> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, TGet struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeBinary(struct.row);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetColumns()) {
        optionals.set(0);
      }
      if (struct.isSetTimestamp()) {
        optionals.set(1);
      }
      if (struct.isSetTimeRange()) {
        optionals.set(2);
      }
      if (struct.isSetMaxVersions()) {
        optionals.set(3);
      }
      if (struct.isSetFilterString()) {
        optionals.set(4);
      }
      if (struct.isSetAttributes()) {
        optionals.set(5);
      }
      if (struct.isSetAuthorizations()) {
        optionals.set(6);
      }
      if (struct.isSetConsistency()) {
        optionals.set(7);
      }
      if (struct.isSetTargetReplicaId()) {
        optionals.set(8);
      }
      if (struct.isSetCacheBlocks()) {
        optionals.set(9);
      }
      if (struct.isSetStoreLimit()) {
        optionals.set(10);
      }
      if (struct.isSetStoreOffset()) {
        optionals.set(11);
      }
      if (struct.isSetExistence_only()) {
        optionals.set(12);
      }
      if (struct.isSetFilterBytes()) {
        optionals.set(13);
      }
      oprot.writeBitSet(optionals, 14);
      if (struct.isSetColumns()) {
        {
          oprot.writeI32(struct.columns.size());
          for (TColumn _iter25 : struct.columns)
          {
            _iter25.write(oprot);
          }
        }
      }
      if (struct.isSetTimestamp()) {
        oprot.writeI64(struct.timestamp);
      }
      if (struct.isSetTimeRange()) {
        struct.timeRange.write(oprot);
      }
      if (struct.isSetMaxVersions()) {
        oprot.writeI32(struct.maxVersions);
      }
      if (struct.isSetFilterString()) {
        oprot.writeBinary(struct.filterString);
      }
      if (struct.isSetAttributes()) {
        {
          oprot.writeI32(struct.attributes.size());
          for (java.util.Map.Entry<java.nio.ByteBuffer, java.nio.ByteBuffer> _iter26 : struct.attributes.entrySet())
          {
            oprot.writeBinary(_iter26.getKey());
            oprot.writeBinary(_iter26.getValue());
          }
        }
      }
      if (struct.isSetAuthorizations()) {
        struct.authorizations.write(oprot);
      }
      if (struct.isSetConsistency()) {
        oprot.writeI32(struct.consistency.getValue());
      }
      if (struct.isSetTargetReplicaId()) {
        oprot.writeI32(struct.targetReplicaId);
      }
      if (struct.isSetCacheBlocks()) {
        oprot.writeBool(struct.cacheBlocks);
      }
      if (struct.isSetStoreLimit()) {
        oprot.writeI32(struct.storeLimit);
      }
      if (struct.isSetStoreOffset()) {
        oprot.writeI32(struct.storeOffset);
      }
      if (struct.isSetExistence_only()) {
        oprot.writeBool(struct.existence_only);
      }
      if (struct.isSetFilterBytes()) {
        oprot.writeBinary(struct.filterBytes);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, TGet struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.row = iprot.readBinary();
      struct.setRowIsSet(true);
      java.util.BitSet incoming = iprot.readBitSet(14);
      if (incoming.get(0)) {
        {
          org.apache.thrift.protocol.TList _list27 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
          struct.columns = new java.util.ArrayList<TColumn>(_list27.size);
          @org.apache.thrift.annotation.Nullable TColumn _elem28;
          for (int _i29 = 0; _i29 < _list27.size; ++_i29)
          {
            _elem28 = new TColumn();
            _elem28.read(iprot);
            struct.columns.add(_elem28);
          }
        }
        struct.setColumnsIsSet(true);
      }
      if (incoming.get(1)) {
        struct.timestamp = iprot.readI64();
        struct.setTimestampIsSet(true);
      }
      if (incoming.get(2)) {
        struct.timeRange = new TTimeRange();
        struct.timeRange.read(iprot);
        struct.setTimeRangeIsSet(true);
      }
      if (incoming.get(3)) {
        struct.maxVersions = iprot.readI32();
        struct.setMaxVersionsIsSet(true);
      }
      if (incoming.get(4)) {
        struct.filterString = iprot.readBinary();
        struct.setFilterStringIsSet(true);
      }
      if (incoming.get(5)) {
        {
          org.apache.thrift.protocol.TMap _map30 = iprot.readMapBegin(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING); 
          struct.attributes = new java.util.HashMap<java.nio.ByteBuffer,java.nio.ByteBuffer>(2*_map30.size);
          @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer _key31;
          @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer _val32;
          for (int _i33 = 0; _i33 < _map30.size; ++_i33)
          {
            _key31 = iprot.readBinary();
            _val32 = iprot.readBinary();
            struct.attributes.put(_key31, _val32);
          }
        }
        struct.setAttributesIsSet(true);
      }
      if (incoming.get(6)) {
        struct.authorizations = new TAuthorization();
        struct.authorizations.read(iprot);
        struct.setAuthorizationsIsSet(true);
      }
      if (incoming.get(7)) {
        struct.consistency = org.apache.hadoop.hbase.thrift2.generated.TConsistency.findByValue(iprot.readI32());
        struct.setConsistencyIsSet(true);
      }
      if (incoming.get(8)) {
        struct.targetReplicaId = iprot.readI32();
        struct.setTargetReplicaIdIsSet(true);
      }
      if (incoming.get(9)) {
        struct.cacheBlocks = iprot.readBool();
        struct.setCacheBlocksIsSet(true);
      }
      if (incoming.get(10)) {
        struct.storeLimit = iprot.readI32();
        struct.setStoreLimitIsSet(true);
      }
      if (incoming.get(11)) {
        struct.storeOffset = iprot.readI32();
        struct.setStoreOffsetIsSet(true);
      }
      if (incoming.get(12)) {
        struct.existence_only = iprot.readBool();
        struct.setExistence_onlyIsSet(true);
      }
      if (incoming.get(13)) {
        struct.filterBytes = iprot.readBinary();
        struct.setFilterBytesIsSet(true);
      }
    }
  }

  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
  }
}

