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

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

 public:
  VObject() {
    memset(this, 0, sizeof(VObject));
  }
  VObject(const VObject &_o) {
    memcpy(this, &_o, 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_);
  }
};
STRUCT_END(VObject, 24);

struct DesignElement FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    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) &&
           VerifyField<flatbuffers::uoffset_t>(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);
  }
  DesignElementBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DesignElementBuilder &operator=(const DesignElementBuilder &);
  flatbuffers::Offset<DesignElement> Finish() {
    const auto end = fbb_.EndTable(start_, 8);
    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 {
    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<DesignElement>> *m_elements() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<DesignElement>> *>(VT_M_ELEMENTS);
  }
  const flatbuffers::Vector<const VObject *> *m_objects() const {
    return GetPointer<const flatbuffers::Vector<const VObject *> *>(VT_M_OBJECTS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<flatbuffers::uoffset_t>(verifier, VT_M_HEADER) &&
           verifier.VerifyTable(m_header()) &&
           VerifyField<flatbuffers::uoffset_t>(verifier, VT_M_ERRORS) &&
           verifier.Verify(m_errors()) &&
           verifier.VerifyVectorOfTables(m_errors()) &&
           VerifyField<flatbuffers::uoffset_t>(verifier, VT_M_SYMBOLS) &&
           verifier.Verify(m_symbols()) &&
           verifier.VerifyVectorOfStrings(m_symbols()) &&
           VerifyField<flatbuffers::uoffset_t>(verifier, VT_M_ELEMENTS) &&
           verifier.Verify(m_elements()) &&
           verifier.VerifyVectorOfTables(m_elements()) &&
           VerifyField<flatbuffers::uoffset_t>(verifier, VT_M_OBJECTS) &&
           verifier.Verify(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<DesignElement>>> m_elements) {
    fbb_.AddOffset(ParseCache::VT_M_ELEMENTS, m_elements);
  }
  void add_m_objects(flatbuffers::Offset<flatbuffers::Vector<const VObject *>> m_objects) {
    fbb_.AddOffset(ParseCache::VT_M_OBJECTS, m_objects);
  }
  ParseCacheBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ParseCacheBuilder &operator=(const ParseCacheBuilder &);
  flatbuffers::Offset<ParseCache> Finish() {
    const auto end = fbb_.EndTable(start_, 5);
    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<DesignElement>>> m_elements = 0,
    flatbuffers::Offset<flatbuffers::Vector<const 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<DesignElement>> *m_elements = nullptr,
    const std::vector<const VObject *> *m_objects = nullptr) {
  return SURELOG::PARSECACHE::CreateParseCache(
      _fbb,
      m_header,
      m_errors ? _fbb.CreateVector<flatbuffers::Offset<SURELOG::CACHE::Error>>(*m_errors) : 0,
      m_symbols ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*m_symbols) : 0,
      m_elements ? _fbb.CreateVector<flatbuffers::Offset<DesignElement>>(*m_elements) : 0,
      m_objects ? _fbb.CreateVector<const VObject *>(*m_objects) : 0);
}

inline const SURELOG::PARSECACHE::ParseCache *GetParseCache(const void *buf) {
  return flatbuffers::GetRoot<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 const char *ParseCacheExtension() {
  return "slpa";
}

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

}  // namespace PARSECACHE
}  // namespace SURELOG

#endif  // FLATBUFFERS_GENERATED_PARSER_SURELOG_PARSECACHE_H_
