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


#ifndef FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
#define FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_

#include "flatbuffers/flatbuffers.h"

#include "namespace_test1_generated.h"

namespace NamespaceA {

struct TableInFirstNS;

}  // namespace NamespaceA

namespace NamespaceC {

struct TableInC;

}  // namespace NamespaceC

namespace NamespaceA {

struct SecondTableInA;

inline const flatbuffers::TypeTable *TableInFirstNSTypeTable();

}  // namespace NamespaceA

namespace NamespaceC {

inline const flatbuffers::TypeTable *TableInCTypeTable();

}  // namespace NamespaceC

namespace NamespaceA {

inline const flatbuffers::TypeTable *SecondTableInATypeTable();

struct TableInFirstNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
    return TableInFirstNSTypeTable();
  }
  enum {
    VT_FOO_TABLE = 4,
    VT_FOO_ENUM = 6,
    VT_FOO_STRUCT = 8
  };
  const NamespaceA::NamespaceB::TableInNestedNS *foo_table() const {
    return GetPointer<const NamespaceA::NamespaceB::TableInNestedNS *>(VT_FOO_TABLE);
  }
  NamespaceA::NamespaceB::TableInNestedNS *mutable_foo_table() {
    return GetPointer<NamespaceA::NamespaceB::TableInNestedNS *>(VT_FOO_TABLE);
  }
  NamespaceA::NamespaceB::EnumInNestedNS foo_enum() const {
    return static_cast<NamespaceA::NamespaceB::EnumInNestedNS>(GetField<int8_t>(VT_FOO_ENUM, 0));
  }
  bool mutate_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS _foo_enum) {
    return SetField<int8_t>(VT_FOO_ENUM, static_cast<int8_t>(_foo_enum), 0);
  }
  const NamespaceA::NamespaceB::StructInNestedNS *foo_struct() const {
    return GetStruct<const NamespaceA::NamespaceB::StructInNestedNS *>(VT_FOO_STRUCT);
  }
  NamespaceA::NamespaceB::StructInNestedNS *mutable_foo_struct() {
    return GetStruct<NamespaceA::NamespaceB::StructInNestedNS *>(VT_FOO_STRUCT);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_FOO_TABLE) &&
           verifier.VerifyTable(foo_table()) &&
           VerifyField<int8_t>(verifier, VT_FOO_ENUM) &&
           VerifyField<NamespaceA::NamespaceB::StructInNestedNS>(verifier, VT_FOO_STRUCT) &&
           verifier.EndTable();
  }
};

struct TableInFirstNSBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_foo_table(flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table) {
    fbb_.AddOffset(TableInFirstNS::VT_FOO_TABLE, foo_table);
  }
  void add_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS foo_enum) {
    fbb_.AddElement<int8_t>(TableInFirstNS::VT_FOO_ENUM, static_cast<int8_t>(foo_enum), 0);
  }
  void add_foo_struct(const NamespaceA::NamespaceB::StructInNestedNS *foo_struct) {
    fbb_.AddStruct(TableInFirstNS::VT_FOO_STRUCT, foo_struct);
  }
  explicit TableInFirstNSBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TableInFirstNSBuilder &operator=(const TableInFirstNSBuilder &);
  flatbuffers::Offset<TableInFirstNS> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TableInFirstNS>(end);
    return o;
  }
};

inline flatbuffers::Offset<TableInFirstNS> CreateTableInFirstNS(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table = 0,
    NamespaceA::NamespaceB::EnumInNestedNS foo_enum = NamespaceA::NamespaceB::EnumInNestedNS_A,
    const NamespaceA::NamespaceB::StructInNestedNS *foo_struct = 0) {
  TableInFirstNSBuilder builder_(_fbb);
  builder_.add_foo_struct(foo_struct);
  builder_.add_foo_table(foo_table);
  builder_.add_foo_enum(foo_enum);
  return builder_.Finish();
}

}  // namespace NamespaceA

namespace NamespaceC {

struct TableInC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
    return TableInCTypeTable();
  }
  enum {
    VT_REFER_TO_A1 = 4,
    VT_REFER_TO_A2 = 6
  };
  const NamespaceA::TableInFirstNS *refer_to_a1() const {
    return GetPointer<const NamespaceA::TableInFirstNS *>(VT_REFER_TO_A1);
  }
  NamespaceA::TableInFirstNS *mutable_refer_to_a1() {
    return GetPointer<NamespaceA::TableInFirstNS *>(VT_REFER_TO_A1);
  }
  const NamespaceA::SecondTableInA *refer_to_a2() const {
    return GetPointer<const NamespaceA::SecondTableInA *>(VT_REFER_TO_A2);
  }
  NamespaceA::SecondTableInA *mutable_refer_to_a2() {
    return GetPointer<NamespaceA::SecondTableInA *>(VT_REFER_TO_A2);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_REFER_TO_A1) &&
           verifier.VerifyTable(refer_to_a1()) &&
           VerifyOffset(verifier, VT_REFER_TO_A2) &&
           verifier.VerifyTable(refer_to_a2()) &&
           verifier.EndTable();
  }
};

struct TableInCBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_refer_to_a1(flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1) {
    fbb_.AddOffset(TableInC::VT_REFER_TO_A1, refer_to_a1);
  }
  void add_refer_to_a2(flatbuffers::Offset<NamespaceA::SecondTableInA> refer_to_a2) {
    fbb_.AddOffset(TableInC::VT_REFER_TO_A2, refer_to_a2);
  }
  explicit TableInCBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TableInCBuilder &operator=(const TableInCBuilder &);
  flatbuffers::Offset<TableInC> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TableInC>(end);
    return o;
  }
};

inline flatbuffers::Offset<TableInC> CreateTableInC(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1 = 0,
    flatbuffers::Offset<NamespaceA::SecondTableInA> refer_to_a2 = 0) {
  TableInCBuilder builder_(_fbb);
  builder_.add_refer_to_a2(refer_to_a2);
  builder_.add_refer_to_a1(refer_to_a1);
  return builder_.Finish();
}

}  // namespace NamespaceC

namespace NamespaceA {

struct SecondTableInA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  static const flatbuffers::TypeTable *MiniReflectTypeTable() {
    return SecondTableInATypeTable();
  }
  enum {
    VT_REFER_TO_C = 4
  };
  const NamespaceC::TableInC *refer_to_c() const {
    return GetPointer<const NamespaceC::TableInC *>(VT_REFER_TO_C);
  }
  NamespaceC::TableInC *mutable_refer_to_c() {
    return GetPointer<NamespaceC::TableInC *>(VT_REFER_TO_C);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_REFER_TO_C) &&
           verifier.VerifyTable(refer_to_c()) &&
           verifier.EndTable();
  }
};

struct SecondTableInABuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_refer_to_c(flatbuffers::Offset<NamespaceC::TableInC> refer_to_c) {
    fbb_.AddOffset(SecondTableInA::VT_REFER_TO_C, refer_to_c);
  }
  explicit SecondTableInABuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SecondTableInABuilder &operator=(const SecondTableInABuilder &);
  flatbuffers::Offset<SecondTableInA> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SecondTableInA>(end);
    return o;
  }
};

inline flatbuffers::Offset<SecondTableInA> CreateSecondTableInA(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<NamespaceC::TableInC> refer_to_c = 0) {
  SecondTableInABuilder builder_(_fbb);
  builder_.add_refer_to_c(refer_to_c);
  return builder_.Finish();
}

}  // namespace NamespaceA

namespace NamespaceC {

}  // namespace NamespaceC

namespace NamespaceA {

inline const flatbuffers::TypeTable *TableInFirstNSTypeTable() {
  static const flatbuffers::TypeCode type_codes[] = {
    { flatbuffers::ET_SEQUENCE, 0, 0 },
    { flatbuffers::ET_CHAR, 0, 1 },
    { flatbuffers::ET_SEQUENCE, 0, 2 }
  };
  static const flatbuffers::TypeFunction type_refs[] = {
    NamespaceA::NamespaceB::TableInNestedNSTypeTable,
    NamespaceA::NamespaceB::EnumInNestedNSTypeTable,
    NamespaceA::NamespaceB::StructInNestedNSTypeTable
  };
  static const char * const names[] = {
    "foo_table",
    "foo_enum",
    "foo_struct"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_TABLE, 3, type_codes, type_refs, nullptr, names
  };
  return &tt;
}

}  // namespace NamespaceA

namespace NamespaceC {

inline const flatbuffers::TypeTable *TableInCTypeTable() {
  static const flatbuffers::TypeCode type_codes[] = {
    { flatbuffers::ET_SEQUENCE, 0, 0 },
    { flatbuffers::ET_SEQUENCE, 0, 1 }
  };
  static const flatbuffers::TypeFunction type_refs[] = {
    NamespaceA::TableInFirstNSTypeTable,
    NamespaceA::SecondTableInATypeTable
  };
  static const char * const names[] = {
    "refer_to_a1",
    "refer_to_a2"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_TABLE, 2, type_codes, type_refs, nullptr, names
  };
  return &tt;
}

}  // namespace NamespaceC

namespace NamespaceA {

inline const flatbuffers::TypeTable *SecondTableInATypeTable() {
  static const flatbuffers::TypeCode type_codes[] = {
    { flatbuffers::ET_SEQUENCE, 0, 0 }
  };
  static const flatbuffers::TypeFunction type_refs[] = {
    NamespaceC::TableInCTypeTable
  };
  static const char * const names[] = {
    "refer_to_c"
  };
  static const flatbuffers::TypeTable tt = {
    flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
  };
  return &tt;
}

}  // namespace NamespaceA

#endif  // FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
