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


#ifndef FLATBUFFERS_GENERATED_PARSER_SURELOG_PARSECACHE_H_
#define FLATBUFFERS_GENERATED_PARSER_SURELOG_PARSECACHE_H_

#include "flatbuffers/flatbuffers.h"

#include "header_generated.h"

namespace SURELOG {
namespace PARSECACHE {

struct DesignElement;

struct VObject;

struct ParseCache;

FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) VObject FLATBUFFERS_FINAL_CLASS {
 private:
  uint64_t m_field1_;
  uint64_t m_field2_;
  uint64_t m_field3_;

 public:
  VObject() {
    memset(static_cast<void *>(this), 0, sizeof(VObject));
  }
  VObject(uint64_t _m_field1, uint64_t _m_field2, uint64_t _m_field3)
      : m_field1_(flatbuffers::EndianScalar(_m_field1)),
        m_field2_(flatbuffers::EndianScalar(_m_field2)),
        m_field3_(flatbuffers::EndianScalar(_m_field3)) {
  }
  uint64_t m_field1() const {
    return flatbuffers::EndianScalar(m_field1_);
  }
  uint64_t m_field2() const {
    return flatbuffers::EndianScalar(m_field2_);
  }
  uint64_t m_field3() const {
    return flatbuffers::EndianScalar(m_field3_);
  }
};
FLATBUFFERS_STRUCT_END(VObject, 24);

struct DesignElement FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_M_NAME = 4,
    VT_M_FILEID = 6,
    VT_M_TYPE = 8,
    VT_M_UNIQUEID = 10,
    VT_M_LINE = 12,
    VT_M_TIMEINFO = 14,
    VT_M_PARENT = 16,
    VT_M_NODE = 18
  };
  uint64_t m_name() const {
    return GetField<uint64_t>(VT_M_NAME, 0);
  }
  uint64_t m_fileId() const {
    return GetField<uint64_t>(VT_M_FILEID, 0);
  }
  uint32_t m_type() const {
    return GetField<uint32_t>(VT_M_TYPE, 0);
  }
  uint64_t m_uniqueId() const {
    return GetField<uint64_t>(VT_M_UNIQUEID, 0);
  }
  uint32_t m_line() const {
    return GetField<uint32_t>(VT_M_LINE, 0);
  }
  const SURELOG::CACHE::TimeInfo *m_timeInfo() const {
    return GetPointer<const SURELOG::CACHE::TimeInfo *>(VT_M_TIMEINFO);
  }
  uint64_t m_parent() const {
    return GetField<uint64_t>(VT_M_PARENT, 0);
  }
  uint32_t m_node() const {
    return GetField<uint32_t>(VT_M_NODE, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint64_t>(verifier, VT_M_NAME) &&
           VerifyField<uint64_t>(verifier, VT_M_FILEID) &&
           VerifyField<uint32_t>(verifier, VT_M_TYPE) &&
           VerifyField<uint64_t>(verifier, VT_M_UNIQUEID) &&
           VerifyField<uint32_t>(verifier, VT_M_LINE) &&
           VerifyOffset(verifier, VT_M_TIMEINFO) &&
           verifier.VerifyTable(m_timeInfo()) &&
           VerifyField<uint64_t>(verifier, VT_M_PARENT) &&
           VerifyField<uint32_t>(verifier, VT_M_NODE) &&
           verifier.EndTable();
  }
};

struct DesignElementBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_m_name(uint64_t m_name) {
    fbb_.AddElement<uint64_t>(DesignElement::VT_M_NAME, m_name, 0);
  }
  void add_m_fileId(uint64_t m_fileId) {
    fbb_.AddElement<uint64_t>(DesignElement::VT_M_FILEID, m_fileId, 0);
  }
  void add_m_type(uint32_t m_type) {
    fbb_.AddElement<uint32_t>(DesignElement::VT_M_TYPE, m_type, 0);
  }
  void add_m_uniqueId(uint64_t m_uniqueId) {
    fbb_.AddElement<uint64_t>(DesignElement::VT_M_UNIQUEID, m_uniqueId, 0);
  }
  void add_m_line(uint32_t m_line) {
    fbb_.AddElement<uint32_t>(DesignElement::VT_M_LINE, m_line, 0);
  }
  void add_m_timeInfo(flatbuffers::Offset<SURELOG::CACHE::TimeInfo> m_timeInfo) {
    fbb_.AddOffset(DesignElement::VT_M_TIMEINFO, m_timeInfo);
  }
  void add_m_parent(uint64_t m_parent) {
    fbb_.AddElement<uint64_t>(DesignElement::VT_M_PARENT, m_parent, 0);
  }
  void add_m_node(uint32_t m_node) {
    fbb_.AddElement<uint32_t>(DesignElement::VT_M_NODE, m_node, 0);
  }
  explicit DesignElementBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DesignElementBuilder &operator=(const DesignElementBuilder &);
  flatbuffers::Offset<DesignElement> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DesignElement>(end);
    return o;
  }
};

inline flatbuffers::Offset<DesignElement> CreateDesignElement(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint64_t m_name = 0,
    uint64_t m_fileId = 0,
    uint32_t m_type = 0,
    uint64_t m_uniqueId = 0,
    uint32_t m_line = 0,
    flatbuffers::Offset<SURELOG::CACHE::TimeInfo> m_timeInfo = 0,
    uint64_t m_parent = 0,
    uint32_t m_node = 0) {
  DesignElementBuilder builder_(_fbb);
  builder_.add_m_parent(m_parent);
  builder_.add_m_uniqueId(m_uniqueId);
  builder_.add_m_fileId(m_fileId);
  builder_.add_m_name(m_name);
  builder_.add_m_node(m_node);
  builder_.add_m_timeInfo(m_timeInfo);
  builder_.add_m_line(m_line);
  builder_.add_m_type(m_type);
  return builder_.Finish();
}

struct ParseCache FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_M_HEADER = 4,
    VT_M_ERRORS = 6,
    VT_M_SYMBOLS = 8,
    VT_M_ELEMENTS = 10,
    VT_M_OBJECTS = 12
  };
  const SURELOG::CACHE::Header *m_header() const {
    return GetPointer<const SURELOG::CACHE::Header *>(VT_M_HEADER);
  }
  const flatbuffers::Vector<flatbuffers::Offset<SURELOG::CACHE::Error>> *m_errors() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<SURELOG::CACHE::Error>> *>(VT_M_ERRORS);
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *m_symbols() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_M_SYMBOLS);
  }
  const flatbuffers::Vector<flatbuffers::Offset<SURELOG::PARSECACHE::DesignElement>> *m_elements() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<SURELOG::PARSECACHE::DesignElement>> *>(VT_M_ELEMENTS);
  }
  const flatbuffers::Vector<const SURELOG::PARSECACHE::VObject *> *m_objects() const {
    return GetPointer<const flatbuffers::Vector<const SURELOG::PARSECACHE::VObject *> *>(VT_M_OBJECTS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_M_HEADER) &&
           verifier.VerifyTable(m_header()) &&
           VerifyOffset(verifier, VT_M_ERRORS) &&
           verifier.VerifyVector(m_errors()) &&
           verifier.VerifyVectorOfTables(m_errors()) &&
           VerifyOffset(verifier, VT_M_SYMBOLS) &&
           verifier.VerifyVector(m_symbols()) &&
           verifier.VerifyVectorOfStrings(m_symbols()) &&
           VerifyOffset(verifier, VT_M_ELEMENTS) &&
           verifier.VerifyVector(m_elements()) &&
           verifier.VerifyVectorOfTables(m_elements()) &&
           VerifyOffset(verifier, VT_M_OBJECTS) &&
           verifier.VerifyVector(m_objects()) &&
           verifier.EndTable();
  }
};

struct ParseCacheBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_m_header(flatbuffers::Offset<SURELOG::CACHE::Header> m_header) {
    fbb_.AddOffset(ParseCache::VT_M_HEADER, m_header);
  }
  void add_m_errors(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<SURELOG::CACHE::Error>>> m_errors) {
    fbb_.AddOffset(ParseCache::VT_M_ERRORS, m_errors);
  }
  void add_m_symbols(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> m_symbols) {
    fbb_.AddOffset(ParseCache::VT_M_SYMBOLS, m_symbols);
  }
  void add_m_elements(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<SURELOG::PARSECACHE::DesignElement>>> m_elements) {
    fbb_.AddOffset(ParseCache::VT_M_ELEMENTS, m_elements);
  }
  void add_m_objects(flatbuffers::Offset<flatbuffers::Vector<const SURELOG::PARSECACHE::VObject *>> m_objects) {
    fbb_.AddOffset(ParseCache::VT_M_OBJECTS, m_objects);
  }
  explicit ParseCacheBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ParseCacheBuilder &operator=(const ParseCacheBuilder &);
  flatbuffers::Offset<ParseCache> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ParseCache>(end);
    return o;
  }
};

inline flatbuffers::Offset<ParseCache> CreateParseCache(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<SURELOG::CACHE::Header> m_header = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<SURELOG::CACHE::Error>>> m_errors = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> m_symbols = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<SURELOG::PARSECACHE::DesignElement>>> m_elements = 0,
    flatbuffers::Offset<flatbuffers::Vector<const SURELOG::PARSECACHE::VObject *>> m_objects = 0) {
  ParseCacheBuilder builder_(_fbb);
  builder_.add_m_objects(m_objects);
  builder_.add_m_elements(m_elements);
  builder_.add_m_symbols(m_symbols);
  builder_.add_m_errors(m_errors);
  builder_.add_m_header(m_header);
  return builder_.Finish();
}

inline flatbuffers::Offset<ParseCache> CreateParseCacheDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<SURELOG::CACHE::Header> m_header = 0,
    const std::vector<flatbuffers::Offset<SURELOG::CACHE::Error>> *m_errors = nullptr,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *m_symbols = nullptr,
    const std::vector<flatbuffers::Offset<SURELOG::PARSECACHE::DesignElement>> *m_elements = nullptr,
    const std::vector<SURELOG::PARSECACHE::VObject> *m_objects = nullptr) {
  auto m_errors__ = m_errors ? _fbb.CreateVector<flatbuffers::Offset<SURELOG::CACHE::Error>>(*m_errors) : 0;
  auto m_symbols__ = m_symbols ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*m_symbols) : 0;
  auto m_elements__ = m_elements ? _fbb.CreateVector<flatbuffers::Offset<SURELOG::PARSECACHE::DesignElement>>(*m_elements) : 0;
  auto m_objects__ = m_objects ? _fbb.CreateVectorOfStructs<SURELOG::PARSECACHE::VObject>(*m_objects) : 0;
  return SURELOG::PARSECACHE::CreateParseCache(
      _fbb,
      m_header,
      m_errors__,
      m_symbols__,
      m_elements__,
      m_objects__);
}

inline const SURELOG::PARSECACHE::ParseCache *GetParseCache(const void *buf) {
  return flatbuffers::GetRoot<SURELOG::PARSECACHE::ParseCache>(buf);
}

inline const SURELOG::PARSECACHE::ParseCache *GetSizePrefixedParseCache(const void *buf) {
  return flatbuffers::GetSizePrefixedRoot<SURELOG::PARSECACHE::ParseCache>(buf);
}

inline const char *ParseCacheIdentifier() {
  return "SLPA";
}

inline bool ParseCacheBufferHasIdentifier(const void *buf) {
  return flatbuffers::BufferHasIdentifier(
      buf, ParseCacheIdentifier());
}

inline bool VerifyParseCacheBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifyBuffer<SURELOG::PARSECACHE::ParseCache>(ParseCacheIdentifier());
}

inline bool VerifySizePrefixedParseCacheBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifySizePrefixedBuffer<SURELOG::PARSECACHE::ParseCache>(ParseCacheIdentifier());
}

inline const char *ParseCacheExtension() {
  return "slpa";
}

inline void FinishParseCacheBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<SURELOG::PARSECACHE::ParseCache> root) {
  fbb.Finish(root, ParseCacheIdentifier());
}

inline void FinishSizePrefixedParseCacheBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<SURELOG::PARSECACHE::ParseCache> root) {
  fbb.FinishSizePrefixed(root, ParseCacheIdentifier());
}

}  // namespace PARSECACHE
}  // namespace SURELOG

#endif  // FLATBUFFERS_GENERATED_PARSER_SURELOG_PARSECACHE_H_
