/**
 * Autogenerated by Thrift Compiler (0.9.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
#ifndef parquet_TYPES_H
#define parquet_TYPES_H

#include <thrift/Thrift.h>
#include <thrift/TApplicationException.h>
#include <thrift/protocol/TProtocol.h>
#include <thrift/transport/TTransport.h>



namespace parquet {

struct Type {
  enum type {
    BOOLEAN = 0,
    INT32 = 1,
    INT64 = 2,
    INT96 = 3,
    FLOAT = 4,
    DOUBLE = 5,
    BYTE_ARRAY = 6,
    FIXED_LEN_BYTE_ARRAY = 7
  };
};

extern const std::map<int, const char*> _Type_VALUES_TO_NAMES;

struct ConvertedType {
  enum type {
    UTF8 = 0,
    MAP = 1,
    MAP_KEY_VALUE = 2,
    LIST = 3,
    ENUM = 4,
    DECIMAL = 5
  };
};

extern const std::map<int, const char*> _ConvertedType_VALUES_TO_NAMES;

struct FieldRepetitionType {
  enum type {
    REQUIRED = 0,
    OPTIONAL = 1,
    REPEATED = 2
  };
};

extern const std::map<int, const char*> _FieldRepetitionType_VALUES_TO_NAMES;

struct Encoding {
  enum type {
    PLAIN = 0,
    PLAIN_DICTIONARY = 2,
    RLE = 3,
    BIT_PACKED = 4,
    DELTA_BINARY_PACKED = 5,
    DELTA_LENGTH_BYTE_ARRAY = 6,
    DELTA_BYTE_ARRAY = 7,
    RLE_DICTIONARY = 8
  };
};

extern const std::map<int, const char*> _Encoding_VALUES_TO_NAMES;

struct CompressionCodec {
  enum type {
    UNCOMPRESSED = 0,
    SNAPPY = 1,
    GZIP = 2,
    LZO = 3
  };
};

extern const std::map<int, const char*> _CompressionCodec_VALUES_TO_NAMES;

struct PageType {
  enum type {
    DATA_PAGE = 0,
    INDEX_PAGE = 1,
    DICTIONARY_PAGE = 2,
    DATA_PAGE_V2 = 3
  };
};

extern const std::map<int, const char*> _PageType_VALUES_TO_NAMES;

typedef struct _Statistics__isset {
  _Statistics__isset() : max(false), min(false), null_count(false), distinct_count(false) {}
  bool max;
  bool min;
  bool null_count;
  bool distinct_count;
} _Statistics__isset;

class Statistics {
 public:

  static const char* ascii_fingerprint; // = "CE004821871820DD79A8FD98BB101F6D";
  static const uint8_t binary_fingerprint[16]; // = {0xCE,0x00,0x48,0x21,0x87,0x18,0x20,0xDD,0x79,0xA8,0xFD,0x98,0xBB,0x10,0x1F,0x6D};

  Statistics() : max(), min(), null_count(0), distinct_count(0) {
  }

  virtual ~Statistics() throw() {}

  std::string max;
  std::string min;
  int64_t null_count;
  int64_t distinct_count;

  _Statistics__isset __isset;

  void __set_max(const std::string& val) {
    max = val;
    __isset.max = true;
  }

  void __set_min(const std::string& val) {
    min = val;
    __isset.min = true;
  }

  void __set_null_count(const int64_t val) {
    null_count = val;
    __isset.null_count = true;
  }

  void __set_distinct_count(const int64_t val) {
    distinct_count = val;
    __isset.distinct_count = true;
  }

  bool operator == (const Statistics & rhs) const
  {
    if (__isset.max != rhs.__isset.max)
      return false;
    else if (__isset.max && !(max == rhs.max))
      return false;
    if (__isset.min != rhs.__isset.min)
      return false;
    else if (__isset.min && !(min == rhs.min))
      return false;
    if (__isset.null_count != rhs.__isset.null_count)
      return false;
    else if (__isset.null_count && !(null_count == rhs.null_count))
      return false;
    if (__isset.distinct_count != rhs.__isset.distinct_count)
      return false;
    else if (__isset.distinct_count && !(distinct_count == rhs.distinct_count))
      return false;
    return true;
  }
  bool operator != (const Statistics &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const Statistics & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(Statistics &a, Statistics &b);

typedef struct _SchemaElement__isset {
  _SchemaElement__isset() : type(false), type_length(false), repetition_type(false), num_children(false), converted_type(false), scale(false), precision(false) {}
  bool type;
  bool type_length;
  bool repetition_type;
  bool num_children;
  bool converted_type;
  bool scale;
  bool precision;
} _SchemaElement__isset;

class SchemaElement {
 public:

  static const char* ascii_fingerprint; // = "388A784401753800444CFEAC8BC1B1A1";
  static const uint8_t binary_fingerprint[16]; // = {0x38,0x8A,0x78,0x44,0x01,0x75,0x38,0x00,0x44,0x4C,0xFE,0xAC,0x8B,0xC1,0xB1,0xA1};

  SchemaElement() : type((Type::type)0), type_length(0), repetition_type((FieldRepetitionType::type)0), name(), num_children(0), converted_type((ConvertedType::type)0), scale(0), precision(0) {
  }

  virtual ~SchemaElement() throw() {}

  Type::type type;
  int32_t type_length;
  FieldRepetitionType::type repetition_type;
  std::string name;
  int32_t num_children;
  ConvertedType::type converted_type;
  int32_t scale;
  int32_t precision;

  _SchemaElement__isset __isset;

  void __set_type(const Type::type val) {
    type = val;
    __isset.type = true;
  }

  void __set_type_length(const int32_t val) {
    type_length = val;
    __isset.type_length = true;
  }

  void __set_repetition_type(const FieldRepetitionType::type val) {
    repetition_type = val;
    __isset.repetition_type = true;
  }

  void __set_name(const std::string& val) {
    name = val;
  }

  void __set_num_children(const int32_t val) {
    num_children = val;
    __isset.num_children = true;
  }

  void __set_converted_type(const ConvertedType::type val) {
    converted_type = val;
    __isset.converted_type = true;
  }

  void __set_scale(const int32_t val) {
    scale = val;
    __isset.scale = true;
  }

  void __set_precision(const int32_t val) {
    precision = val;
    __isset.precision = true;
  }

  bool operator == (const SchemaElement & rhs) const
  {
    if (__isset.type != rhs.__isset.type)
      return false;
    else if (__isset.type && !(type == rhs.type))
      return false;
    if (__isset.type_length != rhs.__isset.type_length)
      return false;
    else if (__isset.type_length && !(type_length == rhs.type_length))
      return false;
    if (__isset.repetition_type != rhs.__isset.repetition_type)
      return false;
    else if (__isset.repetition_type && !(repetition_type == rhs.repetition_type))
      return false;
    if (!(name == rhs.name))
      return false;
    if (__isset.num_children != rhs.__isset.num_children)
      return false;
    else if (__isset.num_children && !(num_children == rhs.num_children))
      return false;
    if (__isset.converted_type != rhs.__isset.converted_type)
      return false;
    else if (__isset.converted_type && !(converted_type == rhs.converted_type))
      return false;
    if (__isset.scale != rhs.__isset.scale)
      return false;
    else if (__isset.scale && !(scale == rhs.scale))
      return false;
    if (__isset.precision != rhs.__isset.precision)
      return false;
    else if (__isset.precision && !(precision == rhs.precision))
      return false;
    return true;
  }
  bool operator != (const SchemaElement &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const SchemaElement & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(SchemaElement &a, SchemaElement &b);

typedef struct _DataPageHeader__isset {
  _DataPageHeader__isset() : statistics(false) {}
  bool statistics;
} _DataPageHeader__isset;

class DataPageHeader {
 public:

  static const char* ascii_fingerprint; // = "5FC1792B0483E9C984475384165040B1";
  static const uint8_t binary_fingerprint[16]; // = {0x5F,0xC1,0x79,0x2B,0x04,0x83,0xE9,0xC9,0x84,0x47,0x53,0x84,0x16,0x50,0x40,0xB1};

  DataPageHeader() : num_values(0), encoding((Encoding::type)0), definition_level_encoding((Encoding::type)0), repetition_level_encoding((Encoding::type)0) {
  }

  virtual ~DataPageHeader() throw() {}

  int32_t num_values;
  Encoding::type encoding;
  Encoding::type definition_level_encoding;
  Encoding::type repetition_level_encoding;
  Statistics statistics;

  _DataPageHeader__isset __isset;

  void __set_num_values(const int32_t val) {
    num_values = val;
  }

  void __set_encoding(const Encoding::type val) {
    encoding = val;
  }

  void __set_definition_level_encoding(const Encoding::type val) {
    definition_level_encoding = val;
  }

  void __set_repetition_level_encoding(const Encoding::type val) {
    repetition_level_encoding = val;
  }

  void __set_statistics(const Statistics& val) {
    statistics = val;
    __isset.statistics = true;
  }

  bool operator == (const DataPageHeader & rhs) const
  {
    if (!(num_values == rhs.num_values))
      return false;
    if (!(encoding == rhs.encoding))
      return false;
    if (!(definition_level_encoding == rhs.definition_level_encoding))
      return false;
    if (!(repetition_level_encoding == rhs.repetition_level_encoding))
      return false;
    if (__isset.statistics != rhs.__isset.statistics)
      return false;
    else if (__isset.statistics && !(statistics == rhs.statistics))
      return false;
    return true;
  }
  bool operator != (const DataPageHeader &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const DataPageHeader & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(DataPageHeader &a, DataPageHeader &b);


class IndexPageHeader {
 public:

  static const char* ascii_fingerprint; // = "99914B932BD37A50B983C5E7C90AE93B";
  static const uint8_t binary_fingerprint[16]; // = {0x99,0x91,0x4B,0x93,0x2B,0xD3,0x7A,0x50,0xB9,0x83,0xC5,0xE7,0xC9,0x0A,0xE9,0x3B};

  IndexPageHeader() {
  }

  virtual ~IndexPageHeader() throw() {}


  bool operator == (const IndexPageHeader & /* rhs */) const
  {
    return true;
  }
  bool operator != (const IndexPageHeader &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const IndexPageHeader & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(IndexPageHeader &a, IndexPageHeader &b);

typedef struct _DictionaryPageHeader__isset {
  _DictionaryPageHeader__isset() : is_sorted(false) {}
  bool is_sorted;
} _DictionaryPageHeader__isset;

class DictionaryPageHeader {
 public:

  static const char* ascii_fingerprint; // = "B149E4528254D495610C22AE4BD539C5";
  static const uint8_t binary_fingerprint[16]; // = {0xB1,0x49,0xE4,0x52,0x82,0x54,0xD4,0x95,0x61,0x0C,0x22,0xAE,0x4B,0xD5,0x39,0xC5};

  DictionaryPageHeader() : num_values(0), encoding((Encoding::type)0), is_sorted(0) {
  }

  virtual ~DictionaryPageHeader() throw() {}

  int32_t num_values;
  Encoding::type encoding;
  bool is_sorted;

  _DictionaryPageHeader__isset __isset;

  void __set_num_values(const int32_t val) {
    num_values = val;
  }

  void __set_encoding(const Encoding::type val) {
    encoding = val;
  }

  void __set_is_sorted(const bool val) {
    is_sorted = val;
    __isset.is_sorted = true;
  }

  bool operator == (const DictionaryPageHeader & rhs) const
  {
    if (!(num_values == rhs.num_values))
      return false;
    if (!(encoding == rhs.encoding))
      return false;
    if (__isset.is_sorted != rhs.__isset.is_sorted)
      return false;
    else if (__isset.is_sorted && !(is_sorted == rhs.is_sorted))
      return false;
    return true;
  }
  bool operator != (const DictionaryPageHeader &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const DictionaryPageHeader & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(DictionaryPageHeader &a, DictionaryPageHeader &b);

typedef struct _DataPageHeaderV2__isset {
  _DataPageHeaderV2__isset() : is_compressed(true), statistics(false) {}
  bool is_compressed;
  bool statistics;
} _DataPageHeaderV2__isset;

class DataPageHeaderV2 {
 public:

  static const char* ascii_fingerprint; // = "69FF2F6BD1A443440D5E46ABA5A3A919";
  static const uint8_t binary_fingerprint[16]; // = {0x69,0xFF,0x2F,0x6B,0xD1,0xA4,0x43,0x44,0x0D,0x5E,0x46,0xAB,0xA5,0xA3,0xA9,0x19};

  DataPageHeaderV2() : num_values(0), num_nulls(0), num_rows(0), encoding((Encoding::type)0), definition_levels_byte_length(0), repetition_levels_byte_length(0), is_compressed(true) {
  }

  virtual ~DataPageHeaderV2() throw() {}

  int32_t num_values;
  int32_t num_nulls;
  int32_t num_rows;
  Encoding::type encoding;
  int32_t definition_levels_byte_length;
  int32_t repetition_levels_byte_length;
  bool is_compressed;
  Statistics statistics;

  _DataPageHeaderV2__isset __isset;

  void __set_num_values(const int32_t val) {
    num_values = val;
  }

  void __set_num_nulls(const int32_t val) {
    num_nulls = val;
  }

  void __set_num_rows(const int32_t val) {
    num_rows = val;
  }

  void __set_encoding(const Encoding::type val) {
    encoding = val;
  }

  void __set_definition_levels_byte_length(const int32_t val) {
    definition_levels_byte_length = val;
  }

  void __set_repetition_levels_byte_length(const int32_t val) {
    repetition_levels_byte_length = val;
  }

  void __set_is_compressed(const bool val) {
    is_compressed = val;
    __isset.is_compressed = true;
  }

  void __set_statistics(const Statistics& val) {
    statistics = val;
    __isset.statistics = true;
  }

  bool operator == (const DataPageHeaderV2 & rhs) const
  {
    if (!(num_values == rhs.num_values))
      return false;
    if (!(num_nulls == rhs.num_nulls))
      return false;
    if (!(num_rows == rhs.num_rows))
      return false;
    if (!(encoding == rhs.encoding))
      return false;
    if (!(definition_levels_byte_length == rhs.definition_levels_byte_length))
      return false;
    if (!(repetition_levels_byte_length == rhs.repetition_levels_byte_length))
      return false;
    if (__isset.is_compressed != rhs.__isset.is_compressed)
      return false;
    else if (__isset.is_compressed && !(is_compressed == rhs.is_compressed))
      return false;
    if (__isset.statistics != rhs.__isset.statistics)
      return false;
    else if (__isset.statistics && !(statistics == rhs.statistics))
      return false;
    return true;
  }
  bool operator != (const DataPageHeaderV2 &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const DataPageHeaderV2 & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(DataPageHeaderV2 &a, DataPageHeaderV2 &b);

typedef struct _PageHeader__isset {
  _PageHeader__isset() : crc(false), data_page_header(false), index_page_header(false), dictionary_page_header(false), data_page_header_v2(false) {}
  bool crc;
  bool data_page_header;
  bool index_page_header;
  bool dictionary_page_header;
  bool data_page_header_v2;
} _PageHeader__isset;

class PageHeader {
 public:

  static const char* ascii_fingerprint; // = "B5BD2BDF3756C883A58B30B9C9F204A0";
  static const uint8_t binary_fingerprint[16]; // = {0xB5,0xBD,0x2B,0xDF,0x37,0x56,0xC8,0x83,0xA5,0x8B,0x30,0xB9,0xC9,0xF2,0x04,0xA0};

  PageHeader() : type((PageType::type)0), uncompressed_page_size(0), compressed_page_size(0), crc(0) {
  }

  virtual ~PageHeader() throw() {}

  PageType::type type;
  int32_t uncompressed_page_size;
  int32_t compressed_page_size;
  int32_t crc;
  DataPageHeader data_page_header;
  IndexPageHeader index_page_header;
  DictionaryPageHeader dictionary_page_header;
  DataPageHeaderV2 data_page_header_v2;

  _PageHeader__isset __isset;

  void __set_type(const PageType::type val) {
    type = val;
  }

  void __set_uncompressed_page_size(const int32_t val) {
    uncompressed_page_size = val;
  }

  void __set_compressed_page_size(const int32_t val) {
    compressed_page_size = val;
  }

  void __set_crc(const int32_t val) {
    crc = val;
    __isset.crc = true;
  }

  void __set_data_page_header(const DataPageHeader& val) {
    data_page_header = val;
    __isset.data_page_header = true;
  }

  void __set_index_page_header(const IndexPageHeader& val) {
    index_page_header = val;
    __isset.index_page_header = true;
  }

  void __set_dictionary_page_header(const DictionaryPageHeader& val) {
    dictionary_page_header = val;
    __isset.dictionary_page_header = true;
  }

  void __set_data_page_header_v2(const DataPageHeaderV2& val) {
    data_page_header_v2 = val;
    __isset.data_page_header_v2 = true;
  }

  bool operator == (const PageHeader & rhs) const
  {
    if (!(type == rhs.type))
      return false;
    if (!(uncompressed_page_size == rhs.uncompressed_page_size))
      return false;
    if (!(compressed_page_size == rhs.compressed_page_size))
      return false;
    if (__isset.crc != rhs.__isset.crc)
      return false;
    else if (__isset.crc && !(crc == rhs.crc))
      return false;
    if (__isset.data_page_header != rhs.__isset.data_page_header)
      return false;
    else if (__isset.data_page_header && !(data_page_header == rhs.data_page_header))
      return false;
    if (__isset.index_page_header != rhs.__isset.index_page_header)
      return false;
    else if (__isset.index_page_header && !(index_page_header == rhs.index_page_header))
      return false;
    if (__isset.dictionary_page_header != rhs.__isset.dictionary_page_header)
      return false;
    else if (__isset.dictionary_page_header && !(dictionary_page_header == rhs.dictionary_page_header))
      return false;
    if (__isset.data_page_header_v2 != rhs.__isset.data_page_header_v2)
      return false;
    else if (__isset.data_page_header_v2 && !(data_page_header_v2 == rhs.data_page_header_v2))
      return false;
    return true;
  }
  bool operator != (const PageHeader &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const PageHeader & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(PageHeader &a, PageHeader &b);

typedef struct _KeyValue__isset {
  _KeyValue__isset() : value(false) {}
  bool value;
} _KeyValue__isset;

class KeyValue {
 public:

  static const char* ascii_fingerprint; // = "5B708A954C550ECA9C1A49D3C5CAFAB9";
  static const uint8_t binary_fingerprint[16]; // = {0x5B,0x70,0x8A,0x95,0x4C,0x55,0x0E,0xCA,0x9C,0x1A,0x49,0xD3,0xC5,0xCA,0xFA,0xB9};

  KeyValue() : key(), value() {
  }

  virtual ~KeyValue() throw() {}

  std::string key;
  std::string value;

  _KeyValue__isset __isset;

  void __set_key(const std::string& val) {
    key = val;
  }

  void __set_value(const std::string& val) {
    value = val;
    __isset.value = true;
  }

  bool operator == (const KeyValue & rhs) const
  {
    if (!(key == rhs.key))
      return false;
    if (__isset.value != rhs.__isset.value)
      return false;
    else if (__isset.value && !(value == rhs.value))
      return false;
    return true;
  }
  bool operator != (const KeyValue &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const KeyValue & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(KeyValue &a, KeyValue &b);


class SortingColumn {
 public:

  static const char* ascii_fingerprint; // = "F079C2D58A783AD90F9BE05D10DBBC6F";
  static const uint8_t binary_fingerprint[16]; // = {0xF0,0x79,0xC2,0xD5,0x8A,0x78,0x3A,0xD9,0x0F,0x9B,0xE0,0x5D,0x10,0xDB,0xBC,0x6F};

  SortingColumn() : column_idx(0), descending(0), nulls_first(0) {
  }

  virtual ~SortingColumn() throw() {}

  int32_t column_idx;
  bool descending;
  bool nulls_first;

  void __set_column_idx(const int32_t val) {
    column_idx = val;
  }

  void __set_descending(const bool val) {
    descending = val;
  }

  void __set_nulls_first(const bool val) {
    nulls_first = val;
  }

  bool operator == (const SortingColumn & rhs) const
  {
    if (!(column_idx == rhs.column_idx))
      return false;
    if (!(descending == rhs.descending))
      return false;
    if (!(nulls_first == rhs.nulls_first))
      return false;
    return true;
  }
  bool operator != (const SortingColumn &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const SortingColumn & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(SortingColumn &a, SortingColumn &b);

typedef struct _ColumnMetaData__isset {
  _ColumnMetaData__isset() : key_value_metadata(false), index_page_offset(false), dictionary_page_offset(false), statistics(false) {}
  bool key_value_metadata;
  bool index_page_offset;
  bool dictionary_page_offset;
  bool statistics;
} _ColumnMetaData__isset;

class ColumnMetaData {
 public:

  static const char* ascii_fingerprint; // = "1AF797732BCB4465C6314FB29B86638D";
  static const uint8_t binary_fingerprint[16]; // = {0x1A,0xF7,0x97,0x73,0x2B,0xCB,0x44,0x65,0xC6,0x31,0x4F,0xB2,0x9B,0x86,0x63,0x8D};

  ColumnMetaData() : type((Type::type)0), codec((CompressionCodec::type)0), num_values(0), total_uncompressed_size(0), total_compressed_size(0), data_page_offset(0), index_page_offset(0), dictionary_page_offset(0) {
  }

  virtual ~ColumnMetaData() throw() {}

  Type::type type;
  std::vector<Encoding::type>  encodings;
  std::vector<std::string>  path_in_schema;
  CompressionCodec::type codec;
  int64_t num_values;
  int64_t total_uncompressed_size;
  int64_t total_compressed_size;
  std::vector<KeyValue>  key_value_metadata;
  int64_t data_page_offset;
  int64_t index_page_offset;
  int64_t dictionary_page_offset;
  Statistics statistics;

  _ColumnMetaData__isset __isset;

  void __set_type(const Type::type val) {
    type = val;
  }

  void __set_encodings(const std::vector<Encoding::type> & val) {
    encodings = val;
  }

  void __set_path_in_schema(const std::vector<std::string> & val) {
    path_in_schema = val;
  }

  void __set_codec(const CompressionCodec::type val) {
    codec = val;
  }

  void __set_num_values(const int64_t val) {
    num_values = val;
  }

  void __set_total_uncompressed_size(const int64_t val) {
    total_uncompressed_size = val;
  }

  void __set_total_compressed_size(const int64_t val) {
    total_compressed_size = val;
  }

  void __set_key_value_metadata(const std::vector<KeyValue> & val) {
    key_value_metadata = val;
    __isset.key_value_metadata = true;
  }

  void __set_data_page_offset(const int64_t val) {
    data_page_offset = val;
  }

  void __set_index_page_offset(const int64_t val) {
    index_page_offset = val;
    __isset.index_page_offset = true;
  }

  void __set_dictionary_page_offset(const int64_t val) {
    dictionary_page_offset = val;
    __isset.dictionary_page_offset = true;
  }

  void __set_statistics(const Statistics& val) {
    statistics = val;
    __isset.statistics = true;
  }

  bool operator == (const ColumnMetaData & rhs) const
  {
    if (!(type == rhs.type))
      return false;
    if (!(encodings == rhs.encodings))
      return false;
    if (!(path_in_schema == rhs.path_in_schema))
      return false;
    if (!(codec == rhs.codec))
      return false;
    if (!(num_values == rhs.num_values))
      return false;
    if (!(total_uncompressed_size == rhs.total_uncompressed_size))
      return false;
    if (!(total_compressed_size == rhs.total_compressed_size))
      return false;
    if (__isset.key_value_metadata != rhs.__isset.key_value_metadata)
      return false;
    else if (__isset.key_value_metadata && !(key_value_metadata == rhs.key_value_metadata))
      return false;
    if (!(data_page_offset == rhs.data_page_offset))
      return false;
    if (__isset.index_page_offset != rhs.__isset.index_page_offset)
      return false;
    else if (__isset.index_page_offset && !(index_page_offset == rhs.index_page_offset))
      return false;
    if (__isset.dictionary_page_offset != rhs.__isset.dictionary_page_offset)
      return false;
    else if (__isset.dictionary_page_offset && !(dictionary_page_offset == rhs.dictionary_page_offset))
      return false;
    if (__isset.statistics != rhs.__isset.statistics)
      return false;
    else if (__isset.statistics && !(statistics == rhs.statistics))
      return false;
    return true;
  }
  bool operator != (const ColumnMetaData &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ColumnMetaData & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(ColumnMetaData &a, ColumnMetaData &b);

typedef struct _ColumnChunk__isset {
  _ColumnChunk__isset() : file_path(false), meta_data(false) {}
  bool file_path;
  bool meta_data;
} _ColumnChunk__isset;

class ColumnChunk {
 public:

  static const char* ascii_fingerprint; // = "169FC47057EF3D82E2FACDDEC2641AE8";
  static const uint8_t binary_fingerprint[16]; // = {0x16,0x9F,0xC4,0x70,0x57,0xEF,0x3D,0x82,0xE2,0xFA,0xCD,0xDE,0xC2,0x64,0x1A,0xE8};

  ColumnChunk() : file_path(), file_offset(0) {
  }

  virtual ~ColumnChunk() throw() {}

  std::string file_path;
  int64_t file_offset;
  ColumnMetaData meta_data;

  _ColumnChunk__isset __isset;

  void __set_file_path(const std::string& val) {
    file_path = val;
    __isset.file_path = true;
  }

  void __set_file_offset(const int64_t val) {
    file_offset = val;
  }

  void __set_meta_data(const ColumnMetaData& val) {
    meta_data = val;
    __isset.meta_data = true;
  }

  bool operator == (const ColumnChunk & rhs) const
  {
    if (__isset.file_path != rhs.__isset.file_path)
      return false;
    else if (__isset.file_path && !(file_path == rhs.file_path))
      return false;
    if (!(file_offset == rhs.file_offset))
      return false;
    if (__isset.meta_data != rhs.__isset.meta_data)
      return false;
    else if (__isset.meta_data && !(meta_data == rhs.meta_data))
      return false;
    return true;
  }
  bool operator != (const ColumnChunk &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const ColumnChunk & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(ColumnChunk &a, ColumnChunk &b);

typedef struct _RowGroup__isset {
  _RowGroup__isset() : sorting_columns(false) {}
  bool sorting_columns;
} _RowGroup__isset;

class RowGroup {
 public:

  static const char* ascii_fingerprint; // = "DC7968627FA826DDC4C6C9BE773586C9";
  static const uint8_t binary_fingerprint[16]; // = {0xDC,0x79,0x68,0x62,0x7F,0xA8,0x26,0xDD,0xC4,0xC6,0xC9,0xBE,0x77,0x35,0x86,0xC9};

  RowGroup() : total_byte_size(0), num_rows(0) {
  }

  virtual ~RowGroup() throw() {}

  std::vector<ColumnChunk>  columns;
  int64_t total_byte_size;
  int64_t num_rows;
  std::vector<SortingColumn>  sorting_columns;

  _RowGroup__isset __isset;

  void __set_columns(const std::vector<ColumnChunk> & val) {
    columns = val;
  }

  void __set_total_byte_size(const int64_t val) {
    total_byte_size = val;
  }

  void __set_num_rows(const int64_t val) {
    num_rows = val;
  }

  void __set_sorting_columns(const std::vector<SortingColumn> & val) {
    sorting_columns = val;
    __isset.sorting_columns = true;
  }

  bool operator == (const RowGroup & rhs) const
  {
    if (!(columns == rhs.columns))
      return false;
    if (!(total_byte_size == rhs.total_byte_size))
      return false;
    if (!(num_rows == rhs.num_rows))
      return false;
    if (__isset.sorting_columns != rhs.__isset.sorting_columns)
      return false;
    else if (__isset.sorting_columns && !(sorting_columns == rhs.sorting_columns))
      return false;
    return true;
  }
  bool operator != (const RowGroup &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const RowGroup & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(RowGroup &a, RowGroup &b);

typedef struct _FileMetaData__isset {
  _FileMetaData__isset() : key_value_metadata(false), created_by(false) {}
  bool key_value_metadata;
  bool created_by;
} _FileMetaData__isset;

class FileMetaData {
 public:

  static const char* ascii_fingerprint; // = "44DC7D83A66D54A7B7892A985C4125C9";
  static const uint8_t binary_fingerprint[16]; // = {0x44,0xDC,0x7D,0x83,0xA6,0x6D,0x54,0xA7,0xB7,0x89,0x2A,0x98,0x5C,0x41,0x25,0xC9};

  FileMetaData() : version(0), num_rows(0), created_by() {
  }

  virtual ~FileMetaData() throw() {}

  int32_t version;
  std::vector<SchemaElement>  schema;
  int64_t num_rows;
  std::vector<RowGroup>  row_groups;
  std::vector<KeyValue>  key_value_metadata;
  std::string created_by;

  _FileMetaData__isset __isset;

  void __set_version(const int32_t val) {
    version = val;
  }

  void __set_schema(const std::vector<SchemaElement> & val) {
    schema = val;
  }

  void __set_num_rows(const int64_t val) {
    num_rows = val;
  }

  void __set_row_groups(const std::vector<RowGroup> & val) {
    row_groups = val;
  }

  void __set_key_value_metadata(const std::vector<KeyValue> & val) {
    key_value_metadata = val;
    __isset.key_value_metadata = true;
  }

  void __set_created_by(const std::string& val) {
    created_by = val;
    __isset.created_by = true;
  }

  bool operator == (const FileMetaData & rhs) const
  {
    if (!(version == rhs.version))
      return false;
    if (!(schema == rhs.schema))
      return false;
    if (!(num_rows == rhs.num_rows))
      return false;
    if (!(row_groups == rhs.row_groups))
      return false;
    if (__isset.key_value_metadata != rhs.__isset.key_value_metadata)
      return false;
    else if (__isset.key_value_metadata && !(key_value_metadata == rhs.key_value_metadata))
      return false;
    if (__isset.created_by != rhs.__isset.created_by)
      return false;
    else if (__isset.created_by && !(created_by == rhs.created_by))
      return false;
    return true;
  }
  bool operator != (const FileMetaData &rhs) const {
    return !(*this == rhs);
  }

  bool operator < (const FileMetaData & ) const;

  uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
  uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;

};

void swap(FileMetaData &a, FileMetaData &b);

} // namespace

#endif
