// automatically generated by the FlatBuffers compiler, do not modify


#ifndef FLATBUFFERS_GENERATED_SCHEMA_ORG_APACHE_ARROW_FLATBUF_H_
#define FLATBUFFERS_GENERATED_SCHEMA_ORG_APACHE_ARROW_FLATBUF_H_

#include "flatbuffers/flatbuffers.h"

namespace org {
namespace apache {
namespace arrow {
namespace flatbuf {

struct Null;
struct NullBuilder;

struct Struct_;
struct Struct_Builder;

struct List;
struct ListBuilder;

struct LargeList;
struct LargeListBuilder;

struct FixedSizeList;
struct FixedSizeListBuilder;

struct Map;
struct MapBuilder;

struct Union;
struct UnionBuilder;

struct Int;
struct IntBuilder;

struct FloatingPoint;
struct FloatingPointBuilder;

struct Utf8;
struct Utf8Builder;

struct Binary;
struct BinaryBuilder;

struct LargeUtf8;
struct LargeUtf8Builder;

struct LargeBinary;
struct LargeBinaryBuilder;

struct FixedSizeBinary;
struct FixedSizeBinaryBuilder;

struct Bool;
struct BoolBuilder;

struct Decimal;
struct DecimalBuilder;

struct Date;
struct DateBuilder;

struct Time;
struct TimeBuilder;

struct Timestamp;
struct TimestampBuilder;

struct Interval;
struct IntervalBuilder;

struct Duration;
struct DurationBuilder;

struct KeyValue;
struct KeyValueBuilder;

struct DictionaryEncoding;
struct DictionaryEncodingBuilder;

struct Field;
struct FieldBuilder;

struct Buffer;

struct Schema;
struct SchemaBuilder;

enum class MetadataVersion : int16_t {
  /// 0.1.0 (October 2016).
  V1 = 0,
  /// 0.2.0 (February 2017). Non-backwards compatible with V1.
  V2 = 1,
  /// 0.3.0 -> 0.7.1 (May - December 2017). Non-backwards compatible with V2.
  V3 = 2,
  /// >= 0.8.0 (December 2017). Non-backwards compatible with V3.
  V4 = 3,
  /// >= 1.0.0 (July 2020. Backwards compatible with V4 (V5 readers can read V4
  /// metadata and IPC messages). Implementations are recommended to provide a
  /// V4 compatibility mode with V5 format changes disabled.
  ///
  /// Incompatible changes between V4 and V5:
  /// - Union buffer layout has changed. In V5, Unions don't have a validity
  ///   bitmap buffer.
  V5 = 4,
  MIN = V1,
  MAX = V5
};

inline const MetadataVersion (&EnumValuesMetadataVersion())[5] {
  static const MetadataVersion values[] = {
    MetadataVersion::V1,
    MetadataVersion::V2,
    MetadataVersion::V3,
    MetadataVersion::V4,
    MetadataVersion::V5
  };
  return values;
}

inline const char * const *EnumNamesMetadataVersion() {
  static const char * const names[6] = {
    "V1",
    "V2",
    "V3",
    "V4",
    "V5",
    nullptr
  };
  return names;
}

inline const char *EnumNameMetadataVersion(MetadataVersion e) {
  if (flatbuffers::IsOutRange(e, MetadataVersion::V1, MetadataVersion::V5)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesMetadataVersion()[index];
}

/// Represents Arrow Features that might not have full support
/// within implementations. This is intended to be used in
/// two scenarios:
///  1.  A mechanism for readers of Arrow Streams
///      and files to understand that the stream or file makes
///      use of a feature that isn't supported or unknown to
///      the implementation (and therefore can meet the Arrow
///      forward compatibility guarantees).
///  2.  A means of negotiating between a client and server
///      what features a stream is allowed to use. The enums
///      values here are intented to represent higher level
///      features, additional details maybe negotiated
///      with key-value pairs specific to the protocol.
///
/// Enums added to this list should be assigned power-of-two values
/// to facilitate exchanging and comparing bitmaps for supported
/// features.
enum class Feature : int64_t {
  /// Needed to make flatbuffers happy.
  UNUSED = 0,
  /// The stream makes use of multiple full dictionaries with the
  /// same ID and assumes clients implement dictionary replacement
  /// correctly.
  DICTIONARY_REPLACEMENT = 1LL,
  /// The stream makes use of compressed bodies as described
  /// in Message.fbs.
  COMPRESSED_BODY = 2LL,
  MIN = UNUSED,
  MAX = COMPRESSED_BODY
};

inline const Feature (&EnumValuesFeature())[3] {
  static const Feature values[] = {
    Feature::UNUSED,
    Feature::DICTIONARY_REPLACEMENT,
    Feature::COMPRESSED_BODY
  };
  return values;
}

inline const char * const *EnumNamesFeature() {
  static const char * const names[4] = {
    "UNUSED",
    "DICTIONARY_REPLACEMENT",
    "COMPRESSED_BODY",
    nullptr
  };
  return names;
}

inline const char *EnumNameFeature(Feature e) {
  if (flatbuffers::IsOutRange(e, Feature::UNUSED, Feature::COMPRESSED_BODY)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesFeature()[index];
}

enum class UnionMode : int16_t {
  Sparse = 0,
  Dense = 1,
  MIN = Sparse,
  MAX = Dense
};

inline const UnionMode (&EnumValuesUnionMode())[2] {
  static const UnionMode values[] = {
    UnionMode::Sparse,
    UnionMode::Dense
  };
  return values;
}

inline const char * const *EnumNamesUnionMode() {
  static const char * const names[3] = {
    "Sparse",
    "Dense",
    nullptr
  };
  return names;
}

inline const char *EnumNameUnionMode(UnionMode e) {
  if (flatbuffers::IsOutRange(e, UnionMode::Sparse, UnionMode::Dense)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesUnionMode()[index];
}

enum class Precision : int16_t {
  HALF = 0,
  SINGLE = 1,
  DOUBLE = 2,
  MIN = HALF,
  MAX = DOUBLE
};

inline const Precision (&EnumValuesPrecision())[3] {
  static const Precision values[] = {
    Precision::HALF,
    Precision::SINGLE,
    Precision::DOUBLE
  };
  return values;
}

inline const char * const *EnumNamesPrecision() {
  static const char * const names[4] = {
    "HALF",
    "SINGLE",
    "DOUBLE",
    nullptr
  };
  return names;
}

inline const char *EnumNamePrecision(Precision e) {
  if (flatbuffers::IsOutRange(e, Precision::HALF, Precision::DOUBLE)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesPrecision()[index];
}

enum class DateUnit : int16_t {
  DAY = 0,
  MILLISECOND = 1,
  MIN = DAY,
  MAX = MILLISECOND
};

inline const DateUnit (&EnumValuesDateUnit())[2] {
  static const DateUnit values[] = {
    DateUnit::DAY,
    DateUnit::MILLISECOND
  };
  return values;
}

inline const char * const *EnumNamesDateUnit() {
  static const char * const names[3] = {
    "DAY",
    "MILLISECOND",
    nullptr
  };
  return names;
}

inline const char *EnumNameDateUnit(DateUnit e) {
  if (flatbuffers::IsOutRange(e, DateUnit::DAY, DateUnit::MILLISECOND)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesDateUnit()[index];
}

enum class TimeUnit : int16_t {
  SECOND = 0,
  MILLISECOND = 1,
  MICROSECOND = 2,
  NANOSECOND = 3,
  MIN = SECOND,
  MAX = NANOSECOND
};

inline const TimeUnit (&EnumValuesTimeUnit())[4] {
  static const TimeUnit values[] = {
    TimeUnit::SECOND,
    TimeUnit::MILLISECOND,
    TimeUnit::MICROSECOND,
    TimeUnit::NANOSECOND
  };
  return values;
}

inline const char * const *EnumNamesTimeUnit() {
  static const char * const names[5] = {
    "SECOND",
    "MILLISECOND",
    "MICROSECOND",
    "NANOSECOND",
    nullptr
  };
  return names;
}

inline const char *EnumNameTimeUnit(TimeUnit e) {
  if (flatbuffers::IsOutRange(e, TimeUnit::SECOND, TimeUnit::NANOSECOND)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesTimeUnit()[index];
}

enum class IntervalUnit : int16_t {
  YEAR_MONTH = 0,
  DAY_TIME = 1,
  MONTH_DAY_NANO = 2,
  MIN = YEAR_MONTH,
  MAX = MONTH_DAY_NANO
};

inline const IntervalUnit (&EnumValuesIntervalUnit())[3] {
  static const IntervalUnit values[] = {
    IntervalUnit::YEAR_MONTH,
    IntervalUnit::DAY_TIME,
    IntervalUnit::MONTH_DAY_NANO
  };
  return values;
}

inline const char * const *EnumNamesIntervalUnit() {
  static const char * const names[4] = {
    "YEAR_MONTH",
    "DAY_TIME",
    "MONTH_DAY_NANO",
    nullptr
  };
  return names;
}

inline const char *EnumNameIntervalUnit(IntervalUnit e) {
  if (flatbuffers::IsOutRange(e, IntervalUnit::YEAR_MONTH, IntervalUnit::MONTH_DAY_NANO)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesIntervalUnit()[index];
}

/// ----------------------------------------------------------------------
/// Top-level Type value, enabling extensible type-specific metadata. We can
/// add new logical types to Type without breaking backwards compatibility
enum class Type : uint8_t {
  NONE = 0,
  Null = 1,
  Int = 2,
  FloatingPoint = 3,
  Binary = 4,
  Utf8 = 5,
  Bool = 6,
  Decimal = 7,
  Date = 8,
  Time = 9,
  Timestamp = 10,
  Interval = 11,
  List = 12,
  Struct_ = 13,
  Union = 14,
  FixedSizeBinary = 15,
  FixedSizeList = 16,
  Map = 17,
  Duration = 18,
  LargeBinary = 19,
  LargeUtf8 = 20,
  LargeList = 21,
  MIN = NONE,
  MAX = LargeList
};

inline const Type (&EnumValuesType())[22] {
  static const Type values[] = {
    Type::NONE,
    Type::Null,
    Type::Int,
    Type::FloatingPoint,
    Type::Binary,
    Type::Utf8,
    Type::Bool,
    Type::Decimal,
    Type::Date,
    Type::Time,
    Type::Timestamp,
    Type::Interval,
    Type::List,
    Type::Struct_,
    Type::Union,
    Type::FixedSizeBinary,
    Type::FixedSizeList,
    Type::Map,
    Type::Duration,
    Type::LargeBinary,
    Type::LargeUtf8,
    Type::LargeList
  };
  return values;
}

inline const char * const *EnumNamesType() {
  static const char * const names[23] = {
    "NONE",
    "Null",
    "Int",
    "FloatingPoint",
    "Binary",
    "Utf8",
    "Bool",
    "Decimal",
    "Date",
    "Time",
    "Timestamp",
    "Interval",
    "List",
    "Struct_",
    "Union",
    "FixedSizeBinary",
    "FixedSizeList",
    "Map",
    "Duration",
    "LargeBinary",
    "LargeUtf8",
    "LargeList",
    nullptr
  };
  return names;
}

inline const char *EnumNameType(Type e) {
  if (flatbuffers::IsOutRange(e, Type::NONE, Type::LargeList)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesType()[index];
}

template<typename T> struct TypeTraits {
  static const Type enum_value = Type::NONE;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Null> {
  static const Type enum_value = Type::Null;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Int> {
  static const Type enum_value = Type::Int;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::FloatingPoint> {
  static const Type enum_value = Type::FloatingPoint;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Binary> {
  static const Type enum_value = Type::Binary;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Utf8> {
  static const Type enum_value = Type::Utf8;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Bool> {
  static const Type enum_value = Type::Bool;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Decimal> {
  static const Type enum_value = Type::Decimal;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Date> {
  static const Type enum_value = Type::Date;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Time> {
  static const Type enum_value = Type::Time;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Timestamp> {
  static const Type enum_value = Type::Timestamp;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Interval> {
  static const Type enum_value = Type::Interval;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::List> {
  static const Type enum_value = Type::List;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Struct_> {
  static const Type enum_value = Type::Struct_;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Union> {
  static const Type enum_value = Type::Union;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::FixedSizeBinary> {
  static const Type enum_value = Type::FixedSizeBinary;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::FixedSizeList> {
  static const Type enum_value = Type::FixedSizeList;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Map> {
  static const Type enum_value = Type::Map;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::Duration> {
  static const Type enum_value = Type::Duration;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::LargeBinary> {
  static const Type enum_value = Type::LargeBinary;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::LargeUtf8> {
  static const Type enum_value = Type::LargeUtf8;
};

template<> struct TypeTraits<org::apache::arrow::flatbuf::LargeList> {
  static const Type enum_value = Type::LargeList;
};

bool VerifyType(flatbuffers::Verifier &verifier, const void *obj, Type type);
bool VerifyTypeVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);

/// ----------------------------------------------------------------------
/// Dictionary encoding metadata
/// Maintained for forwards compatibility, in the future
/// Dictionaries might be explicit maps between integers and values
/// allowing for non-contiguous index values
enum class DictionaryKind : int16_t {
  DenseArray = 0,
  MIN = DenseArray,
  MAX = DenseArray
};

inline const DictionaryKind (&EnumValuesDictionaryKind())[1] {
  static const DictionaryKind values[] = {
    DictionaryKind::DenseArray
  };
  return values;
}

inline const char * const *EnumNamesDictionaryKind() {
  static const char * const names[2] = {
    "DenseArray",
    nullptr
  };
  return names;
}

inline const char *EnumNameDictionaryKind(DictionaryKind e) {
  if (flatbuffers::IsOutRange(e, DictionaryKind::DenseArray, DictionaryKind::DenseArray)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesDictionaryKind()[index];
}

/// ----------------------------------------------------------------------
/// Endianness of the platform producing the data
enum class Endianness : int16_t {
  Little = 0,
  Big = 1,
  MIN = Little,
  MAX = Big
};

inline const Endianness (&EnumValuesEndianness())[2] {
  static const Endianness values[] = {
    Endianness::Little,
    Endianness::Big
  };
  return values;
}

inline const char * const *EnumNamesEndianness() {
  static const char * const names[3] = {
    "Little",
    "Big",
    nullptr
  };
  return names;
}

inline const char *EnumNameEndianness(Endianness e) {
  if (flatbuffers::IsOutRange(e, Endianness::Little, Endianness::Big)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesEndianness()[index];
}

/// ----------------------------------------------------------------------
/// A Buffer represents a single contiguous memory segment
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Buffer FLATBUFFERS_FINAL_CLASS {
 private:
  int64_t offset_;
  int64_t length_;

 public:
  Buffer() {
    memset(static_cast<void *>(this), 0, sizeof(Buffer));
  }
  Buffer(int64_t _offset, int64_t _length)
      : offset_(flatbuffers::EndianScalar(_offset)),
        length_(flatbuffers::EndianScalar(_length)) {
  }
  /// The relative offset into the shared memory page where the bytes for this
  /// buffer starts
  int64_t offset() const {
    return flatbuffers::EndianScalar(offset_);
  }
  /// The absolute length (in bytes) of the memory buffer. The memory is found
  /// from offset (inclusive) to offset + length (non-inclusive). When building
  /// messages using the encapsulated IPC message, padding bytes may be written
  /// after a buffer, but such padding bytes do not need to be accounted for in
  /// the size here.
  int64_t length() const {
    return flatbuffers::EndianScalar(length_);
  }
};
FLATBUFFERS_STRUCT_END(Buffer, 16);

/// These are stored in the flatbuffer in the Type union below
struct Null FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef NullBuilder Builder;
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

struct NullBuilder {
  typedef Null Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  explicit NullBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  NullBuilder &operator=(const NullBuilder &);
  flatbuffers::Offset<Null> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Null>(end);
    return o;
  }
};

inline flatbuffers::Offset<Null> CreateNull(
    flatbuffers::FlatBufferBuilder &_fbb) {
  NullBuilder builder_(_fbb);
  return builder_.Finish();
}

/// A Struct_ in the flatbuffer metadata is the same as an Arrow Struct
/// (according to the physical memory layout). We used Struct_ here as
/// Struct is a reserved word in Flatbuffers
struct Struct_ FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef Struct_Builder Builder;
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

struct Struct_Builder {
  typedef Struct_ Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  explicit Struct_Builder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  Struct_Builder &operator=(const Struct_Builder &);
  flatbuffers::Offset<Struct_> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Struct_>(end);
    return o;
  }
};

inline flatbuffers::Offset<Struct_> CreateStruct_(
    flatbuffers::FlatBufferBuilder &_fbb) {
  Struct_Builder builder_(_fbb);
  return builder_.Finish();
}

struct List FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ListBuilder Builder;
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

struct ListBuilder {
  typedef List Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  explicit ListBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ListBuilder &operator=(const ListBuilder &);
  flatbuffers::Offset<List> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<List>(end);
    return o;
  }
};

inline flatbuffers::Offset<List> CreateList(
    flatbuffers::FlatBufferBuilder &_fbb) {
  ListBuilder builder_(_fbb);
  return builder_.Finish();
}

/// Same as List, but with 64-bit offsets, allowing to represent
/// extremely large data values.
struct LargeList FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LargeListBuilder Builder;
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

struct LargeListBuilder {
  typedef LargeList Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  explicit LargeListBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LargeListBuilder &operator=(const LargeListBuilder &);
  flatbuffers::Offset<LargeList> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LargeList>(end);
    return o;
  }
};

inline flatbuffers::Offset<LargeList> CreateLargeList(
    flatbuffers::FlatBufferBuilder &_fbb) {
  LargeListBuilder builder_(_fbb);
  return builder_.Finish();
}

struct FixedSizeList FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FixedSizeListBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_LISTSIZE = 4
  };
  /// Number of list items per value
  int32_t listSize() const {
    return GetField<int32_t>(VT_LISTSIZE, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_LISTSIZE) &&
           verifier.EndTable();
  }
};

struct FixedSizeListBuilder {
  typedef FixedSizeList Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_listSize(int32_t listSize) {
    fbb_.AddElement<int32_t>(FixedSizeList::VT_LISTSIZE, listSize, 0);
  }
  explicit FixedSizeListBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FixedSizeListBuilder &operator=(const FixedSizeListBuilder &);
  flatbuffers::Offset<FixedSizeList> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FixedSizeList>(end);
    return o;
  }
};

inline flatbuffers::Offset<FixedSizeList> CreateFixedSizeList(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t listSize = 0) {
  FixedSizeListBuilder builder_(_fbb);
  builder_.add_listSize(listSize);
  return builder_.Finish();
}

/// A Map is a logical nested type that is represented as
///
/// List<entries: Struct<key: K, value: V>>
///
/// In this layout, the keys and values are each respectively contiguous. We do
/// not constrain the key and value types, so the application is responsible
/// for ensuring that the keys are hashable and unique. Whether the keys are sorted
/// may be set in the metadata for this field.
///
/// In a field with Map type, the field has a child Struct field, which then
/// has two children: key type and the second the value type. The names of the
/// child fields may be respectively "entries", "key", and "value", but this is
/// not enforced.
///
/// Map
/// ```text
///   - child[0] entries: Struct
///     - child[0] key: K
///     - child[1] value: V
/// ```
/// Neither the "entries" field nor the "key" field may be nullable.
///
/// The metadata is structured so that Arrow systems without special handling
/// for Map can make Map an alias for List. The "layout" attribute for the Map
/// field must have the same contents as a List.
struct Map FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef MapBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_KEYSSORTED = 4
  };
  /// Set to true if the keys within each value are sorted
  bool keysSorted() const {
    return GetField<uint8_t>(VT_KEYSSORTED, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_KEYSSORTED) &&
           verifier.EndTable();
  }
};

struct MapBuilder {
  typedef Map Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_keysSorted(bool keysSorted) {
    fbb_.AddElement<uint8_t>(Map::VT_KEYSSORTED, static_cast<uint8_t>(keysSorted), 0);
  }
  explicit MapBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  MapBuilder &operator=(const MapBuilder &);
  flatbuffers::Offset<Map> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Map>(end);
    return o;
  }
};

inline flatbuffers::Offset<Map> CreateMap(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool keysSorted = false) {
  MapBuilder builder_(_fbb);
  builder_.add_keysSorted(keysSorted);
  return builder_.Finish();
}

/// A union is a complex type with children in Field
/// By default ids in the type vector refer to the offsets in the children
/// optionally typeIds provides an indirection between the child offset and the type id
/// for each child `typeIds[offset]` is the id used in the type vector
struct Union FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef UnionBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_MODE = 4,
    VT_TYPEIDS = 6
  };
  org::apache::arrow::flatbuf::UnionMode mode() const {
    return static_cast<org::apache::arrow::flatbuf::UnionMode>(GetField<int16_t>(VT_MODE, 0));
  }
  const flatbuffers::Vector<int32_t> *typeIds() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_TYPEIDS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int16_t>(verifier, VT_MODE) &&
           VerifyOffset(verifier, VT_TYPEIDS) &&
           verifier.VerifyVector(typeIds()) &&
           verifier.EndTable();
  }
};

struct UnionBuilder {
  typedef Union Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_mode(org::apache::arrow::flatbuf::UnionMode mode) {
    fbb_.AddElement<int16_t>(Union::VT_MODE, static_cast<int16_t>(mode), 0);
  }
  void add_typeIds(flatbuffers::Offset<flatbuffers::Vector<int32_t>> typeIds) {
    fbb_.AddOffset(Union::VT_TYPEIDS, typeIds);
  }
  explicit UnionBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  UnionBuilder &operator=(const UnionBuilder &);
  flatbuffers::Offset<Union> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Union>(end);
    return o;
  }
};

inline flatbuffers::Offset<Union> CreateUnion(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::flatbuf::UnionMode mode = org::apache::arrow::flatbuf::UnionMode::Sparse,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> typeIds = 0) {
  UnionBuilder builder_(_fbb);
  builder_.add_typeIds(typeIds);
  builder_.add_mode(mode);
  return builder_.Finish();
}

inline flatbuffers::Offset<Union> CreateUnionDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::flatbuf::UnionMode mode = org::apache::arrow::flatbuf::UnionMode::Sparse,
    const std::vector<int32_t> *typeIds = nullptr) {
  auto typeIds__ = typeIds ? _fbb.CreateVector<int32_t>(*typeIds) : 0;
  return org::apache::arrow::flatbuf::CreateUnion(
      _fbb,
      mode,
      typeIds__);
}

struct Int FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef IntBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BITWIDTH = 4,
    VT_IS_SIGNED = 6
  };
  int32_t bitWidth() const {
    return GetField<int32_t>(VT_BITWIDTH, 0);
  }
  bool is_signed() const {
    return GetField<uint8_t>(VT_IS_SIGNED, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_BITWIDTH) &&
           VerifyField<uint8_t>(verifier, VT_IS_SIGNED) &&
           verifier.EndTable();
  }
};

struct IntBuilder {
  typedef Int Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_bitWidth(int32_t bitWidth) {
    fbb_.AddElement<int32_t>(Int::VT_BITWIDTH, bitWidth, 0);
  }
  void add_is_signed(bool is_signed) {
    fbb_.AddElement<uint8_t>(Int::VT_IS_SIGNED, static_cast<uint8_t>(is_signed), 0);
  }
  explicit IntBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  IntBuilder &operator=(const IntBuilder &);
  flatbuffers::Offset<Int> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Int>(end);
    return o;
  }
};

inline flatbuffers::Offset<Int> CreateInt(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t bitWidth = 0,
    bool is_signed = false) {
  IntBuilder builder_(_fbb);
  builder_.add_bitWidth(bitWidth);
  builder_.add_is_signed(is_signed);
  return builder_.Finish();
}

struct FloatingPoint FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FloatingPointBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PRECISION = 4
  };
  org::apache::arrow::flatbuf::Precision precision() const {
    return static_cast<org::apache::arrow::flatbuf::Precision>(GetField<int16_t>(VT_PRECISION, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int16_t>(verifier, VT_PRECISION) &&
           verifier.EndTable();
  }
};

struct FloatingPointBuilder {
  typedef FloatingPoint Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_precision(org::apache::arrow::flatbuf::Precision precision) {
    fbb_.AddElement<int16_t>(FloatingPoint::VT_PRECISION, static_cast<int16_t>(precision), 0);
  }
  explicit FloatingPointBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FloatingPointBuilder &operator=(const FloatingPointBuilder &);
  flatbuffers::Offset<FloatingPoint> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FloatingPoint>(end);
    return o;
  }
};

inline flatbuffers::Offset<FloatingPoint> CreateFloatingPoint(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::flatbuf::Precision precision = org::apache::arrow::flatbuf::Precision::HALF) {
  FloatingPointBuilder builder_(_fbb);
  builder_.add_precision(precision);
  return builder_.Finish();
}

/// Unicode with UTF-8 encoding
struct Utf8 FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef Utf8Builder Builder;
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

struct Utf8Builder {
  typedef Utf8 Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  explicit Utf8Builder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  Utf8Builder &operator=(const Utf8Builder &);
  flatbuffers::Offset<Utf8> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Utf8>(end);
    return o;
  }
};

inline flatbuffers::Offset<Utf8> CreateUtf8(
    flatbuffers::FlatBufferBuilder &_fbb) {
  Utf8Builder builder_(_fbb);
  return builder_.Finish();
}

/// Opaque binary data
struct Binary FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef BinaryBuilder Builder;
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

struct BinaryBuilder {
  typedef Binary Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  explicit BinaryBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BinaryBuilder &operator=(const BinaryBuilder &);
  flatbuffers::Offset<Binary> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Binary>(end);
    return o;
  }
};

inline flatbuffers::Offset<Binary> CreateBinary(
    flatbuffers::FlatBufferBuilder &_fbb) {
  BinaryBuilder builder_(_fbb);
  return builder_.Finish();
}

/// Same as Utf8, but with 64-bit offsets, allowing to represent
/// extremely large data values.
struct LargeUtf8 FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LargeUtf8Builder Builder;
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

struct LargeUtf8Builder {
  typedef LargeUtf8 Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  explicit LargeUtf8Builder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LargeUtf8Builder &operator=(const LargeUtf8Builder &);
  flatbuffers::Offset<LargeUtf8> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LargeUtf8>(end);
    return o;
  }
};

inline flatbuffers::Offset<LargeUtf8> CreateLargeUtf8(
    flatbuffers::FlatBufferBuilder &_fbb) {
  LargeUtf8Builder builder_(_fbb);
  return builder_.Finish();
}

/// Same as Binary, but with 64-bit offsets, allowing to represent
/// extremely large data values.
struct LargeBinary FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LargeBinaryBuilder Builder;
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

struct LargeBinaryBuilder {
  typedef LargeBinary Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  explicit LargeBinaryBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LargeBinaryBuilder &operator=(const LargeBinaryBuilder &);
  flatbuffers::Offset<LargeBinary> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LargeBinary>(end);
    return o;
  }
};

inline flatbuffers::Offset<LargeBinary> CreateLargeBinary(
    flatbuffers::FlatBufferBuilder &_fbb) {
  LargeBinaryBuilder builder_(_fbb);
  return builder_.Finish();
}

struct FixedSizeBinary FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FixedSizeBinaryBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_BYTEWIDTH = 4
  };
  /// Number of bytes per value
  int32_t byteWidth() const {
    return GetField<int32_t>(VT_BYTEWIDTH, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_BYTEWIDTH) &&
           verifier.EndTable();
  }
};

struct FixedSizeBinaryBuilder {
  typedef FixedSizeBinary Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_byteWidth(int32_t byteWidth) {
    fbb_.AddElement<int32_t>(FixedSizeBinary::VT_BYTEWIDTH, byteWidth, 0);
  }
  explicit FixedSizeBinaryBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FixedSizeBinaryBuilder &operator=(const FixedSizeBinaryBuilder &);
  flatbuffers::Offset<FixedSizeBinary> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FixedSizeBinary>(end);
    return o;
  }
};

inline flatbuffers::Offset<FixedSizeBinary> CreateFixedSizeBinary(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t byteWidth = 0) {
  FixedSizeBinaryBuilder builder_(_fbb);
  builder_.add_byteWidth(byteWidth);
  return builder_.Finish();
}

struct Bool FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef BoolBuilder Builder;
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

struct BoolBuilder {
  typedef Bool Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  explicit BoolBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BoolBuilder &operator=(const BoolBuilder &);
  flatbuffers::Offset<Bool> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Bool>(end);
    return o;
  }
};

inline flatbuffers::Offset<Bool> CreateBool(
    flatbuffers::FlatBufferBuilder &_fbb) {
  BoolBuilder builder_(_fbb);
  return builder_.Finish();
}

/// Exact decimal value represented as an integer value in two's
/// complement. Currently only 128-bit (16-byte) and 256-bit (32-byte) integers
/// are used. The representation uses the endianness indicated
/// in the Schema.
struct Decimal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DecimalBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_PRECISION = 4,
    VT_SCALE = 6,
    VT_BITWIDTH = 8
  };
  /// Total number of decimal digits
  int32_t precision() const {
    return GetField<int32_t>(VT_PRECISION, 0);
  }
  /// Number of digits after the decimal point "."
  int32_t scale() const {
    return GetField<int32_t>(VT_SCALE, 0);
  }
  /// Number of bits per value. The only accepted widths are 128 and 256.
  /// We use bitWidth for consistency with Int::bitWidth.
  int32_t bitWidth() const {
    return GetField<int32_t>(VT_BITWIDTH, 128);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_PRECISION) &&
           VerifyField<int32_t>(verifier, VT_SCALE) &&
           VerifyField<int32_t>(verifier, VT_BITWIDTH) &&
           verifier.EndTable();
  }
};

struct DecimalBuilder {
  typedef Decimal Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_precision(int32_t precision) {
    fbb_.AddElement<int32_t>(Decimal::VT_PRECISION, precision, 0);
  }
  void add_scale(int32_t scale) {
    fbb_.AddElement<int32_t>(Decimal::VT_SCALE, scale, 0);
  }
  void add_bitWidth(int32_t bitWidth) {
    fbb_.AddElement<int32_t>(Decimal::VT_BITWIDTH, bitWidth, 128);
  }
  explicit DecimalBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DecimalBuilder &operator=(const DecimalBuilder &);
  flatbuffers::Offset<Decimal> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Decimal>(end);
    return o;
  }
};

inline flatbuffers::Offset<Decimal> CreateDecimal(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t precision = 0,
    int32_t scale = 0,
    int32_t bitWidth = 128) {
  DecimalBuilder builder_(_fbb);
  builder_.add_bitWidth(bitWidth);
  builder_.add_scale(scale);
  builder_.add_precision(precision);
  return builder_.Finish();
}

/// Date is either a 32-bit or 64-bit signed integer type representing an
/// elapsed time since UNIX epoch (1970-01-01), stored in either of two units:
///
/// * Milliseconds (64 bits) indicating UNIX time elapsed since the epoch (no
///   leap seconds), where the values are evenly divisible by 86400000
/// * Days (32 bits) since the UNIX epoch
struct Date FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DateBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_UNIT = 4
  };
  org::apache::arrow::flatbuf::DateUnit unit() const {
    return static_cast<org::apache::arrow::flatbuf::DateUnit>(GetField<int16_t>(VT_UNIT, 1));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int16_t>(verifier, VT_UNIT) &&
           verifier.EndTable();
  }
};

struct DateBuilder {
  typedef Date Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_unit(org::apache::arrow::flatbuf::DateUnit unit) {
    fbb_.AddElement<int16_t>(Date::VT_UNIT, static_cast<int16_t>(unit), 1);
  }
  explicit DateBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DateBuilder &operator=(const DateBuilder &);
  flatbuffers::Offset<Date> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Date>(end);
    return o;
  }
};

inline flatbuffers::Offset<Date> CreateDate(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::flatbuf::DateUnit unit = org::apache::arrow::flatbuf::DateUnit::MILLISECOND) {
  DateBuilder builder_(_fbb);
  builder_.add_unit(unit);
  return builder_.Finish();
}

/// Time is either a 32-bit or 64-bit signed integer type representing an
/// elapsed time since midnight, stored in either of four units: seconds,
/// milliseconds, microseconds or nanoseconds.
///
/// The integer `bitWidth` depends on the `unit` and must be one of the following:
/// * SECOND and MILLISECOND: 32 bits
/// * MICROSECOND and NANOSECOND: 64 bits
///
/// The allowed values are between 0 (inclusive) and 86400 (=24*60*60) seconds
/// (exclusive), adjusted for the time unit (for example, up to 86400000
/// exclusive for the MILLISECOND unit).
/// This definition doesn't allow for leap seconds. Time values from
/// measurements with leap seconds will need to be corrected when ingesting
/// into Arrow (for example by replacing the value 86400 with 86399).
struct Time FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TimeBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_UNIT = 4,
    VT_BITWIDTH = 6
  };
  org::apache::arrow::flatbuf::TimeUnit unit() const {
    return static_cast<org::apache::arrow::flatbuf::TimeUnit>(GetField<int16_t>(VT_UNIT, 1));
  }
  int32_t bitWidth() const {
    return GetField<int32_t>(VT_BITWIDTH, 32);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int16_t>(verifier, VT_UNIT) &&
           VerifyField<int32_t>(verifier, VT_BITWIDTH) &&
           verifier.EndTable();
  }
};

struct TimeBuilder {
  typedef Time Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_unit(org::apache::arrow::flatbuf::TimeUnit unit) {
    fbb_.AddElement<int16_t>(Time::VT_UNIT, static_cast<int16_t>(unit), 1);
  }
  void add_bitWidth(int32_t bitWidth) {
    fbb_.AddElement<int32_t>(Time::VT_BITWIDTH, bitWidth, 32);
  }
  explicit TimeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TimeBuilder &operator=(const TimeBuilder &);
  flatbuffers::Offset<Time> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Time>(end);
    return o;
  }
};

inline flatbuffers::Offset<Time> CreateTime(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::flatbuf::TimeUnit unit = org::apache::arrow::flatbuf::TimeUnit::MILLISECOND,
    int32_t bitWidth = 32) {
  TimeBuilder builder_(_fbb);
  builder_.add_bitWidth(bitWidth);
  builder_.add_unit(unit);
  return builder_.Finish();
}

/// Timestamp is a 64-bit signed integer representing an elapsed time since a
/// fixed epoch, stored in either of four units: seconds, milliseconds,
/// microseconds or nanoseconds, and is optionally annotated with a timezone.
///
/// Timestamp values do not include any leap seconds (in other words, all
/// days are considered 86400 seconds long).
///
/// Timestamps with a non-empty timezone
/// ------------------------------------
///
/// If a Timestamp column has a non-empty timezone value, its epoch is
/// 1970-01-01 00:00:00 (January 1st 1970, midnight) in the *UTC* timezone
/// (the Unix epoch), regardless of the Timestamp's own timezone.
///
/// Therefore, timestamp values with a non-empty timezone correspond to
/// physical points in time together with some additional information about
/// how the data was obtained and/or how to display it (the timezone).
///
///   For example, the timestamp value 0 with the timezone string "Europe/Paris"
///   corresponds to "January 1st 1970, 00h00" in the UTC timezone, but the
///   application may prefer to display it as "January 1st 1970, 01h00" in
///   the Europe/Paris timezone (which is the same physical point in time).
///
/// One consequence is that timestamp values with a non-empty timezone
/// can be compared and ordered directly, since they all share the same
/// well-known point of reference (the Unix epoch).
///
/// Timestamps with an unset / empty timezone
/// -----------------------------------------
///
/// If a Timestamp column has no timezone value, its epoch is
/// 1970-01-01 00:00:00 (January 1st 1970, midnight) in an *unknown* timezone.
///
/// Therefore, timestamp values without a timezone cannot be meaningfully
/// interpreted as physical points in time, but only as calendar / clock
/// indications ("wall clock time") in an unspecified timezone.
///
///   For example, the timestamp value 0 with an empty timezone string
///   corresponds to "January 1st 1970, 00h00" in an unknown timezone: there
///   is not enough information to interpret it as a well-defined physical
///   point in time.
///
/// One consequence is that timestamp values without a timezone cannot
/// be reliably compared or ordered, since they may have different points of
/// reference.  In particular, it is *not* possible to interpret an unset
/// or empty timezone as the same as "UTC".
///
/// Conversion between timezones
/// ----------------------------
///
/// If a Timestamp column has a non-empty timezone, changing the timezone
/// to a different non-empty value is a metadata-only operation:
/// the timestamp values need not change as their point of reference remains
/// the same (the Unix epoch).
///
/// However, if a Timestamp column has no timezone value, changing it to a
/// non-empty value requires to think about the desired semantics.
/// One possibility is to assume that the original timestamp values are
/// relative to the epoch of the timezone being set; timestamp values should
/// then adjusted to the Unix epoch (for example, changing the timezone from
/// empty to "Europe/Paris" would require converting the timestamp values
/// from "Europe/Paris" to "UTC", which seems counter-intuitive but is
/// nevertheless correct).
///
/// Guidelines for encoding data from external libraries
/// ----------------------------------------------------
///
/// Date & time libraries often have multiple different data types for temporal
/// data. In order to ease interoperability between different implementations the
/// Arrow project has some recommendations for encoding these types into a Timestamp
/// column.
///
/// An "instant" represents a physical point in time that has no relevant timezone
/// (for example, astronomical data). To encode an instant, use a Timestamp with
/// the timezone string set to "UTC", and make sure the Timestamp values
/// are relative to the UTC epoch (January 1st 1970, midnight).
///
/// A "zoned date-time" represents a physical point in time annotated with an
/// informative timezone (for example, the timezone in which the data was
/// recorded).  To encode a zoned date-time, use a Timestamp with the timezone
/// string set to the name of the timezone, and make sure the Timestamp values
/// are relative to the UTC epoch (January 1st 1970, midnight).
///
///  (There is some ambiguity between an instant and a zoned date-time with the
///   UTC timezone.  Both of these are stored the same in Arrow.  Typically,
///   this distinction does not matter.  If it does, then an application should
///   use custom metadata or an extension type to distinguish between the two cases.)
///
/// An "offset date-time" represents a physical point in time combined with an
/// explicit offset from UTC.  To encode an offset date-time, use a Timestamp
/// with the timezone string set to the numeric timezone offset string
/// (e.g. "+03:00"), and make sure the Timestamp values are relative to
/// the UTC epoch (January 1st 1970, midnight).
///
/// A "naive date-time" (also called "local date-time" in some libraries)
/// represents a wall clock time combined with a calendar date, but with
/// no indication of how to map this information to a physical point in time.
/// Naive date-times must be handled with care because of this missing
/// information, and also because daylight saving time (DST) may make
/// some values ambiguous or non-existent. A naive date-time may be
/// stored as a struct with Date and Time fields. However, it may also be
/// encoded into a Timestamp column with an empty timezone. The timestamp
/// values should be computed "as if" the timezone of the date-time values
/// was UTC; for example, the naive date-time "January 1st 1970, 00h00" would
/// be encoded as timestamp value 0.
struct Timestamp FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TimestampBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_UNIT = 4,
    VT_TIMEZONE = 6
  };
  org::apache::arrow::flatbuf::TimeUnit unit() const {
    return static_cast<org::apache::arrow::flatbuf::TimeUnit>(GetField<int16_t>(VT_UNIT, 0));
  }
  /// The timezone is an optional string indicating the name of a timezone,
  /// one of:
  ///
  /// * As used in the Olson timezone database (the "tz database" or
  ///   "tzdata"), such as "America/New_York".
  /// * An absolute timezone offset of the form "+XX:XX" or "-XX:XX",
  ///   such as "+07:30".
  ///
  /// Whether a timezone string is present indicates different semantics about
  /// the data (see above).
  const flatbuffers::String *timezone() const {
    return GetPointer<const flatbuffers::String *>(VT_TIMEZONE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int16_t>(verifier, VT_UNIT) &&
           VerifyOffset(verifier, VT_TIMEZONE) &&
           verifier.VerifyString(timezone()) &&
           verifier.EndTable();
  }
};

struct TimestampBuilder {
  typedef Timestamp Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_unit(org::apache::arrow::flatbuf::TimeUnit unit) {
    fbb_.AddElement<int16_t>(Timestamp::VT_UNIT, static_cast<int16_t>(unit), 0);
  }
  void add_timezone(flatbuffers::Offset<flatbuffers::String> timezone) {
    fbb_.AddOffset(Timestamp::VT_TIMEZONE, timezone);
  }
  explicit TimestampBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TimestampBuilder &operator=(const TimestampBuilder &);
  flatbuffers::Offset<Timestamp> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Timestamp>(end);
    return o;
  }
};

inline flatbuffers::Offset<Timestamp> CreateTimestamp(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::flatbuf::TimeUnit unit = org::apache::arrow::flatbuf::TimeUnit::SECOND,
    flatbuffers::Offset<flatbuffers::String> timezone = 0) {
  TimestampBuilder builder_(_fbb);
  builder_.add_timezone(timezone);
  builder_.add_unit(unit);
  return builder_.Finish();
}

inline flatbuffers::Offset<Timestamp> CreateTimestampDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::flatbuf::TimeUnit unit = org::apache::arrow::flatbuf::TimeUnit::SECOND,
    const char *timezone = nullptr) {
  auto timezone__ = timezone ? _fbb.CreateString(timezone) : 0;
  return org::apache::arrow::flatbuf::CreateTimestamp(
      _fbb,
      unit,
      timezone__);
}

struct Interval FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef IntervalBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_UNIT = 4
  };
  org::apache::arrow::flatbuf::IntervalUnit unit() const {
    return static_cast<org::apache::arrow::flatbuf::IntervalUnit>(GetField<int16_t>(VT_UNIT, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int16_t>(verifier, VT_UNIT) &&
           verifier.EndTable();
  }
};

struct IntervalBuilder {
  typedef Interval Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_unit(org::apache::arrow::flatbuf::IntervalUnit unit) {
    fbb_.AddElement<int16_t>(Interval::VT_UNIT, static_cast<int16_t>(unit), 0);
  }
  explicit IntervalBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  IntervalBuilder &operator=(const IntervalBuilder &);
  flatbuffers::Offset<Interval> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Interval>(end);
    return o;
  }
};

inline flatbuffers::Offset<Interval> CreateInterval(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::flatbuf::IntervalUnit unit = org::apache::arrow::flatbuf::IntervalUnit::YEAR_MONTH) {
  IntervalBuilder builder_(_fbb);
  builder_.add_unit(unit);
  return builder_.Finish();
}

struct Duration FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DurationBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_UNIT = 4
  };
  org::apache::arrow::flatbuf::TimeUnit unit() const {
    return static_cast<org::apache::arrow::flatbuf::TimeUnit>(GetField<int16_t>(VT_UNIT, 1));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int16_t>(verifier, VT_UNIT) &&
           verifier.EndTable();
  }
};

struct DurationBuilder {
  typedef Duration Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_unit(org::apache::arrow::flatbuf::TimeUnit unit) {
    fbb_.AddElement<int16_t>(Duration::VT_UNIT, static_cast<int16_t>(unit), 1);
  }
  explicit DurationBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DurationBuilder &operator=(const DurationBuilder &);
  flatbuffers::Offset<Duration> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Duration>(end);
    return o;
  }
};

inline flatbuffers::Offset<Duration> CreateDuration(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::flatbuf::TimeUnit unit = org::apache::arrow::flatbuf::TimeUnit::MILLISECOND) {
  DurationBuilder builder_(_fbb);
  builder_.add_unit(unit);
  return builder_.Finish();
}

/// ----------------------------------------------------------------------
/// user defined key value pairs to add custom metadata to arrow
/// key namespacing is the responsibility of the user
struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef KeyValueBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_KEY = 4,
    VT_VALUE = 6
  };
  const flatbuffers::String *key() const {
    return GetPointer<const flatbuffers::String *>(VT_KEY);
  }
  const flatbuffers::String *value() const {
    return GetPointer<const flatbuffers::String *>(VT_VALUE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_KEY) &&
           verifier.VerifyString(key()) &&
           VerifyOffset(verifier, VT_VALUE) &&
           verifier.VerifyString(value()) &&
           verifier.EndTable();
  }
};

struct KeyValueBuilder {
  typedef KeyValue Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_key(flatbuffers::Offset<flatbuffers::String> key) {
    fbb_.AddOffset(KeyValue::VT_KEY, key);
  }
  void add_value(flatbuffers::Offset<flatbuffers::String> value) {
    fbb_.AddOffset(KeyValue::VT_VALUE, value);
  }
  explicit KeyValueBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  KeyValueBuilder &operator=(const KeyValueBuilder &);
  flatbuffers::Offset<KeyValue> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<KeyValue>(end);
    return o;
  }
};

inline flatbuffers::Offset<KeyValue> CreateKeyValue(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> key = 0,
    flatbuffers::Offset<flatbuffers::String> value = 0) {
  KeyValueBuilder builder_(_fbb);
  builder_.add_value(value);
  builder_.add_key(key);
  return builder_.Finish();
}

inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *key = nullptr,
    const char *value = nullptr) {
  auto key__ = key ? _fbb.CreateString(key) : 0;
  auto value__ = value ? _fbb.CreateString(value) : 0;
  return org::apache::arrow::flatbuf::CreateKeyValue(
      _fbb,
      key__,
      value__);
}

struct DictionaryEncoding FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DictionaryEncodingBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ID = 4,
    VT_INDEXTYPE = 6,
    VT_ISORDERED = 8,
    VT_DICTIONARYKIND = 10
  };
  /// The known dictionary id in the application where this data is used. In
  /// the file or streaming formats, the dictionary ids are found in the
  /// DictionaryBatch messages
  int64_t id() const {
    return GetField<int64_t>(VT_ID, 0);
  }
  /// The dictionary indices are constrained to be non-negative integers. If
  /// this field is null, the indices must be signed int32. To maximize
  /// cross-language compatibility and performance, implementations are
  /// recommended to prefer signed integer types over unsigned integer types
  /// and to avoid uint64 indices unless they are required by an application.
  const org::apache::arrow::flatbuf::Int *indexType() const {
    return GetPointer<const org::apache::arrow::flatbuf::Int *>(VT_INDEXTYPE);
  }
  /// By default, dictionaries are not ordered, or the order does not have
  /// semantic meaning. In some statistical, applications, dictionary-encoding
  /// is used to represent ordered categorical data, and we provide a way to
  /// preserve that metadata here
  bool isOrdered() const {
    return GetField<uint8_t>(VT_ISORDERED, 0) != 0;
  }
  org::apache::arrow::flatbuf::DictionaryKind dictionaryKind() const {
    return static_cast<org::apache::arrow::flatbuf::DictionaryKind>(GetField<int16_t>(VT_DICTIONARYKIND, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int64_t>(verifier, VT_ID) &&
           VerifyOffset(verifier, VT_INDEXTYPE) &&
           verifier.VerifyTable(indexType()) &&
           VerifyField<uint8_t>(verifier, VT_ISORDERED) &&
           VerifyField<int16_t>(verifier, VT_DICTIONARYKIND) &&
           verifier.EndTable();
  }
};

struct DictionaryEncodingBuilder {
  typedef DictionaryEncoding Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_id(int64_t id) {
    fbb_.AddElement<int64_t>(DictionaryEncoding::VT_ID, id, 0);
  }
  void add_indexType(flatbuffers::Offset<org::apache::arrow::flatbuf::Int> indexType) {
    fbb_.AddOffset(DictionaryEncoding::VT_INDEXTYPE, indexType);
  }
  void add_isOrdered(bool isOrdered) {
    fbb_.AddElement<uint8_t>(DictionaryEncoding::VT_ISORDERED, static_cast<uint8_t>(isOrdered), 0);
  }
  void add_dictionaryKind(org::apache::arrow::flatbuf::DictionaryKind dictionaryKind) {
    fbb_.AddElement<int16_t>(DictionaryEncoding::VT_DICTIONARYKIND, static_cast<int16_t>(dictionaryKind), 0);
  }
  explicit DictionaryEncodingBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DictionaryEncodingBuilder &operator=(const DictionaryEncodingBuilder &);
  flatbuffers::Offset<DictionaryEncoding> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DictionaryEncoding>(end);
    return o;
  }
};

inline flatbuffers::Offset<DictionaryEncoding> CreateDictionaryEncoding(
    flatbuffers::FlatBufferBuilder &_fbb,
    int64_t id = 0,
    flatbuffers::Offset<org::apache::arrow::flatbuf::Int> indexType = 0,
    bool isOrdered = false,
    org::apache::arrow::flatbuf::DictionaryKind dictionaryKind = org::apache::arrow::flatbuf::DictionaryKind::DenseArray) {
  DictionaryEncodingBuilder builder_(_fbb);
  builder_.add_id(id);
  builder_.add_indexType(indexType);
  builder_.add_dictionaryKind(dictionaryKind);
  builder_.add_isOrdered(isOrdered);
  return builder_.Finish();
}

/// ----------------------------------------------------------------------
/// A field represents a named column in a record / row batch or child of a
/// nested type.
struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FieldBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_NAME = 4,
    VT_NULLABLE = 6,
    VT_TYPE_TYPE = 8,
    VT_TYPE = 10,
    VT_DICTIONARY = 12,
    VT_CHILDREN = 14,
    VT_CUSTOM_METADATA = 16
  };
  /// Name is not required, in i.e. a List
  const flatbuffers::String *name() const {
    return GetPointer<const flatbuffers::String *>(VT_NAME);
  }
  /// Whether or not this field can contain nulls. Should be true in general.
  bool nullable() const {
    return GetField<uint8_t>(VT_NULLABLE, 0) != 0;
  }
  org::apache::arrow::flatbuf::Type type_type() const {
    return static_cast<org::apache::arrow::flatbuf::Type>(GetField<uint8_t>(VT_TYPE_TYPE, 0));
  }
  /// This is the type of the decoded value if the field is dictionary encoded.
  const void *type() const {
    return GetPointer<const void *>(VT_TYPE);
  }
  template<typename T> const T *type_as() const;
  const org::apache::arrow::flatbuf::Null *type_as_Null() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Null ? static_cast<const org::apache::arrow::flatbuf::Null *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Int *type_as_Int() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Int ? static_cast<const org::apache::arrow::flatbuf::Int *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::FloatingPoint *type_as_FloatingPoint() const {
    return type_type() == org::apache::arrow::flatbuf::Type::FloatingPoint ? static_cast<const org::apache::arrow::flatbuf::FloatingPoint *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Binary *type_as_Binary() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Binary ? static_cast<const org::apache::arrow::flatbuf::Binary *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Utf8 *type_as_Utf8() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Utf8 ? static_cast<const org::apache::arrow::flatbuf::Utf8 *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Bool *type_as_Bool() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Bool ? static_cast<const org::apache::arrow::flatbuf::Bool *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Decimal *type_as_Decimal() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Decimal ? static_cast<const org::apache::arrow::flatbuf::Decimal *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Date *type_as_Date() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Date ? static_cast<const org::apache::arrow::flatbuf::Date *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Time *type_as_Time() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Time ? static_cast<const org::apache::arrow::flatbuf::Time *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Timestamp *type_as_Timestamp() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Timestamp ? static_cast<const org::apache::arrow::flatbuf::Timestamp *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Interval *type_as_Interval() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Interval ? static_cast<const org::apache::arrow::flatbuf::Interval *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::List *type_as_List() const {
    return type_type() == org::apache::arrow::flatbuf::Type::List ? static_cast<const org::apache::arrow::flatbuf::List *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Struct_ *type_as_Struct_() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Struct_ ? static_cast<const org::apache::arrow::flatbuf::Struct_ *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Union *type_as_Union() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Union ? static_cast<const org::apache::arrow::flatbuf::Union *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::FixedSizeBinary *type_as_FixedSizeBinary() const {
    return type_type() == org::apache::arrow::flatbuf::Type::FixedSizeBinary ? static_cast<const org::apache::arrow::flatbuf::FixedSizeBinary *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::FixedSizeList *type_as_FixedSizeList() const {
    return type_type() == org::apache::arrow::flatbuf::Type::FixedSizeList ? static_cast<const org::apache::arrow::flatbuf::FixedSizeList *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Map *type_as_Map() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Map ? static_cast<const org::apache::arrow::flatbuf::Map *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Duration *type_as_Duration() const {
    return type_type() == org::apache::arrow::flatbuf::Type::Duration ? static_cast<const org::apache::arrow::flatbuf::Duration *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::LargeBinary *type_as_LargeBinary() const {
    return type_type() == org::apache::arrow::flatbuf::Type::LargeBinary ? static_cast<const org::apache::arrow::flatbuf::LargeBinary *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::LargeUtf8 *type_as_LargeUtf8() const {
    return type_type() == org::apache::arrow::flatbuf::Type::LargeUtf8 ? static_cast<const org::apache::arrow::flatbuf::LargeUtf8 *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::LargeList *type_as_LargeList() const {
    return type_type() == org::apache::arrow::flatbuf::Type::LargeList ? static_cast<const org::apache::arrow::flatbuf::LargeList *>(type()) : nullptr;
  }
  /// Present only if the field is dictionary encoded.
  const org::apache::arrow::flatbuf::DictionaryEncoding *dictionary() const {
    return GetPointer<const org::apache::arrow::flatbuf::DictionaryEncoding *>(VT_DICTIONARY);
  }
  /// children apply only to nested data types like Struct, List and Union. For
  /// primitive types children will have length 0.
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>> *children() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>> *>(VT_CHILDREN);
  }
  /// User-defined metadata
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>> *custom_metadata() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>> *>(VT_CUSTOM_METADATA);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_NAME) &&
           verifier.VerifyString(name()) &&
           VerifyField<uint8_t>(verifier, VT_NULLABLE) &&
           VerifyField<uint8_t>(verifier, VT_TYPE_TYPE) &&
           VerifyOffset(verifier, VT_TYPE) &&
           VerifyType(verifier, type(), type_type()) &&
           VerifyOffset(verifier, VT_DICTIONARY) &&
           verifier.VerifyTable(dictionary()) &&
           VerifyOffset(verifier, VT_CHILDREN) &&
           verifier.VerifyVector(children()) &&
           verifier.VerifyVectorOfTables(children()) &&
           VerifyOffset(verifier, VT_CUSTOM_METADATA) &&
           verifier.VerifyVector(custom_metadata()) &&
           verifier.VerifyVectorOfTables(custom_metadata()) &&
           verifier.EndTable();
  }
};

template<> inline const org::apache::arrow::flatbuf::Null *Field::type_as<org::apache::arrow::flatbuf::Null>() const {
  return type_as_Null();
}

template<> inline const org::apache::arrow::flatbuf::Int *Field::type_as<org::apache::arrow::flatbuf::Int>() const {
  return type_as_Int();
}

template<> inline const org::apache::arrow::flatbuf::FloatingPoint *Field::type_as<org::apache::arrow::flatbuf::FloatingPoint>() const {
  return type_as_FloatingPoint();
}

template<> inline const org::apache::arrow::flatbuf::Binary *Field::type_as<org::apache::arrow::flatbuf::Binary>() const {
  return type_as_Binary();
}

template<> inline const org::apache::arrow::flatbuf::Utf8 *Field::type_as<org::apache::arrow::flatbuf::Utf8>() const {
  return type_as_Utf8();
}

template<> inline const org::apache::arrow::flatbuf::Bool *Field::type_as<org::apache::arrow::flatbuf::Bool>() const {
  return type_as_Bool();
}

template<> inline const org::apache::arrow::flatbuf::Decimal *Field::type_as<org::apache::arrow::flatbuf::Decimal>() const {
  return type_as_Decimal();
}

template<> inline const org::apache::arrow::flatbuf::Date *Field::type_as<org::apache::arrow::flatbuf::Date>() const {
  return type_as_Date();
}

template<> inline const org::apache::arrow::flatbuf::Time *Field::type_as<org::apache::arrow::flatbuf::Time>() const {
  return type_as_Time();
}

template<> inline const org::apache::arrow::flatbuf::Timestamp *Field::type_as<org::apache::arrow::flatbuf::Timestamp>() const {
  return type_as_Timestamp();
}

template<> inline const org::apache::arrow::flatbuf::Interval *Field::type_as<org::apache::arrow::flatbuf::Interval>() const {
  return type_as_Interval();
}

template<> inline const org::apache::arrow::flatbuf::List *Field::type_as<org::apache::arrow::flatbuf::List>() const {
  return type_as_List();
}

template<> inline const org::apache::arrow::flatbuf::Struct_ *Field::type_as<org::apache::arrow::flatbuf::Struct_>() const {
  return type_as_Struct_();
}

template<> inline const org::apache::arrow::flatbuf::Union *Field::type_as<org::apache::arrow::flatbuf::Union>() const {
  return type_as_Union();
}

template<> inline const org::apache::arrow::flatbuf::FixedSizeBinary *Field::type_as<org::apache::arrow::flatbuf::FixedSizeBinary>() const {
  return type_as_FixedSizeBinary();
}

template<> inline const org::apache::arrow::flatbuf::FixedSizeList *Field::type_as<org::apache::arrow::flatbuf::FixedSizeList>() const {
  return type_as_FixedSizeList();
}

template<> inline const org::apache::arrow::flatbuf::Map *Field::type_as<org::apache::arrow::flatbuf::Map>() const {
  return type_as_Map();
}

template<> inline const org::apache::arrow::flatbuf::Duration *Field::type_as<org::apache::arrow::flatbuf::Duration>() const {
  return type_as_Duration();
}

template<> inline const org::apache::arrow::flatbuf::LargeBinary *Field::type_as<org::apache::arrow::flatbuf::LargeBinary>() const {
  return type_as_LargeBinary();
}

template<> inline const org::apache::arrow::flatbuf::LargeUtf8 *Field::type_as<org::apache::arrow::flatbuf::LargeUtf8>() const {
  return type_as_LargeUtf8();
}

template<> inline const org::apache::arrow::flatbuf::LargeList *Field::type_as<org::apache::arrow::flatbuf::LargeList>() const {
  return type_as_LargeList();
}

struct FieldBuilder {
  typedef Field Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
    fbb_.AddOffset(Field::VT_NAME, name);
  }
  void add_nullable(bool nullable) {
    fbb_.AddElement<uint8_t>(Field::VT_NULLABLE, static_cast<uint8_t>(nullable), 0);
  }
  void add_type_type(org::apache::arrow::flatbuf::Type type_type) {
    fbb_.AddElement<uint8_t>(Field::VT_TYPE_TYPE, static_cast<uint8_t>(type_type), 0);
  }
  void add_type(flatbuffers::Offset<void> type) {
    fbb_.AddOffset(Field::VT_TYPE, type);
  }
  void add_dictionary(flatbuffers::Offset<org::apache::arrow::flatbuf::DictionaryEncoding> dictionary) {
    fbb_.AddOffset(Field::VT_DICTIONARY, dictionary);
  }
  void add_children(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>>> children) {
    fbb_.AddOffset(Field::VT_CHILDREN, children);
  }
  void add_custom_metadata(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>>> custom_metadata) {
    fbb_.AddOffset(Field::VT_CUSTOM_METADATA, custom_metadata);
  }
  explicit FieldBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FieldBuilder &operator=(const FieldBuilder &);
  flatbuffers::Offset<Field> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Field>(end);
    return o;
  }
};

inline flatbuffers::Offset<Field> CreateField(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> name = 0,
    bool nullable = false,
    org::apache::arrow::flatbuf::Type type_type = org::apache::arrow::flatbuf::Type::NONE,
    flatbuffers::Offset<void> type = 0,
    flatbuffers::Offset<org::apache::arrow::flatbuf::DictionaryEncoding> dictionary = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>>> children = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>>> custom_metadata = 0) {
  FieldBuilder builder_(_fbb);
  builder_.add_custom_metadata(custom_metadata);
  builder_.add_children(children);
  builder_.add_dictionary(dictionary);
  builder_.add_type(type);
  builder_.add_name(name);
  builder_.add_type_type(type_type);
  builder_.add_nullable(nullable);
  return builder_.Finish();
}

inline flatbuffers::Offset<Field> CreateFieldDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *name = nullptr,
    bool nullable = false,
    org::apache::arrow::flatbuf::Type type_type = org::apache::arrow::flatbuf::Type::NONE,
    flatbuffers::Offset<void> type = 0,
    flatbuffers::Offset<org::apache::arrow::flatbuf::DictionaryEncoding> dictionary = 0,
    const std::vector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>> *children = nullptr,
    const std::vector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>> *custom_metadata = nullptr) {
  auto name__ = name ? _fbb.CreateString(name) : 0;
  auto children__ = children ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>>(*children) : 0;
  auto custom_metadata__ = custom_metadata ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>>(*custom_metadata) : 0;
  return org::apache::arrow::flatbuf::CreateField(
      _fbb,
      name__,
      nullable,
      type_type,
      type,
      dictionary,
      children__,
      custom_metadata__);
}

/// ----------------------------------------------------------------------
/// A Schema describes the columns in a row batch
struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SchemaBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ENDIANNESS = 4,
    VT_FIELDS = 6,
    VT_CUSTOM_METADATA = 8,
    VT_FEATURES = 10
  };
  /// endianness of the buffer
  /// it is Little Endian by default
  /// if endianness doesn't match the underlying system then the vectors need to be converted
  org::apache::arrow::flatbuf::Endianness endianness() const {
    return static_cast<org::apache::arrow::flatbuf::Endianness>(GetField<int16_t>(VT_ENDIANNESS, 0));
  }
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>> *fields() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>> *>(VT_FIELDS);
  }
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>> *custom_metadata() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>> *>(VT_CUSTOM_METADATA);
  }
  /// Features used in the stream/file.
  const flatbuffers::Vector<int64_t> *features() const {
    return GetPointer<const flatbuffers::Vector<int64_t> *>(VT_FEATURES);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int16_t>(verifier, VT_ENDIANNESS) &&
           VerifyOffset(verifier, VT_FIELDS) &&
           verifier.VerifyVector(fields()) &&
           verifier.VerifyVectorOfTables(fields()) &&
           VerifyOffset(verifier, VT_CUSTOM_METADATA) &&
           verifier.VerifyVector(custom_metadata()) &&
           verifier.VerifyVectorOfTables(custom_metadata()) &&
           VerifyOffset(verifier, VT_FEATURES) &&
           verifier.VerifyVector(features()) &&
           verifier.EndTable();
  }
};

struct SchemaBuilder {
  typedef Schema Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_endianness(org::apache::arrow::flatbuf::Endianness endianness) {
    fbb_.AddElement<int16_t>(Schema::VT_ENDIANNESS, static_cast<int16_t>(endianness), 0);
  }
  void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>>> fields) {
    fbb_.AddOffset(Schema::VT_FIELDS, fields);
  }
  void add_custom_metadata(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>>> custom_metadata) {
    fbb_.AddOffset(Schema::VT_CUSTOM_METADATA, custom_metadata);
  }
  void add_features(flatbuffers::Offset<flatbuffers::Vector<int64_t>> features) {
    fbb_.AddOffset(Schema::VT_FEATURES, features);
  }
  explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SchemaBuilder &operator=(const SchemaBuilder &);
  flatbuffers::Offset<Schema> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Schema>(end);
    return o;
  }
};

inline flatbuffers::Offset<Schema> CreateSchema(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::flatbuf::Endianness endianness = org::apache::arrow::flatbuf::Endianness::Little,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>>> fields = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>>> custom_metadata = 0,
    flatbuffers::Offset<flatbuffers::Vector<int64_t>> features = 0) {
  SchemaBuilder builder_(_fbb);
  builder_.add_features(features);
  builder_.add_custom_metadata(custom_metadata);
  builder_.add_fields(fields);
  builder_.add_endianness(endianness);
  return builder_.Finish();
}

inline flatbuffers::Offset<Schema> CreateSchemaDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::flatbuf::Endianness endianness = org::apache::arrow::flatbuf::Endianness::Little,
    const std::vector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>> *fields = nullptr,
    const std::vector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>> *custom_metadata = nullptr,
    const std::vector<int64_t> *features = nullptr) {
  auto fields__ = fields ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::flatbuf::Field>>(*fields) : 0;
  auto custom_metadata__ = custom_metadata ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::flatbuf::KeyValue>>(*custom_metadata) : 0;
  auto features__ = features ? _fbb.CreateVector<int64_t>(*features) : 0;
  return org::apache::arrow::flatbuf::CreateSchema(
      _fbb,
      endianness,
      fields__,
      custom_metadata__,
      features__);
}

inline bool VerifyType(flatbuffers::Verifier &verifier, const void *obj, Type type) {
  switch (type) {
    case Type::NONE: {
      return true;
    }
    case Type::Null: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Null *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Int: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Int *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::FloatingPoint: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::FloatingPoint *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Binary: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Binary *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Utf8: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Utf8 *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Bool: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Bool *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Decimal: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Decimal *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Date: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Date *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Time: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Time *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Timestamp: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Timestamp *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Interval: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Interval *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::List: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::List *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Struct_: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Struct_ *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Union: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Union *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::FixedSizeBinary: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::FixedSizeBinary *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::FixedSizeList: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::FixedSizeList *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Map: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Map *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::Duration: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Duration *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::LargeBinary: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::LargeBinary *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::LargeUtf8: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::LargeUtf8 *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type::LargeList: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::LargeList *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return true;
  }
}

inline bool VerifyTypeVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
  if (!values || !types) return !values && !types;
  if (values->size() != types->size()) return false;
  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
    if (!VerifyType(
        verifier,  values->Get(i), types->GetEnum<Type>(i))) {
      return false;
    }
  }
  return true;
}

inline const org::apache::arrow::flatbuf::Schema *GetSchema(const void *buf) {
  return flatbuffers::GetRoot<org::apache::arrow::flatbuf::Schema>(buf);
}

inline const org::apache::arrow::flatbuf::Schema *GetSizePrefixedSchema(const void *buf) {
  return flatbuffers::GetSizePrefixedRoot<org::apache::arrow::flatbuf::Schema>(buf);
}

inline bool VerifySchemaBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifyBuffer<org::apache::arrow::flatbuf::Schema>(nullptr);
}

inline bool VerifySizePrefixedSchemaBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifySizePrefixedBuffer<org::apache::arrow::flatbuf::Schema>(nullptr);
}

inline void FinishSchemaBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<org::apache::arrow::flatbuf::Schema> root) {
  fbb.Finish(root);
}

inline void FinishSizePrefixedSchemaBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<org::apache::arrow::flatbuf::Schema> root) {
  fbb.FinishSizePrefixed(root);
}

}  // namespace flatbuf
}  // namespace arrow
}  // namespace apache
}  // namespace org

#endif  // FLATBUFFERS_GENERATED_SCHEMA_ORG_APACHE_ARROW_FLATBUF_H_
