// 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"

// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 24 &&
              FLATBUFFERS_VERSION_MINOR == 3 &&
              FLATBUFFERS_VERSION_REVISION == 6,
             "Non-compatible flatbuffers version included");

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 ListView;
struct ListViewBuilder;

struct LargeListView;
struct LargeListViewBuilder;

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 Utf8View;
struct Utf8ViewBuilder;

struct BinaryView;
struct BinaryViewBuilder;

struct FixedSizeBinary;
struct FixedSizeBinaryBuilder;

struct Bool;
struct BoolBuilder;

struct RunEndEncoded;
struct RunEndEncodedBuilder;

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 MetadataVersion : int16_t {
  /// 0.1.0 (October 2016).
  MetadataVersion_V1 = 0,
  /// 0.2.0 (February 2017). Non-backwards compatible with V1.
  MetadataVersion_V2 = 1,
  /// 0.3.0 -> 0.7.1 (May - December 2017). Non-backwards compatible with V2.
  MetadataVersion_V3 = 2,
  /// >= 0.8.0 (December 2017). Non-backwards compatible with V3.
  MetadataVersion_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.
  MetadataVersion_V5 = 4,
  MetadataVersion_MIN = MetadataVersion_V1,
  MetadataVersion_MAX = MetadataVersion_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 intended to represent higher level
///      features, additional details may be 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 Feature : int64_t {
  /// Needed to make flatbuffers happy.
  Feature_UNUSED = 0,
  /// The stream makes use of multiple full dictionaries with the
  /// same ID and assumes clients implement dictionary replacement
  /// correctly.
  Feature_DICTIONARY_REPLACEMENT = 1LL,
  /// The stream makes use of compressed bodies as described
  /// in Message.fbs.
  Feature_COMPRESSED_BODY = 2LL,
  Feature_MIN = Feature_UNUSED,
  Feature_MAX = Feature_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 UnionMode : int16_t {
  UnionMode_Sparse = 0,
  UnionMode_Dense = 1,
  UnionMode_MIN = UnionMode_Sparse,
  UnionMode_MAX = UnionMode_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 Precision : int16_t {
  Precision_HALF = 0,
  Precision_SINGLE = 1,
  Precision_DOUBLE = 2,
  Precision_MIN = Precision_HALF,
  Precision_MAX = Precision_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 DateUnit : int16_t {
  DateUnit_DAY = 0,
  DateUnit_MILLISECOND = 1,
  DateUnit_MIN = DateUnit_DAY,
  DateUnit_MAX = DateUnit_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 TimeUnit : int16_t {
  TimeUnit_SECOND = 0,
  TimeUnit_MILLISECOND = 1,
  TimeUnit_MICROSECOND = 2,
  TimeUnit_NANOSECOND = 3,
  TimeUnit_MIN = TimeUnit_SECOND,
  TimeUnit_MAX = TimeUnit_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 IntervalUnit : int16_t {
  IntervalUnit_YEAR_MONTH = 0,
  IntervalUnit_DAY_TIME = 1,
  IntervalUnit_MONTH_DAY_NANO = 2,
  IntervalUnit_MIN = IntervalUnit_YEAR_MONTH,
  IntervalUnit_MAX = IntervalUnit_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 Type : uint8_t {
  Type_NONE = 0,
  Type_Null = 1,
  Type_Int = 2,
  Type_FloatingPoint = 3,
  Type_Binary = 4,
  Type_Utf8 = 5,
  Type_Bool = 6,
  Type_Decimal = 7,
  Type_Date = 8,
  Type_Time = 9,
  Type_Timestamp = 10,
  Type_Interval = 11,
  Type_List = 12,
  Type_Struct_ = 13,
  Type_Union = 14,
  Type_FixedSizeBinary = 15,
  Type_FixedSizeList = 16,
  Type_Map = 17,
  Type_Duration = 18,
  Type_LargeBinary = 19,
  Type_LargeUtf8 = 20,
  Type_LargeList = 21,
  Type_RunEndEncoded = 22,
  Type_BinaryView = 23,
  Type_Utf8View = 24,
  Type_ListView = 25,
  Type_LargeListView = 26,
  Type_MIN = Type_NONE,
  Type_MAX = Type_LargeListView
};

inline const Type (&EnumValuesType())[27] {
  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,
    Type_RunEndEncoded,
    Type_BinaryView,
    Type_Utf8View,
    Type_ListView,
    Type_LargeListView
  };
  return values;
}

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

inline const char *EnumNameType(Type e) {
  if (::flatbuffers::IsOutRange(e, Type_NONE, Type_LargeListView)) 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;
};

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

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

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

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

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

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 DictionaryKind : int16_t {
  DictionaryKind_DenseArray = 0,
  DictionaryKind_MIN = DictionaryKind_DenseArray,
  DictionaryKind_MAX = DictionaryKind_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 Endianness : int16_t {
  Endianness_Little = 0,
  Endianness_Big = 1,
  Endianness_MIN = Endianness_Little,
  Endianness_MAX = Endianness_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()
      : offset_(0),
        length_(0) {
  }
  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();
  }
  ::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();
  }
  ::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();
  }
  ::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();
  }
  ::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();
}

/// Represents the same logical types that List can, but contains offsets and
/// sizes allowing for writes in any order and sharing of child values among
/// list values.
struct ListView FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef ListViewBuilder Builder;
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

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

inline ::flatbuffers::Offset<ListView> CreateListView(
    ::flatbuffers::FlatBufferBuilder &_fbb) {
  ListViewBuilder builder_(_fbb);
  return builder_.Finish();
}

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

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

inline ::flatbuffers::Offset<LargeListView> CreateLargeListView(
    ::flatbuffers::FlatBufferBuilder &_fbb) {
  LargeListViewBuilder 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, 4) &&
           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();
  }
  ::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, 1) &&
           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();
  }
  ::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, 2) &&
           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();
  }
  ::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, 4) &&
           VerifyField<uint8_t>(verifier, VT_IS_SIGNED, 1) &&
           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();
  }
  ::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, 2) &&
           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();
  }
  ::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();
  }
  ::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();
  }
  ::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();
  }
  ::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();
  }
  ::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();
}

/// Logically the same as Utf8, but the internal representation uses a view
/// struct that contains the string length and either the string's entire data
/// inline (for small strings) or an inlined prefix, an index of another buffer,
/// and an offset pointing to a slice in that buffer (for non-small strings).
///
/// Since it uses a variable number of data buffers, each Field with this type
/// must have a corresponding entry in `variadicBufferCounts`.
struct Utf8View FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef Utf8ViewBuilder Builder;
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

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

inline ::flatbuffers::Offset<Utf8View> CreateUtf8View(
    ::flatbuffers::FlatBufferBuilder &_fbb) {
  Utf8ViewBuilder builder_(_fbb);
  return builder_.Finish();
}

/// Logically the same as Binary, but the internal representation uses a view
/// struct that contains the string length and either the string's entire data
/// inline (for small strings) or an inlined prefix, an index of another buffer,
/// and an offset pointing to a slice in that buffer (for non-small strings).
///
/// Since it uses a variable number of data buffers, each Field with this type
/// must have a corresponding entry in `variadicBufferCounts`.
struct BinaryView FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef BinaryViewBuilder Builder;
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

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

inline ::flatbuffers::Offset<BinaryView> CreateBinaryView(
    ::flatbuffers::FlatBufferBuilder &_fbb) {
  BinaryViewBuilder 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, 4) &&
           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();
  }
  ::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();
  }
  ::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();
}

/// Contains two child arrays, run_ends and values.
/// The run_ends child array must be a 16/32/64-bit integer array
/// which encodes the indices at which the run with the value in 
/// each corresponding index in the values child array ends.
/// Like list/struct types, the value array can be of any type.
struct RunEndEncoded FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
  typedef RunEndEncodedBuilder Builder;
  bool Verify(::flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

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

inline ::flatbuffers::Offset<RunEndEncoded> CreateRunEndEncoded(
    ::flatbuffers::FlatBufferBuilder &_fbb) {
  RunEndEncodedBuilder builder_(_fbb);
  return builder_.Finish();
}

/// Exact decimal value represented as an integer value in two's
/// complement. Currently 32-bit (4-byte), 64-bit (8-byte), 
/// 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 accepted widths are 32, 64, 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, 4) &&
           VerifyField<int32_t>(verifier, VT_SCALE, 4) &&
           VerifyField<int32_t>(verifier, VT_BITWIDTH, 4) &&
           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();
  }
  ::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, 2) &&
           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();
  }
  ::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, 2) &&
           VerifyField<int32_t>(verifier, VT_BITWIDTH, 4) &&
           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();
  }
  ::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 nonexistent. 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, 2) &&
           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();
  }
  ::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, 2) &&
           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();
  }
  ::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, 2) &&
           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();
  }
  ::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();
  }
  ::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, 8) &&
           VerifyOffset(verifier, VT_INDEXTYPE) &&
           verifier.VerifyTable(indexType()) &&
           VerifyField<uint8_t>(verifier, VT_ISORDERED, 1) &&
           VerifyField<int16_t>(verifier, VT_DICTIONARYKIND, 2) &&
           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();
  }
  ::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 (e.g., in 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;
  }
  const org::apache::arrow::flatbuf::RunEndEncoded *type_as_RunEndEncoded() const {
    return type_type() == org::apache::arrow::flatbuf::Type_RunEndEncoded ? static_cast<const org::apache::arrow::flatbuf::RunEndEncoded *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::BinaryView *type_as_BinaryView() const {
    return type_type() == org::apache::arrow::flatbuf::Type_BinaryView ? static_cast<const org::apache::arrow::flatbuf::BinaryView *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::Utf8View *type_as_Utf8View() const {
    return type_type() == org::apache::arrow::flatbuf::Type_Utf8View ? static_cast<const org::apache::arrow::flatbuf::Utf8View *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::ListView *type_as_ListView() const {
    return type_type() == org::apache::arrow::flatbuf::Type_ListView ? static_cast<const org::apache::arrow::flatbuf::ListView *>(type()) : nullptr;
  }
  const org::apache::arrow::flatbuf::LargeListView *type_as_LargeListView() const {
    return type_type() == org::apache::arrow::flatbuf::Type_LargeListView ? static_cast<const org::apache::arrow::flatbuf::LargeListView *>(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, 1) &&
           VerifyField<uint8_t>(verifier, VT_TYPE_TYPE, 1) &&
           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();
}

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

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

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

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

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

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();
  }
  ::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, 2) &&
           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();
  }
  ::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);
    }
    case Type_RunEndEncoded: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::RunEndEncoded *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type_BinaryView: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::BinaryView *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type_Utf8View: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::Utf8View *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type_ListView: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::ListView *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case Type_LargeListView: {
      auto ptr = reinterpret_cast<const org::apache::arrow::flatbuf::LargeListView *>(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_
