/**
 * Autogenerated by Thrift Compiler (0.9.3)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.distributedlog.thrift;

import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.AbstractNonblockingServer.*;
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.nio.ByteBuffer;
import java.util.Arrays;
import javax.annotation.Generated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = "2017-05-27")
public class BKDLConfigFormat implements org.apache.thrift.TBase<BKDLConfigFormat, BKDLConfigFormat._Fields>, java.io.Serializable, Cloneable, Comparable<BKDLConfigFormat> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("BKDLConfigFormat");

  private static final org.apache.thrift.protocol.TField BK_ZK_SERVERS_FIELD_DESC = new org.apache.thrift.protocol.TField("bkZkServers", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField BK_LEDGERS_PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("bkLedgersPath", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField SANITY_CHECK_TXN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("sanityCheckTxnID", org.apache.thrift.protocol.TType.BOOL, (short)3);
  private static final org.apache.thrift.protocol.TField ENCODE_REGION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("encodeRegionID", org.apache.thrift.protocol.TType.BOOL, (short)4);
  private static final org.apache.thrift.protocol.TField BK_ZK_SERVERS_FOR_READER_FIELD_DESC = new org.apache.thrift.protocol.TField("bkZkServersForReader", org.apache.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.thrift.protocol.TField DL_ZK_SERVERS_FOR_WRITER_FIELD_DESC = new org.apache.thrift.protocol.TField("dlZkServersForWriter", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField DL_ZK_SERVERS_FOR_READER_FIELD_DESC = new org.apache.thrift.protocol.TField("dlZkServersForReader", org.apache.thrift.protocol.TType.STRING, (short)7);
  private static final org.apache.thrift.protocol.TField ACL_ROOT_PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("aclRootPath", org.apache.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.thrift.protocol.TField FIRST_LOG_SEGMENT_SEQ_NO_FIELD_DESC = new org.apache.thrift.protocol.TField("firstLogSegmentSeqNo", org.apache.thrift.protocol.TType.I64, (short)9);
  private static final org.apache.thrift.protocol.TField FEDERATED_NAMESPACE_FIELD_DESC = new org.apache.thrift.protocol.TField("federatedNamespace", org.apache.thrift.protocol.TType.BOOL, (short)10);

  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
  static {
    schemes.put(StandardScheme.class, new BKDLConfigFormatStandardSchemeFactory());
    schemes.put(TupleScheme.class, new BKDLConfigFormatTupleSchemeFactory());
  }

  public String bkZkServers; // optional
  public String bkLedgersPath; // optional
  public boolean sanityCheckTxnID; // optional
  public boolean encodeRegionID; // optional
  public String bkZkServersForReader; // optional
  public String dlZkServersForWriter; // optional
  public String dlZkServersForReader; // optional
  public String aclRootPath; // optional
  public long firstLogSegmentSeqNo; // optional
  public boolean federatedNamespace; // 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 {
    BK_ZK_SERVERS((short)1, "bkZkServers"),
    BK_LEDGERS_PATH((short)2, "bkLedgersPath"),
    SANITY_CHECK_TXN_ID((short)3, "sanityCheckTxnID"),
    ENCODE_REGION_ID((short)4, "encodeRegionID"),
    BK_ZK_SERVERS_FOR_READER((short)5, "bkZkServersForReader"),
    DL_ZK_SERVERS_FOR_WRITER((short)6, "dlZkServersForWriter"),
    DL_ZK_SERVERS_FOR_READER((short)7, "dlZkServersForReader"),
    ACL_ROOT_PATH((short)8, "aclRootPath"),
    FIRST_LOG_SEGMENT_SEQ_NO((short)9, "firstLogSegmentSeqNo"),
    FEDERATED_NAMESPACE((short)10, "federatedNamespace");

    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: // BK_ZK_SERVERS
          return BK_ZK_SERVERS;
        case 2: // BK_LEDGERS_PATH
          return BK_LEDGERS_PATH;
        case 3: // SANITY_CHECK_TXN_ID
          return SANITY_CHECK_TXN_ID;
        case 4: // ENCODE_REGION_ID
          return ENCODE_REGION_ID;
        case 5: // BK_ZK_SERVERS_FOR_READER
          return BK_ZK_SERVERS_FOR_READER;
        case 6: // DL_ZK_SERVERS_FOR_WRITER
          return DL_ZK_SERVERS_FOR_WRITER;
        case 7: // DL_ZK_SERVERS_FOR_READER
          return DL_ZK_SERVERS_FOR_READER;
        case 8: // ACL_ROOT_PATH
          return ACL_ROOT_PATH;
        case 9: // FIRST_LOG_SEGMENT_SEQ_NO
          return FIRST_LOG_SEGMENT_SEQ_NO;
        case 10: // FEDERATED_NAMESPACE
          return FEDERATED_NAMESPACE;
        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 __SANITYCHECKTXNID_ISSET_ID = 0;
  private static final int __ENCODEREGIONID_ISSET_ID = 1;
  private static final int __FIRSTLOGSEGMENTSEQNO_ISSET_ID = 2;
  private static final int __FEDERATEDNAMESPACE_ISSET_ID = 3;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.BK_ZK_SERVERS,_Fields.BK_LEDGERS_PATH,_Fields.SANITY_CHECK_TXN_ID,_Fields.ENCODE_REGION_ID,_Fields.BK_ZK_SERVERS_FOR_READER,_Fields.DL_ZK_SERVERS_FOR_WRITER,_Fields.DL_ZK_SERVERS_FOR_READER,_Fields.ACL_ROOT_PATH,_Fields.FIRST_LOG_SEGMENT_SEQ_NO,_Fields.FEDERATED_NAMESPACE};
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.BK_ZK_SERVERS, new org.apache.thrift.meta_data.FieldMetaData("bkZkServers", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.BK_LEDGERS_PATH, new org.apache.thrift.meta_data.FieldMetaData("bkLedgersPath", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.SANITY_CHECK_TXN_ID, new org.apache.thrift.meta_data.FieldMetaData("sanityCheckTxnID", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.ENCODE_REGION_ID, new org.apache.thrift.meta_data.FieldMetaData("encodeRegionID", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.BK_ZK_SERVERS_FOR_READER, new org.apache.thrift.meta_data.FieldMetaData("bkZkServersForReader", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.DL_ZK_SERVERS_FOR_WRITER, new org.apache.thrift.meta_data.FieldMetaData("dlZkServersForWriter", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.DL_ZK_SERVERS_FOR_READER, new org.apache.thrift.meta_data.FieldMetaData("dlZkServersForReader", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.ACL_ROOT_PATH, new org.apache.thrift.meta_data.FieldMetaData("aclRootPath", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.FIRST_LOG_SEGMENT_SEQ_NO, new org.apache.thrift.meta_data.FieldMetaData("firstLogSegmentSeqNo", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.FEDERATED_NAMESPACE, new org.apache.thrift.meta_data.FieldMetaData("federatedNamespace", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(BKDLConfigFormat.class, metaDataMap);
  }

  public BKDLConfigFormat() {
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public BKDLConfigFormat(BKDLConfigFormat other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetBkZkServers()) {
      this.bkZkServers = other.bkZkServers;
    }
    if (other.isSetBkLedgersPath()) {
      this.bkLedgersPath = other.bkLedgersPath;
    }
    this.sanityCheckTxnID = other.sanityCheckTxnID;
    this.encodeRegionID = other.encodeRegionID;
    if (other.isSetBkZkServersForReader()) {
      this.bkZkServersForReader = other.bkZkServersForReader;
    }
    if (other.isSetDlZkServersForWriter()) {
      this.dlZkServersForWriter = other.dlZkServersForWriter;
    }
    if (other.isSetDlZkServersForReader()) {
      this.dlZkServersForReader = other.dlZkServersForReader;
    }
    if (other.isSetAclRootPath()) {
      this.aclRootPath = other.aclRootPath;
    }
    this.firstLogSegmentSeqNo = other.firstLogSegmentSeqNo;
    this.federatedNamespace = other.federatedNamespace;
  }

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

  @Override
  public void clear() {
    this.bkZkServers = null;
    this.bkLedgersPath = null;
    setSanityCheckTxnIDIsSet(false);
    this.sanityCheckTxnID = false;
    setEncodeRegionIDIsSet(false);
    this.encodeRegionID = false;
    this.bkZkServersForReader = null;
    this.dlZkServersForWriter = null;
    this.dlZkServersForReader = null;
    this.aclRootPath = null;
    setFirstLogSegmentSeqNoIsSet(false);
    this.firstLogSegmentSeqNo = 0;
    setFederatedNamespaceIsSet(false);
    this.federatedNamespace = false;
  }

  public String getBkZkServers() {
    return this.bkZkServers;
  }

  public BKDLConfigFormat setBkZkServers(String bkZkServers) {
    this.bkZkServers = bkZkServers;
    return this;
  }

  public void unsetBkZkServers() {
    this.bkZkServers = null;
  }

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

  public void setBkZkServersIsSet(boolean value) {
    if (!value) {
      this.bkZkServers = null;
    }
  }

  public String getBkLedgersPath() {
    return this.bkLedgersPath;
  }

  public BKDLConfigFormat setBkLedgersPath(String bkLedgersPath) {
    this.bkLedgersPath = bkLedgersPath;
    return this;
  }

  public void unsetBkLedgersPath() {
    this.bkLedgersPath = null;
  }

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

  public void setBkLedgersPathIsSet(boolean value) {
    if (!value) {
      this.bkLedgersPath = null;
    }
  }

  public boolean isSanityCheckTxnID() {
    return this.sanityCheckTxnID;
  }

  public BKDLConfigFormat setSanityCheckTxnID(boolean sanityCheckTxnID) {
    this.sanityCheckTxnID = sanityCheckTxnID;
    setSanityCheckTxnIDIsSet(true);
    return this;
  }

  public void unsetSanityCheckTxnID() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SANITYCHECKTXNID_ISSET_ID);
  }

  /** Returns true if field sanityCheckTxnID is set (has been assigned a value) and false otherwise */
  public boolean isSetSanityCheckTxnID() {
    return EncodingUtils.testBit(__isset_bitfield, __SANITYCHECKTXNID_ISSET_ID);
  }

  public void setSanityCheckTxnIDIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SANITYCHECKTXNID_ISSET_ID, value);
  }

  public boolean isEncodeRegionID() {
    return this.encodeRegionID;
  }

  public BKDLConfigFormat setEncodeRegionID(boolean encodeRegionID) {
    this.encodeRegionID = encodeRegionID;
    setEncodeRegionIDIsSet(true);
    return this;
  }

  public void unsetEncodeRegionID() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ENCODEREGIONID_ISSET_ID);
  }

  /** Returns true if field encodeRegionID is set (has been assigned a value) and false otherwise */
  public boolean isSetEncodeRegionID() {
    return EncodingUtils.testBit(__isset_bitfield, __ENCODEREGIONID_ISSET_ID);
  }

  public void setEncodeRegionIDIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ENCODEREGIONID_ISSET_ID, value);
  }

  public String getBkZkServersForReader() {
    return this.bkZkServersForReader;
  }

  public BKDLConfigFormat setBkZkServersForReader(String bkZkServersForReader) {
    this.bkZkServersForReader = bkZkServersForReader;
    return this;
  }

  public void unsetBkZkServersForReader() {
    this.bkZkServersForReader = null;
  }

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

  public void setBkZkServersForReaderIsSet(boolean value) {
    if (!value) {
      this.bkZkServersForReader = null;
    }
  }

  public String getDlZkServersForWriter() {
    return this.dlZkServersForWriter;
  }

  public BKDLConfigFormat setDlZkServersForWriter(String dlZkServersForWriter) {
    this.dlZkServersForWriter = dlZkServersForWriter;
    return this;
  }

  public void unsetDlZkServersForWriter() {
    this.dlZkServersForWriter = null;
  }

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

  public void setDlZkServersForWriterIsSet(boolean value) {
    if (!value) {
      this.dlZkServersForWriter = null;
    }
  }

  public String getDlZkServersForReader() {
    return this.dlZkServersForReader;
  }

  public BKDLConfigFormat setDlZkServersForReader(String dlZkServersForReader) {
    this.dlZkServersForReader = dlZkServersForReader;
    return this;
  }

  public void unsetDlZkServersForReader() {
    this.dlZkServersForReader = null;
  }

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

  public void setDlZkServersForReaderIsSet(boolean value) {
    if (!value) {
      this.dlZkServersForReader = null;
    }
  }

  public String getAclRootPath() {
    return this.aclRootPath;
  }

  public BKDLConfigFormat setAclRootPath(String aclRootPath) {
    this.aclRootPath = aclRootPath;
    return this;
  }

  public void unsetAclRootPath() {
    this.aclRootPath = null;
  }

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

  public void setAclRootPathIsSet(boolean value) {
    if (!value) {
      this.aclRootPath = null;
    }
  }

  public long getFirstLogSegmentSeqNo() {
    return this.firstLogSegmentSeqNo;
  }

  public BKDLConfigFormat setFirstLogSegmentSeqNo(long firstLogSegmentSeqNo) {
    this.firstLogSegmentSeqNo = firstLogSegmentSeqNo;
    setFirstLogSegmentSeqNoIsSet(true);
    return this;
  }

  public void unsetFirstLogSegmentSeqNo() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __FIRSTLOGSEGMENTSEQNO_ISSET_ID);
  }

  /** Returns true if field firstLogSegmentSeqNo is set (has been assigned a value) and false otherwise */
  public boolean isSetFirstLogSegmentSeqNo() {
    return EncodingUtils.testBit(__isset_bitfield, __FIRSTLOGSEGMENTSEQNO_ISSET_ID);
  }

  public void setFirstLogSegmentSeqNoIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __FIRSTLOGSEGMENTSEQNO_ISSET_ID, value);
  }

  public boolean isFederatedNamespace() {
    return this.federatedNamespace;
  }

  public BKDLConfigFormat setFederatedNamespace(boolean federatedNamespace) {
    this.federatedNamespace = federatedNamespace;
    setFederatedNamespaceIsSet(true);
    return this;
  }

  public void unsetFederatedNamespace() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __FEDERATEDNAMESPACE_ISSET_ID);
  }

  /** Returns true if field federatedNamespace is set (has been assigned a value) and false otherwise */
  public boolean isSetFederatedNamespace() {
    return EncodingUtils.testBit(__isset_bitfield, __FEDERATEDNAMESPACE_ISSET_ID);
  }

  public void setFederatedNamespaceIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __FEDERATEDNAMESPACE_ISSET_ID, value);
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case BK_ZK_SERVERS:
      if (value == null) {
        unsetBkZkServers();
      } else {
        setBkZkServers((String)value);
      }
      break;

    case BK_LEDGERS_PATH:
      if (value == null) {
        unsetBkLedgersPath();
      } else {
        setBkLedgersPath((String)value);
      }
      break;

    case SANITY_CHECK_TXN_ID:
      if (value == null) {
        unsetSanityCheckTxnID();
      } else {
        setSanityCheckTxnID((Boolean)value);
      }
      break;

    case ENCODE_REGION_ID:
      if (value == null) {
        unsetEncodeRegionID();
      } else {
        setEncodeRegionID((Boolean)value);
      }
      break;

    case BK_ZK_SERVERS_FOR_READER:
      if (value == null) {
        unsetBkZkServersForReader();
      } else {
        setBkZkServersForReader((String)value);
      }
      break;

    case DL_ZK_SERVERS_FOR_WRITER:
      if (value == null) {
        unsetDlZkServersForWriter();
      } else {
        setDlZkServersForWriter((String)value);
      }
      break;

    case DL_ZK_SERVERS_FOR_READER:
      if (value == null) {
        unsetDlZkServersForReader();
      } else {
        setDlZkServersForReader((String)value);
      }
      break;

    case ACL_ROOT_PATH:
      if (value == null) {
        unsetAclRootPath();
      } else {
        setAclRootPath((String)value);
      }
      break;

    case FIRST_LOG_SEGMENT_SEQ_NO:
      if (value == null) {
        unsetFirstLogSegmentSeqNo();
      } else {
        setFirstLogSegmentSeqNo((Long)value);
      }
      break;

    case FEDERATED_NAMESPACE:
      if (value == null) {
        unsetFederatedNamespace();
      } else {
        setFederatedNamespace((Boolean)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case BK_ZK_SERVERS:
      return getBkZkServers();

    case BK_LEDGERS_PATH:
      return getBkLedgersPath();

    case SANITY_CHECK_TXN_ID:
      return isSanityCheckTxnID();

    case ENCODE_REGION_ID:
      return isEncodeRegionID();

    case BK_ZK_SERVERS_FOR_READER:
      return getBkZkServersForReader();

    case DL_ZK_SERVERS_FOR_WRITER:
      return getDlZkServersForWriter();

    case DL_ZK_SERVERS_FOR_READER:
      return getDlZkServersForReader();

    case ACL_ROOT_PATH:
      return getAclRootPath();

    case FIRST_LOG_SEGMENT_SEQ_NO:
      return getFirstLogSegmentSeqNo();

    case FEDERATED_NAMESPACE:
      return isFederatedNamespace();

    }
    throw new 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 IllegalArgumentException();
    }

    switch (field) {
    case BK_ZK_SERVERS:
      return isSetBkZkServers();
    case BK_LEDGERS_PATH:
      return isSetBkLedgersPath();
    case SANITY_CHECK_TXN_ID:
      return isSetSanityCheckTxnID();
    case ENCODE_REGION_ID:
      return isSetEncodeRegionID();
    case BK_ZK_SERVERS_FOR_READER:
      return isSetBkZkServersForReader();
    case DL_ZK_SERVERS_FOR_WRITER:
      return isSetDlZkServersForWriter();
    case DL_ZK_SERVERS_FOR_READER:
      return isSetDlZkServersForReader();
    case ACL_ROOT_PATH:
      return isSetAclRootPath();
    case FIRST_LOG_SEGMENT_SEQ_NO:
      return isSetFirstLogSegmentSeqNo();
    case FEDERATED_NAMESPACE:
      return isSetFederatedNamespace();
    }
    throw new IllegalStateException();
  }

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

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

    boolean this_present_bkZkServers = true && this.isSetBkZkServers();
    boolean that_present_bkZkServers = true && that.isSetBkZkServers();
    if (this_present_bkZkServers || that_present_bkZkServers) {
      if (!(this_present_bkZkServers && that_present_bkZkServers))
        return false;
      if (!this.bkZkServers.equals(that.bkZkServers))
        return false;
    }

    boolean this_present_bkLedgersPath = true && this.isSetBkLedgersPath();
    boolean that_present_bkLedgersPath = true && that.isSetBkLedgersPath();
    if (this_present_bkLedgersPath || that_present_bkLedgersPath) {
      if (!(this_present_bkLedgersPath && that_present_bkLedgersPath))
        return false;
      if (!this.bkLedgersPath.equals(that.bkLedgersPath))
        return false;
    }

    boolean this_present_sanityCheckTxnID = true && this.isSetSanityCheckTxnID();
    boolean that_present_sanityCheckTxnID = true && that.isSetSanityCheckTxnID();
    if (this_present_sanityCheckTxnID || that_present_sanityCheckTxnID) {
      if (!(this_present_sanityCheckTxnID && that_present_sanityCheckTxnID))
        return false;
      if (this.sanityCheckTxnID != that.sanityCheckTxnID)
        return false;
    }

    boolean this_present_encodeRegionID = true && this.isSetEncodeRegionID();
    boolean that_present_encodeRegionID = true && that.isSetEncodeRegionID();
    if (this_present_encodeRegionID || that_present_encodeRegionID) {
      if (!(this_present_encodeRegionID && that_present_encodeRegionID))
        return false;
      if (this.encodeRegionID != that.encodeRegionID)
        return false;
    }

    boolean this_present_bkZkServersForReader = true && this.isSetBkZkServersForReader();
    boolean that_present_bkZkServersForReader = true && that.isSetBkZkServersForReader();
    if (this_present_bkZkServersForReader || that_present_bkZkServersForReader) {
      if (!(this_present_bkZkServersForReader && that_present_bkZkServersForReader))
        return false;
      if (!this.bkZkServersForReader.equals(that.bkZkServersForReader))
        return false;
    }

    boolean this_present_dlZkServersForWriter = true && this.isSetDlZkServersForWriter();
    boolean that_present_dlZkServersForWriter = true && that.isSetDlZkServersForWriter();
    if (this_present_dlZkServersForWriter || that_present_dlZkServersForWriter) {
      if (!(this_present_dlZkServersForWriter && that_present_dlZkServersForWriter))
        return false;
      if (!this.dlZkServersForWriter.equals(that.dlZkServersForWriter))
        return false;
    }

    boolean this_present_dlZkServersForReader = true && this.isSetDlZkServersForReader();
    boolean that_present_dlZkServersForReader = true && that.isSetDlZkServersForReader();
    if (this_present_dlZkServersForReader || that_present_dlZkServersForReader) {
      if (!(this_present_dlZkServersForReader && that_present_dlZkServersForReader))
        return false;
      if (!this.dlZkServersForReader.equals(that.dlZkServersForReader))
        return false;
    }

    boolean this_present_aclRootPath = true && this.isSetAclRootPath();
    boolean that_present_aclRootPath = true && that.isSetAclRootPath();
    if (this_present_aclRootPath || that_present_aclRootPath) {
      if (!(this_present_aclRootPath && that_present_aclRootPath))
        return false;
      if (!this.aclRootPath.equals(that.aclRootPath))
        return false;
    }

    boolean this_present_firstLogSegmentSeqNo = true && this.isSetFirstLogSegmentSeqNo();
    boolean that_present_firstLogSegmentSeqNo = true && that.isSetFirstLogSegmentSeqNo();
    if (this_present_firstLogSegmentSeqNo || that_present_firstLogSegmentSeqNo) {
      if (!(this_present_firstLogSegmentSeqNo && that_present_firstLogSegmentSeqNo))
        return false;
      if (this.firstLogSegmentSeqNo != that.firstLogSegmentSeqNo)
        return false;
    }

    boolean this_present_federatedNamespace = true && this.isSetFederatedNamespace();
    boolean that_present_federatedNamespace = true && that.isSetFederatedNamespace();
    if (this_present_federatedNamespace || that_present_federatedNamespace) {
      if (!(this_present_federatedNamespace && that_present_federatedNamespace))
        return false;
      if (this.federatedNamespace != that.federatedNamespace)
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    List<Object> list = new ArrayList<Object>();

    boolean present_bkZkServers = true && (isSetBkZkServers());
    list.add(present_bkZkServers);
    if (present_bkZkServers)
      list.add(bkZkServers);

    boolean present_bkLedgersPath = true && (isSetBkLedgersPath());
    list.add(present_bkLedgersPath);
    if (present_bkLedgersPath)
      list.add(bkLedgersPath);

    boolean present_sanityCheckTxnID = true && (isSetSanityCheckTxnID());
    list.add(present_sanityCheckTxnID);
    if (present_sanityCheckTxnID)
      list.add(sanityCheckTxnID);

    boolean present_encodeRegionID = true && (isSetEncodeRegionID());
    list.add(present_encodeRegionID);
    if (present_encodeRegionID)
      list.add(encodeRegionID);

    boolean present_bkZkServersForReader = true && (isSetBkZkServersForReader());
    list.add(present_bkZkServersForReader);
    if (present_bkZkServersForReader)
      list.add(bkZkServersForReader);

    boolean present_dlZkServersForWriter = true && (isSetDlZkServersForWriter());
    list.add(present_dlZkServersForWriter);
    if (present_dlZkServersForWriter)
      list.add(dlZkServersForWriter);

    boolean present_dlZkServersForReader = true && (isSetDlZkServersForReader());
    list.add(present_dlZkServersForReader);
    if (present_dlZkServersForReader)
      list.add(dlZkServersForReader);

    boolean present_aclRootPath = true && (isSetAclRootPath());
    list.add(present_aclRootPath);
    if (present_aclRootPath)
      list.add(aclRootPath);

    boolean present_firstLogSegmentSeqNo = true && (isSetFirstLogSegmentSeqNo());
    list.add(present_firstLogSegmentSeqNo);
    if (present_firstLogSegmentSeqNo)
      list.add(firstLogSegmentSeqNo);

    boolean present_federatedNamespace = true && (isSetFederatedNamespace());
    list.add(present_federatedNamespace);
    if (present_federatedNamespace)
      list.add(federatedNamespace);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetBkZkServers()).compareTo(other.isSetBkZkServers());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetBkZkServers()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.bkZkServers, other.bkZkServers);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetBkLedgersPath()).compareTo(other.isSetBkLedgersPath());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetBkLedgersPath()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.bkLedgersPath, other.bkLedgersPath);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetSanityCheckTxnID()).compareTo(other.isSetSanityCheckTxnID());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSanityCheckTxnID()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sanityCheckTxnID, other.sanityCheckTxnID);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetEncodeRegionID()).compareTo(other.isSetEncodeRegionID());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetEncodeRegionID()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.encodeRegionID, other.encodeRegionID);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetBkZkServersForReader()).compareTo(other.isSetBkZkServersForReader());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetBkZkServersForReader()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.bkZkServersForReader, other.bkZkServersForReader);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetDlZkServersForWriter()).compareTo(other.isSetDlZkServersForWriter());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDlZkServersForWriter()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dlZkServersForWriter, other.dlZkServersForWriter);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetDlZkServersForReader()).compareTo(other.isSetDlZkServersForReader());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDlZkServersForReader()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dlZkServersForReader, other.dlZkServersForReader);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetAclRootPath()).compareTo(other.isSetAclRootPath());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetAclRootPath()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.aclRootPath, other.aclRootPath);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetFirstLogSegmentSeqNo()).compareTo(other.isSetFirstLogSegmentSeqNo());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetFirstLogSegmentSeqNo()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.firstLogSegmentSeqNo, other.firstLogSegmentSeqNo);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetFederatedNamespace()).compareTo(other.isSetFederatedNamespace());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetFederatedNamespace()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.federatedNamespace, other.federatedNamespace);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

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

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

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

    if (isSetBkZkServers()) {
      sb.append("bkZkServers:");
      if (this.bkZkServers == null) {
        sb.append("null");
      } else {
        sb.append(this.bkZkServers);
      }
      first = false;
    }
    if (isSetBkLedgersPath()) {
      if (!first) sb.append(", ");
      sb.append("bkLedgersPath:");
      if (this.bkLedgersPath == null) {
        sb.append("null");
      } else {
        sb.append(this.bkLedgersPath);
      }
      first = false;
    }
    if (isSetSanityCheckTxnID()) {
      if (!first) sb.append(", ");
      sb.append("sanityCheckTxnID:");
      sb.append(this.sanityCheckTxnID);
      first = false;
    }
    if (isSetEncodeRegionID()) {
      if (!first) sb.append(", ");
      sb.append("encodeRegionID:");
      sb.append(this.encodeRegionID);
      first = false;
    }
    if (isSetBkZkServersForReader()) {
      if (!first) sb.append(", ");
      sb.append("bkZkServersForReader:");
      if (this.bkZkServersForReader == null) {
        sb.append("null");
      } else {
        sb.append(this.bkZkServersForReader);
      }
      first = false;
    }
    if (isSetDlZkServersForWriter()) {
      if (!first) sb.append(", ");
      sb.append("dlZkServersForWriter:");
      if (this.dlZkServersForWriter == null) {
        sb.append("null");
      } else {
        sb.append(this.dlZkServersForWriter);
      }
      first = false;
    }
    if (isSetDlZkServersForReader()) {
      if (!first) sb.append(", ");
      sb.append("dlZkServersForReader:");
      if (this.dlZkServersForReader == null) {
        sb.append("null");
      } else {
        sb.append(this.dlZkServersForReader);
      }
      first = false;
    }
    if (isSetAclRootPath()) {
      if (!first) sb.append(", ");
      sb.append("aclRootPath:");
      if (this.aclRootPath == null) {
        sb.append("null");
      } else {
        sb.append(this.aclRootPath);
      }
      first = false;
    }
    if (isSetFirstLogSegmentSeqNo()) {
      if (!first) sb.append(", ");
      sb.append("firstLogSegmentSeqNo:");
      sb.append(this.firstLogSegmentSeqNo);
      first = false;
    }
    if (isSetFederatedNamespace()) {
      if (!first) sb.append(", ");
      sb.append("federatedNamespace:");
      sb.append(this.federatedNamespace);
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    // check for sub-struct validity
  }

  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, 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 BKDLConfigFormatStandardSchemeFactory implements SchemeFactory {
    public BKDLConfigFormatStandardScheme getScheme() {
      return new BKDLConfigFormatStandardScheme();
    }
  }

  private static class BKDLConfigFormatStandardScheme extends StandardScheme<BKDLConfigFormat> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, BKDLConfigFormat 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: // BK_ZK_SERVERS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.bkZkServers = iprot.readString();
              struct.setBkZkServersIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // BK_LEDGERS_PATH
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.bkLedgersPath = iprot.readString();
              struct.setBkLedgersPathIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // SANITY_CHECK_TXN_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.sanityCheckTxnID = iprot.readBool();
              struct.setSanityCheckTxnIDIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // ENCODE_REGION_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.encodeRegionID = iprot.readBool();
              struct.setEncodeRegionIDIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // BK_ZK_SERVERS_FOR_READER
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.bkZkServersForReader = iprot.readString();
              struct.setBkZkServersForReaderIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // DL_ZK_SERVERS_FOR_WRITER
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.dlZkServersForWriter = iprot.readString();
              struct.setDlZkServersForWriterIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // DL_ZK_SERVERS_FOR_READER
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.dlZkServersForReader = iprot.readString();
              struct.setDlZkServersForReaderIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // ACL_ROOT_PATH
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.aclRootPath = iprot.readString();
              struct.setAclRootPathIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // FIRST_LOG_SEGMENT_SEQ_NO
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.firstLogSegmentSeqNo = iprot.readI64();
              struct.setFirstLogSegmentSeqNoIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // FEDERATED_NAMESPACE
            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
              struct.federatedNamespace = iprot.readBool();
              struct.setFederatedNamespaceIsSet(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, BKDLConfigFormat struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.bkZkServers != null) {
        if (struct.isSetBkZkServers()) {
          oprot.writeFieldBegin(BK_ZK_SERVERS_FIELD_DESC);
          oprot.writeString(struct.bkZkServers);
          oprot.writeFieldEnd();
        }
      }
      if (struct.bkLedgersPath != null) {
        if (struct.isSetBkLedgersPath()) {
          oprot.writeFieldBegin(BK_LEDGERS_PATH_FIELD_DESC);
          oprot.writeString(struct.bkLedgersPath);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetSanityCheckTxnID()) {
        oprot.writeFieldBegin(SANITY_CHECK_TXN_ID_FIELD_DESC);
        oprot.writeBool(struct.sanityCheckTxnID);
        oprot.writeFieldEnd();
      }
      if (struct.isSetEncodeRegionID()) {
        oprot.writeFieldBegin(ENCODE_REGION_ID_FIELD_DESC);
        oprot.writeBool(struct.encodeRegionID);
        oprot.writeFieldEnd();
      }
      if (struct.bkZkServersForReader != null) {
        if (struct.isSetBkZkServersForReader()) {
          oprot.writeFieldBegin(BK_ZK_SERVERS_FOR_READER_FIELD_DESC);
          oprot.writeString(struct.bkZkServersForReader);
          oprot.writeFieldEnd();
        }
      }
      if (struct.dlZkServersForWriter != null) {
        if (struct.isSetDlZkServersForWriter()) {
          oprot.writeFieldBegin(DL_ZK_SERVERS_FOR_WRITER_FIELD_DESC);
          oprot.writeString(struct.dlZkServersForWriter);
          oprot.writeFieldEnd();
        }
      }
      if (struct.dlZkServersForReader != null) {
        if (struct.isSetDlZkServersForReader()) {
          oprot.writeFieldBegin(DL_ZK_SERVERS_FOR_READER_FIELD_DESC);
          oprot.writeString(struct.dlZkServersForReader);
          oprot.writeFieldEnd();
        }
      }
      if (struct.aclRootPath != null) {
        if (struct.isSetAclRootPath()) {
          oprot.writeFieldBegin(ACL_ROOT_PATH_FIELD_DESC);
          oprot.writeString(struct.aclRootPath);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetFirstLogSegmentSeqNo()) {
        oprot.writeFieldBegin(FIRST_LOG_SEGMENT_SEQ_NO_FIELD_DESC);
        oprot.writeI64(struct.firstLogSegmentSeqNo);
        oprot.writeFieldEnd();
      }
      if (struct.isSetFederatedNamespace()) {
        oprot.writeFieldBegin(FEDERATED_NAMESPACE_FIELD_DESC);
        oprot.writeBool(struct.federatedNamespace);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class BKDLConfigFormatTupleSchemeFactory implements SchemeFactory {
    public BKDLConfigFormatTupleScheme getScheme() {
      return new BKDLConfigFormatTupleScheme();
    }
  }

  private static class BKDLConfigFormatTupleScheme extends TupleScheme<BKDLConfigFormat> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, BKDLConfigFormat struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      BitSet optionals = new BitSet();
      if (struct.isSetBkZkServers()) {
        optionals.set(0);
      }
      if (struct.isSetBkLedgersPath()) {
        optionals.set(1);
      }
      if (struct.isSetSanityCheckTxnID()) {
        optionals.set(2);
      }
      if (struct.isSetEncodeRegionID()) {
        optionals.set(3);
      }
      if (struct.isSetBkZkServersForReader()) {
        optionals.set(4);
      }
      if (struct.isSetDlZkServersForWriter()) {
        optionals.set(5);
      }
      if (struct.isSetDlZkServersForReader()) {
        optionals.set(6);
      }
      if (struct.isSetAclRootPath()) {
        optionals.set(7);
      }
      if (struct.isSetFirstLogSegmentSeqNo()) {
        optionals.set(8);
      }
      if (struct.isSetFederatedNamespace()) {
        optionals.set(9);
      }
      oprot.writeBitSet(optionals, 10);
      if (struct.isSetBkZkServers()) {
        oprot.writeString(struct.bkZkServers);
      }
      if (struct.isSetBkLedgersPath()) {
        oprot.writeString(struct.bkLedgersPath);
      }
      if (struct.isSetSanityCheckTxnID()) {
        oprot.writeBool(struct.sanityCheckTxnID);
      }
      if (struct.isSetEncodeRegionID()) {
        oprot.writeBool(struct.encodeRegionID);
      }
      if (struct.isSetBkZkServersForReader()) {
        oprot.writeString(struct.bkZkServersForReader);
      }
      if (struct.isSetDlZkServersForWriter()) {
        oprot.writeString(struct.dlZkServersForWriter);
      }
      if (struct.isSetDlZkServersForReader()) {
        oprot.writeString(struct.dlZkServersForReader);
      }
      if (struct.isSetAclRootPath()) {
        oprot.writeString(struct.aclRootPath);
      }
      if (struct.isSetFirstLogSegmentSeqNo()) {
        oprot.writeI64(struct.firstLogSegmentSeqNo);
      }
      if (struct.isSetFederatedNamespace()) {
        oprot.writeBool(struct.federatedNamespace);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, BKDLConfigFormat struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      BitSet incoming = iprot.readBitSet(10);
      if (incoming.get(0)) {
        struct.bkZkServers = iprot.readString();
        struct.setBkZkServersIsSet(true);
      }
      if (incoming.get(1)) {
        struct.bkLedgersPath = iprot.readString();
        struct.setBkLedgersPathIsSet(true);
      }
      if (incoming.get(2)) {
        struct.sanityCheckTxnID = iprot.readBool();
        struct.setSanityCheckTxnIDIsSet(true);
      }
      if (incoming.get(3)) {
        struct.encodeRegionID = iprot.readBool();
        struct.setEncodeRegionIDIsSet(true);
      }
      if (incoming.get(4)) {
        struct.bkZkServersForReader = iprot.readString();
        struct.setBkZkServersForReaderIsSet(true);
      }
      if (incoming.get(5)) {
        struct.dlZkServersForWriter = iprot.readString();
        struct.setDlZkServersForWriterIsSet(true);
      }
      if (incoming.get(6)) {
        struct.dlZkServersForReader = iprot.readString();
        struct.setDlZkServersForReaderIsSet(true);
      }
      if (incoming.get(7)) {
        struct.aclRootPath = iprot.readString();
        struct.setAclRootPathIsSet(true);
      }
      if (incoming.get(8)) {
        struct.firstLogSegmentSeqNo = iprot.readI64();
        struct.setFirstLogSegmentSeqNoIsSet(true);
      }
      if (incoming.get(9)) {
        struct.federatedNamespace = iprot.readBool();
        struct.setFederatedNamespaceIsSet(true);
      }
    }
  }

}

