/*
 * Copyright 2021 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FLATBUFFERS_FLATBUFFER_BUILDER_H_
#define FLATBUFFERS_FLATBUFFER_BUILDER_H_

#include <algorithm>
#include <cstdint>
#include <functional>
#include <initializer_list>
#include <type_traits>

#include "flatbuffers/allocator.h"
#include "flatbuffers/array.h"
#include "flatbuffers/base.h"
#include "flatbuffers/buffer.h"
#include "flatbuffers/buffer_ref.h"
#include "flatbuffers/default_allocator.h"
#include "flatbuffers/detached_buffer.h"
#include "flatbuffers/stl_emulation.h"
#include "flatbuffers/string.h"
#include "flatbuffers/struct.h"
#include "flatbuffers/table.h"
#include "flatbuffers/vector.h"
#include "flatbuffers/vector_downward.h"
#include "flatbuffers/verifier.h"

namespace flatbuffers {

// Converts a Field ID to a virtual table offset.
inline voffset_t FieldIndexToOffset(voffset_t field_id) {
  // Should correspond to what EndTable() below builds up.
  const voffset_t fixed_fields =
      2 * sizeof(voffset_t);  // Vtable size and Object Size.
  size_t offset = fixed_fields + field_id * sizeof(voffset_t);
  FLATBUFFERS_ASSERT(offset < std::numeric_limits<voffset_t>::max());
  return static_cast<voffset_t>(offset);}

template<typename T, typename Alloc = std::allocator<T>>
const T *data(const std::vector<T, Alloc> &v) {
  // Eventually the returned pointer gets passed down to memcpy, so
  // we need it to be non-null to avoid undefined behavior.
  static uint8_t t;
  return v.empty() ? reinterpret_cast<const T *>(&t) : &v.front();
}
template<typename T, typename Alloc = std::allocator<T>>
T *data(std::vector<T, Alloc> &v) {
  // Eventually the returned pointer gets passed down to memcpy, so
  // we need it to be non-null to avoid undefined behavior.
  static uint8_t t;
  return v.empty() ? reinterpret_cast<T *>(&t) : &v.front();
}

/// @addtogroup flatbuffers_cpp_api
/// @{
/// @class FlatBufferBuilder
/// @brief Helper class to hold data needed in creation of a FlatBuffer.
/// To serialize data, you typically call one of the `Create*()` functions in
/// the generated code, which in turn call a sequence of `StartTable`/
/// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/
/// `CreateVector` functions. Do this is depth-first order to build up a tree to
/// the root. `Finish()` wraps up the buffer ready for transport.
template<bool Is64Aware = false> class FlatBufferBuilderImpl {
 public:
  // This switches the size type of the builder, based on if its 64-bit aware
  // (uoffset64_t) or not (uoffset_t).
  typedef
      typename std::conditional<Is64Aware, uoffset64_t, uoffset_t>::type SizeT;

  /// @brief Default constructor for FlatBufferBuilder.
  /// @param[in] initial_size The initial size of the buffer, in bytes. Defaults
  /// to `1024`.
  /// @param[in] allocator An `Allocator` to use. If null will use
  /// `DefaultAllocator`.
  /// @param[in] own_allocator Whether the builder/vector should own the
  /// allocator. Defaults to / `false`.
  /// @param[in] buffer_minalign Force the buffer to be aligned to the given
  /// minimum alignment upon reallocation. Only needed if you intend to store
  /// types with custom alignment AND you wish to read the buffer in-place
  /// directly after creation.
  explicit FlatBufferBuilderImpl(
      size_t initial_size = 1024, Allocator *allocator = nullptr,
      bool own_allocator = false,
      size_t buffer_minalign = AlignOf<largest_scalar_t>())
      : buf_(initial_size, allocator, own_allocator, buffer_minalign,
             static_cast<SizeT>(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE
                                          : FLATBUFFERS_MAX_BUFFER_SIZE)),
        num_field_loc(0),
        max_voffset_(0),
        length_of_64_bit_region_(0),
        nested(false),
        finished(false),
        minalign_(1),
        force_defaults_(false),
        dedup_vtables_(true),
        string_pool(nullptr) {
    EndianCheck();
  }

  /// @brief Move constructor for FlatBufferBuilder.
  FlatBufferBuilderImpl(FlatBufferBuilderImpl &&other) noexcept
      : buf_(1024, nullptr, false, AlignOf<largest_scalar_t>(),
             static_cast<SizeT>(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE
                                          : FLATBUFFERS_MAX_BUFFER_SIZE)),
        num_field_loc(0),
        max_voffset_(0),
        length_of_64_bit_region_(0),
        nested(false),
        finished(false),
        minalign_(1),
        force_defaults_(false),
        dedup_vtables_(true),
        string_pool(nullptr) {
    EndianCheck();
    // Default construct and swap idiom.
    // Lack of delegating constructors in vs2010 makes it more verbose than
    // needed.
    Swap(other);
  }

  /// @brief Move assignment operator for FlatBufferBuilder.
  FlatBufferBuilderImpl &operator=(FlatBufferBuilderImpl &&other) noexcept {
    // Move construct a temporary and swap idiom
    FlatBufferBuilderImpl temp(std::move(other));
    Swap(temp);
    return *this;
  }

  void Swap(FlatBufferBuilderImpl &other) {
    using std::swap;
    buf_.swap(other.buf_);
    swap(num_field_loc, other.num_field_loc);
    swap(max_voffset_, other.max_voffset_);
    swap(length_of_64_bit_region_, other.length_of_64_bit_region_);
    swap(nested, other.nested);
    swap(finished, other.finished);
    swap(minalign_, other.minalign_);
    swap(force_defaults_, other.force_defaults_);
    swap(dedup_vtables_, other.dedup_vtables_);
    swap(string_pool, other.string_pool);
  }

  ~FlatBufferBuilderImpl() {
    if (string_pool) delete string_pool;
  }

  void Reset() {
    Clear();       // clear builder state
    buf_.reset();  // deallocate buffer
  }

  /// @brief Reset all the state in this FlatBufferBuilder so it can be reused
  /// to construct another buffer.
  void Clear() {
    ClearOffsets();
    buf_.clear();
    nested = false;
    finished = false;
    minalign_ = 1;
    length_of_64_bit_region_ = 0;
    if (string_pool) string_pool->clear();
  }

  /// @brief The current size of the serialized buffer, counting from the end.
  /// @return Returns an `SizeT` with the current size of the buffer.
  SizeT GetSize() const { return buf_.size(); }

  /// @brief The current size of the serialized buffer relative to the end of
  /// the 32-bit region.
  /// @return Returns an `uoffset_t` with the current size of the buffer.
  template<bool is_64 = Is64Aware>
  // Only enable this method for the 64-bit builder, as only that builder is
  // concerned with the 32/64-bit boundary, and should be the one to bare any
  // run time costs.
  typename std::enable_if<is_64, uoffset_t>::type GetSizeRelative32BitRegion()
      const {
    //[32-bit region][64-bit region]
    //         [XXXXXXXXXXXXXXXXXXX] GetSize()
    //               [YYYYYYYYYYYYY] length_of_64_bit_region_
    //         [ZZZZ]                return size
    return static_cast<uoffset_t>(GetSize() - length_of_64_bit_region_);
  }

  template<bool is_64 = Is64Aware>
  // Only enable this method for the 32-bit builder.
  typename std::enable_if<!is_64, uoffset_t>::type GetSizeRelative32BitRegion()
      const {
    return static_cast<uoffset_t>(GetSize());
  }

  /// @brief Get the serialized buffer (after you call `Finish()`).
  /// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the
  /// buffer.
  uint8_t *GetBufferPointer() const {
    Finished();
    return buf_.data();
  }

  /// @brief Get the serialized buffer (after you call `Finish()`) as a span.
  /// @return Returns a constructed flatbuffers::span that is a view over the
  /// FlatBuffer data inside the buffer.
  flatbuffers::span<uint8_t> GetBufferSpan() const {
    Finished();
    return flatbuffers::span<uint8_t>(buf_.data(), buf_.size());
  }

  /// @brief Get a pointer to an unfinished buffer.
  /// @return Returns a `uint8_t` pointer to the unfinished buffer.
  uint8_t *GetCurrentBufferPointer() const { return buf_.data(); }

  /// @brief Get the released DetachedBuffer.
  /// @return A `DetachedBuffer` that owns the buffer and its allocator.
  DetachedBuffer Release() {
    Finished();
    DetachedBuffer buffer = buf_.release();
    Clear();
    return buffer;
  }

  /// @brief Get the released pointer to the serialized buffer.
  /// @param size The size of the memory block containing
  /// the serialized `FlatBuffer`.
  /// @param offset The offset from the released pointer where the finished
  /// `FlatBuffer` starts.
  /// @return A raw pointer to the start of the memory block containing
  /// the serialized `FlatBuffer`.
  /// @remark If the allocator is owned, it gets deleted when the destructor is
  /// called.
  uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
    Finished();
    uint8_t* raw = buf_.release_raw(size, offset);
    Clear();
    return raw;
  }

  /// @brief get the minimum alignment this buffer needs to be accessed
  /// properly. This is only known once all elements have been written (after
  /// you call Finish()). You can use this information if you need to embed
  /// a FlatBuffer in some other buffer, such that you can later read it
  /// without first having to copy it into its own buffer.
  size_t GetBufferMinAlignment() const {
    Finished();
    return minalign_;
  }

  /// @cond FLATBUFFERS_INTERNAL
  void Finished() const {
    // If you get this assert, you're attempting to get access a buffer
    // which hasn't been finished yet. Be sure to call
    // FlatBufferBuilder::Finish with your root table.
    // If you really need to access an unfinished buffer, call
    // GetCurrentBufferPointer instead.
    FLATBUFFERS_ASSERT(finished);
  }
  /// @endcond

  /// @brief In order to save space, fields that are set to their default value
  /// don't get serialized into the buffer.
  /// @param[in] fd When set to `true`, always serializes default values that
  /// are set. Optional fields which are not set explicitly, will still not be
  /// serialized.
  void ForceDefaults(bool fd) { force_defaults_ = fd; }

  /// @brief By default vtables are deduped in order to save space.
  /// @param[in] dedup When set to `true`, dedup vtables.
  void DedupVtables(bool dedup) { dedup_vtables_ = dedup; }

  /// @cond FLATBUFFERS_INTERNAL
  void Pad(size_t num_bytes) { buf_.fill(num_bytes); }

  void TrackMinAlign(size_t elem_size) {
    if (elem_size > minalign_) minalign_ = elem_size;
  }

  void Align(size_t elem_size) {
    TrackMinAlign(elem_size);
    buf_.fill(PaddingBytes(buf_.size(), elem_size));
  }

  void PushFlatBuffer(const uint8_t *bytes, size_t size) {
    PushBytes(bytes, size);
    finished = true;
  }

  void PushBytes(const uint8_t *bytes, size_t size) { buf_.push(bytes, size); }

  void PopBytes(size_t amount) { buf_.pop(amount); }

  template<typename T> void AssertScalarT() {
    // The code assumes power of 2 sizes and endian-swap-ability.
    static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type");
  }

  // Write a single aligned scalar to the buffer
  template<typename T, typename ReturnT = uoffset_t>
  ReturnT PushElement(T element) {
    AssertScalarT<T>();
    Align(sizeof(T));
    buf_.push_small(EndianScalar(element));
    return CalculateOffset<ReturnT>();
  }

  template<typename T, template<typename> class OffsetT = Offset>
  uoffset_t PushElement(OffsetT<T> off) {
    // Special case for offsets: see ReferTo below.
    return PushElement(ReferTo(off.o));
  }

  // When writing fields, we track where they are, so we can create correct
  // vtables later.
  void TrackField(voffset_t field, uoffset_t off) {
    FieldLoc fl = { off, field };
    buf_.scratch_push_small(fl);
    num_field_loc++;
    if (field > max_voffset_) { max_voffset_ = field; }
  }

  // Like PushElement, but additionally tracks the field this represents.
  template<typename T> void AddElement(voffset_t field, T e, T def) {
    // We don't serialize values equal to the default.
    if (IsTheSameAs(e, def) && !force_defaults_) return;
    TrackField(field, PushElement(e));
  }

  template<typename T> void AddElement(voffset_t field, T e) {
    TrackField(field, PushElement(e));
  }

  template<typename T> void AddOffset(voffset_t field, Offset<T> off) {
    if (off.IsNull()) return;  // Don't store.
    AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0));
  }

  template<typename T> void AddOffset(voffset_t field, Offset64<T> off) {
    if (off.IsNull()) return;  // Don't store.
    AddElement(field, ReferTo(off.o), static_cast<uoffset64_t>(0));
  }

  template<typename T> void AddStruct(voffset_t field, const T *structptr) {
    if (!structptr) return;  // Default, don't store.
    Align(AlignOf<T>());
    buf_.push_small(*structptr);
    TrackField(field, CalculateOffset<uoffset_t>());
  }

  void AddStructOffset(voffset_t field, uoffset_t off) {
    TrackField(field, off);
  }

  // Offsets initially are relative to the end of the buffer (downwards).
  // This function converts them to be relative to the current location
  // in the buffer (when stored here), pointing upwards.
  uoffset_t ReferTo(uoffset_t off) {
    // Align to ensure GetSizeRelative32BitRegion() below is correct.
    Align(sizeof(uoffset_t));
    // 32-bit offsets are relative to the tail of the 32-bit region of the
    // buffer. For most cases (without 64-bit entities) this is equivalent to
    // size of the whole buffer (e.g. GetSize())
    return ReferTo(off, GetSizeRelative32BitRegion());
  }

  uoffset64_t ReferTo(uoffset64_t off) {
    // Align to ensure GetSize() below is correct.
    Align(sizeof(uoffset64_t));
    // 64-bit offsets are relative to tail of the whole buffer
    return ReferTo(off, GetSize());
  }

  template<typename T, typename T2> T ReferTo(const T off, const T2 size) {
    FLATBUFFERS_ASSERT(off && off <= size);
    return size - off + static_cast<T>(sizeof(T));
  }

  template<typename T> T ReferTo(const T off, const T size) {
    FLATBUFFERS_ASSERT(off && off <= size);
    return size - off + static_cast<T>(sizeof(T));
  }

  void NotNested() {
    // If you hit this, you're trying to construct a Table/Vector/String
    // during the construction of its parent table (between the MyTableBuilder
    // and table.Finish().
    // Move the creation of these sub-objects to above the MyTableBuilder to
    // not get this assert.
    // Ignoring this assert may appear to work in simple cases, but the reason
    // it is here is that storing objects in-line may cause vtable offsets
    // to not fit anymore. It also leads to vtable duplication.
    FLATBUFFERS_ASSERT(!nested);
    // If you hit this, fields were added outside the scope of a table.
    FLATBUFFERS_ASSERT(!num_field_loc);
  }

  // From generated code (or from the parser), we call StartTable/EndTable
  // with a sequence of AddElement calls in between.
  uoffset_t StartTable() {
    NotNested();
    nested = true;
    return GetSizeRelative32BitRegion();
  }

  // This finishes one serialized object by generating the vtable if it's a
  // table, comparing it against existing vtables, and writing the
  // resulting vtable offset.
  uoffset_t EndTable(uoffset_t start) {
    // If you get this assert, a corresponding StartTable wasn't called.
    FLATBUFFERS_ASSERT(nested);
    // Write the vtable offset, which is the start of any Table.
    // We fill its value later.
    // This is relative to the end of the 32-bit region.
    const uoffset_t vtable_offset_loc =
        static_cast<uoffset_t>(PushElement<soffset_t>(0));
    // Write a vtable, which consists entirely of voffset_t elements.
    // It starts with the number of offsets, followed by a type id, followed
    // by the offsets themselves. In reverse:
    // Include space for the last offset and ensure empty tables have a
    // minimum size.
    max_voffset_ =
        (std::max)(static_cast<voffset_t>(max_voffset_ + sizeof(voffset_t)),
                   FieldIndexToOffset(0));
    buf_.fill_big(max_voffset_);
    const uoffset_t table_object_size = vtable_offset_loc - start;
    // Vtable use 16bit offsets.
    FLATBUFFERS_ASSERT(table_object_size < 0x10000);
    WriteScalar<voffset_t>(buf_.data() + sizeof(voffset_t),
                           static_cast<voffset_t>(table_object_size));
    WriteScalar<voffset_t>(buf_.data(), max_voffset_);
    // Write the offsets into the table
    for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc);
         it < buf_.scratch_end(); it += sizeof(FieldLoc)) {
      auto field_location = reinterpret_cast<FieldLoc *>(it);
      const voffset_t pos =
          static_cast<voffset_t>(vtable_offset_loc - field_location->off);
      // If this asserts, it means you've set a field twice.
      FLATBUFFERS_ASSERT(
          !ReadScalar<voffset_t>(buf_.data() + field_location->id));
      WriteScalar<voffset_t>(buf_.data() + field_location->id, pos);
    }
    ClearOffsets();
    auto vt1 = reinterpret_cast<voffset_t *>(buf_.data());
    auto vt1_size = ReadScalar<voffset_t>(vt1);
    auto vt_use = GetSizeRelative32BitRegion();
    // See if we already have generated a vtable with this exact same
    // layout before. If so, make it point to the old one, remove this one.
    if (dedup_vtables_) {
      for (auto it = buf_.scratch_data(); it < buf_.scratch_end();
           it += sizeof(uoffset_t)) {
        auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
        auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
        auto vt2_size = ReadScalar<voffset_t>(vt2);
        if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
        vt_use = *vt_offset_ptr;
        buf_.pop(GetSizeRelative32BitRegion() - vtable_offset_loc);
        break;
      }
    }
    // If this is a new vtable, remember it.
    if (vt_use == GetSizeRelative32BitRegion()) {
      buf_.scratch_push_small(vt_use);
    }
    // Fill the vtable offset we created above.
    // The offset points from the beginning of the object to where the vtable is
    // stored.
    // Offsets default direction is downward in memory for future format
    // flexibility (storing all vtables at the start of the file).
    WriteScalar(buf_.data_at(vtable_offset_loc + length_of_64_bit_region_),
                static_cast<soffset_t>(vt_use) -
                    static_cast<soffset_t>(vtable_offset_loc));
    nested = false;
    return vtable_offset_loc;
  }

  FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]])
  uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) {
    return EndTable(start);
  }

  // This checks a required field has been set in a given table that has
  // just been constructed.
  template<typename T> void Required(Offset<T> table, voffset_t field) {
    auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
    bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
    // If this fails, the caller will show what field needs to be set.
    FLATBUFFERS_ASSERT(ok);
    (void)ok;
  }

  uoffset_t StartStruct(size_t alignment) {
    Align(alignment);
    return GetSizeRelative32BitRegion();
  }

  uoffset_t EndStruct() { return GetSizeRelative32BitRegion(); }

  void ClearOffsets() {
    buf_.scratch_pop(num_field_loc * sizeof(FieldLoc));
    num_field_loc = 0;
    max_voffset_ = 0;
  }

  // Aligns such that when "len" bytes are written, an object can be written
  // after it (forward in the buffer) with "alignment" without padding.
  void PreAlign(size_t len, size_t alignment) {
    if (len == 0) return;
    TrackMinAlign(alignment);
    buf_.fill(PaddingBytes(GetSize() + len, alignment));
  }

  // Aligns such than when "len" bytes are written, an object of type `AlignT`
  // can be written after it (forward in the buffer) without padding.
  template<typename AlignT> void PreAlign(size_t len) {
    AssertScalarT<AlignT>();
    PreAlign(len, AlignOf<AlignT>());
  }
  /// @endcond

  /// @brief Store a string in the buffer, which can contain any binary data.
  /// @param[in] str A const char pointer to the data to be stored as a string.
  /// @param[in] len The number of bytes that should be stored from `str`.
  /// @return Returns the offset in the buffer where the string starts.
  template<template<typename> class OffsetT = Offset>
  OffsetT<String> CreateString(const char *str, size_t len) {
    CreateStringImpl(str, len);
    return OffsetT<String>(
        CalculateOffset<typename OffsetT<String>::offset_type>());
  }

  /// @brief Store a string in the buffer, which is null-terminated.
  /// @param[in] str A const char pointer to a C-string to add to the buffer.
  /// @return Returns the offset in the buffer where the string starts.
  template<template<typename> class OffsetT = Offset>
  OffsetT<String> CreateString(const char *str) {
    return CreateString<OffsetT>(str, strlen(str));
  }

  /// @brief Store a string in the buffer, which is null-terminated.
  /// @param[in] str A char pointer to a C-string to add to the buffer.
  /// @return Returns the offset in the buffer where the string starts.
  template<template<typename> class OffsetT = Offset>
  OffsetT<String> CreateString(char *str) {
    return CreateString<OffsetT>(str, strlen(str));
  }

  /// @brief Store a string in the buffer, which can contain any binary data.
  /// @param[in] str A const reference to a std::string to store in the buffer.
  /// @return Returns the offset in the buffer where the string starts.
  template<template<typename> class OffsetT = Offset>
  OffsetT<String> CreateString(const std::string &str) {
    return CreateString<OffsetT>(str.c_str(), str.length());
  }

// clang-format off
  #ifdef FLATBUFFERS_HAS_STRING_VIEW
  /// @brief Store a string in the buffer, which can contain any binary data.
  /// @param[in] str A const string_view to copy in to the buffer.
  /// @return Returns the offset in the buffer where the string starts.
  template<template <typename> class OffsetT = Offset>
  OffsetT<String>CreateString(flatbuffers::string_view str) {
    return CreateString<OffsetT>(str.data(), str.size());
  }
  #endif // FLATBUFFERS_HAS_STRING_VIEW
  // clang-format on

  /// @brief Store a string in the buffer, which can contain any binary data.
  /// @param[in] str A const pointer to a `String` struct to add to the buffer.
  /// @return Returns the offset in the buffer where the string starts
  template<template<typename> class OffsetT = Offset>
  OffsetT<String> CreateString(const String *str) {
    return str ? CreateString<OffsetT>(str->c_str(), str->size()) : 0;
  }

  /// @brief Store a string in the buffer, which can contain any binary data.
  /// @param[in] str A const reference to a std::string like type with support
  /// of T::data() and T::length() to store in the buffer.
  /// @return Returns the offset in the buffer where the string starts.
  template<template<typename> class OffsetT = Offset,
           // No need to explicitly declare the T type, let the compiler deduce
           // it.
           int &...ExplicitArgumentBarrier, typename T>
  OffsetT<String> CreateString(const T &str) {
    return CreateString<OffsetT>(str.data(), str.length());
  }

  /// @brief Store a string in the buffer, which can contain any binary data.
  /// If a string with this exact contents has already been serialized before,
  /// instead simply returns the offset of the existing string. This uses a map
  /// stored on the heap, but only stores the numerical offsets.
  /// @param[in] str A const char pointer to the data to be stored as a string.
  /// @param[in] len The number of bytes that should be stored from `str`.
  /// @return Returns the offset in the buffer where the string starts.
  Offset<String> CreateSharedString(const char *str, size_t len) {
    FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
    if (!string_pool) {
      string_pool = new StringOffsetMap(StringOffsetCompare(buf_));
    }

    const size_t size_before_string = buf_.size();
    // Must first serialize the string, since the set is all offsets into
    // buffer.
    const Offset<String> off = CreateString<Offset>(str, len);
    auto it = string_pool->find(off);
    // If it exists we reuse existing serialized data!
    if (it != string_pool->end()) {
      // We can remove the string we serialized.
      buf_.pop(buf_.size() - size_before_string);
      return *it;
    }
    // Record this string for future use.
    string_pool->insert(off);
    return off;
  }

#ifdef FLATBUFFERS_HAS_STRING_VIEW
  /// @brief Store a string in the buffer, which can contain any binary data.
  /// If a string with this exact contents has already been serialized before,
  /// instead simply returns the offset of the existing string. This uses a map
  /// stored on the heap, but only stores the numerical offsets.
  /// @param[in] str A const std::string_view to store in the buffer.
  /// @return Returns the offset in the buffer where the string starts
  Offset<String> CreateSharedString(const flatbuffers::string_view str) {
    return CreateSharedString(str.data(), str.size());
  }
#else
  /// @brief Store a string in the buffer, which null-terminated.
  /// If a string with this exact contents has already been serialized before,
  /// instead simply returns the offset of the existing string. This uses a map
  /// stored on the heap, but only stores the numerical offsets.
  /// @param[in] str A const char pointer to a C-string to add to the buffer.
  /// @return Returns the offset in the buffer where the string starts.
  Offset<String> CreateSharedString(const char *str) {
    return CreateSharedString(str, strlen(str));
  }

  /// @brief Store a string in the buffer, which can contain any binary data.
  /// If a string with this exact contents has already been serialized before,
  /// instead simply returns the offset of the existing string. This uses a map
  /// stored on the heap, but only stores the numerical offsets.
  /// @param[in] str A const reference to a std::string to store in the buffer.
  /// @return Returns the offset in the buffer where the string starts.
  Offset<String> CreateSharedString(const std::string &str) {
    return CreateSharedString(str.c_str(), str.length());
  }
#endif

  /// @brief Store a string in the buffer, which can contain any binary data.
  /// If a string with this exact contents has already been serialized before,
  /// instead simply returns the offset of the existing string. This uses a map
  /// stored on the heap, but only stores the numerical offsets.
  /// @param[in] str A const pointer to a `String` struct to add to the buffer.
  /// @return Returns the offset in the buffer where the string starts
  Offset<String> CreateSharedString(const String *str) {
    return str ? CreateSharedString(str->c_str(), str->size()) : 0;
  }

  /// @cond FLATBUFFERS_INTERNAL
  template<typename LenT = uoffset_t, typename ReturnT = uoffset_t>
  ReturnT EndVector(size_t len) {
    FLATBUFFERS_ASSERT(nested);  // Hit if no corresponding StartVector.
    nested = false;
    return PushElement<LenT, ReturnT>(static_cast<LenT>(len));
  }

  template<template<typename> class OffsetT = Offset, typename LenT = uint32_t>
  void StartVector(size_t len, size_t elemsize, size_t alignment) {
    NotNested();
    nested = true;
    // Align to the Length type of the vector (either 32-bit or 64-bit), so
    // that the length of the buffer can be added without padding.
    PreAlign<LenT>(len * elemsize);
    PreAlign(len * elemsize, alignment);  // Just in case elemsize > uoffset_t.
  }

  template<typename T, template<typename> class OffsetT = Offset,
           typename LenT = uint32_t>
  void StartVector(size_t len) {
    return StartVector<OffsetT, LenT>(len, sizeof(T), AlignOf<T>());
  }

  // Call this right before StartVector/CreateVector if you want to force the
  // alignment to be something different than what the element size would
  // normally dictate.
  // This is useful when storing a nested_flatbuffer in a vector of bytes,
  // or when storing SIMD floats, etc.
  void ForceVectorAlignment(const size_t len, const size_t elemsize,
                            const size_t alignment) {
    if (len == 0) return;
    FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
    PreAlign(len * elemsize, alignment);
  }

  template<bool is_64 = Is64Aware>
  typename std::enable_if<is_64, void>::type ForceVectorAlignment64(
      const size_t len, const size_t elemsize, const size_t alignment) {
    // If you hit this assertion, you are trying to force alignment on a
    // vector with offset64 after serializing a 32-bit offset.
    FLATBUFFERS_ASSERT(GetSize() == length_of_64_bit_region_);

    // Call through.
    ForceVectorAlignment(len, elemsize, alignment);

    // Update the 64 bit region.
    length_of_64_bit_region_ = GetSize();
  }

  // Similar to ForceVectorAlignment but for String fields.
  void ForceStringAlignment(size_t len, size_t alignment) {
    if (len == 0) return;
    FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
    PreAlign((len + 1) * sizeof(char), alignment);
  }

  /// @endcond

  /// @brief Serialize an array into a FlatBuffer `vector`.
  /// @tparam T The data type of the array elements.
  /// @tparam OffsetT the type of offset to return
  /// @tparam VectorT the type of vector to cast to.
  /// @param[in] v A pointer to the array of type `T` to serialize into the
  /// buffer as a `vector`.
  /// @param[in] len The number of elements to serialize.
  /// @return Returns a typed `TOffset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, template<typename...> class OffsetT = Offset,
           template<typename...> class VectorT = Vector>
  OffsetT<VectorT<T>> CreateVector(const T *v, size_t len) {
    // The type of the length field in the vector.
    typedef typename VectorT<T>::size_type LenT;
    typedef typename OffsetT<VectorT<T>>::offset_type offset_type;
    // If this assert hits, you're specifying a template argument that is
    // causing the wrong overload to be selected, remove it.
    AssertScalarT<T>();
    StartVector<T, OffsetT, LenT>(len);
    if (len > 0) {
// clang-format off
      #if FLATBUFFERS_LITTLEENDIAN
        PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T));
      #else
        if (sizeof(T) == 1) {
          PushBytes(reinterpret_cast<const uint8_t *>(v), len);
        } else {
          for (auto i = len; i > 0; ) {
            PushElement(v[--i]);
          }
        }
      #endif
      // clang-format on
    }
    return OffsetT<VectorT<T>>(EndVector<LenT, offset_type>(len));
  }

  /// @brief Serialize an array like object into a FlatBuffer `vector`.
  /// @tparam T The data type of the array elements.
  /// @tparam C The type of the array.
  /// @param[in] array A reference to an array like object of type `T` to
  /// serialize into the buffer as a `vector`.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, class C> Offset<Vector<T>> CreateVector(const C &array) {
    return CreateVector(array.data(), array.size());
  }

  /// @brief Serialize an initializer list into a FlatBuffer `vector`.
  /// @tparam T The data type of the initializer list elements.
  /// @param[in] v The value of the initializer list.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T>
  Offset<Vector<T>> CreateVector(std::initializer_list<T> v) {
    return CreateVector(v.begin(), v.size());
  }

  template<typename T>
  Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) {
    StartVector<Offset<T>>(len);
    for (auto i = len; i > 0;) { PushElement(v[--i]); }
    return Offset<Vector<Offset<T>>>(EndVector(len));
  }

  /// @brief Serialize a `std::vector` into a FlatBuffer `vector`.
  /// @tparam T The data type of the `std::vector` elements.
  /// @param v A const reference to the `std::vector` to serialize into the
  /// buffer as a `vector`.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, typename Alloc = std::allocator<T>>
  Offset<Vector<T>> CreateVector(const std::vector<T, Alloc> &v) {
    return CreateVector(data(v), v.size());
  }

  template<template<typename...> class VectorT = Vector64,
           int &...ExplicitArgumentBarrier, typename T>
  Offset64<VectorT<T>> CreateVector64(const std::vector<T> &v) {
    return CreateVector<T, Offset64, VectorT>(data(v), v.size());
  }

  // vector<bool> may be implemented using a bit-set, so we can't access it as
  // an array. Instead, read elements manually.
  // Background: https://isocpp.org/blog/2012/11/on-vectorbool
  Offset<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) {
    StartVector<uint8_t>(v.size());
    for (auto i = v.size(); i > 0;) {
      PushElement(static_cast<uint8_t>(v[--i]));
    }
    return Offset<Vector<uint8_t>>(EndVector(v.size()));
  }

  /// @brief Serialize values returned by a function into a FlatBuffer `vector`.
  /// This is a convenience function that takes care of iteration for you.
  /// @tparam T The data type of the `std::vector` elements.
  /// @param f A function that takes the current iteration 0..vector_size-1 and
  /// returns any type that you can construct a FlatBuffers vector out of.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T>
  Offset<Vector<T>> CreateVector(size_t vector_size,
                                 const std::function<T(size_t i)> &f) {
    FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
    std::vector<T> elems(vector_size);
    for (size_t i = 0; i < vector_size; i++) elems[i] = f(i);
    return CreateVector(elems);
  }

  /// @brief Serialize values returned by a function into a FlatBuffer `vector`.
  /// This is a convenience function that takes care of iteration for you. This
  /// uses a vector stored on the heap to store the intermediate results of the
  /// iteration.
  /// @tparam T The data type of the `std::vector` elements.
  /// @param f A function that takes the current iteration 0..vector_size-1,
  /// and the state parameter returning any type that you can construct a
  /// FlatBuffers vector out of.
  /// @param state State passed to f.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, typename F, typename S>
  Offset<Vector<T>> CreateVector(size_t vector_size, F f, S *state) {
    FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
    std::vector<T> elems(vector_size);
    for (size_t i = 0; i < vector_size; i++) elems[i] = f(i, state);
    return CreateVector(elems);
  }

  /// @brief Serialize a `std::vector<StringType>` into a FlatBuffer `vector`.
  /// whereas StringType is any type that is accepted by the CreateString()
  /// overloads.
  /// This is a convenience function for a common case.
  /// @param v A const reference to the `std::vector` to serialize into the
  /// buffer as a `vector`.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename StringType = std::string,
           typename Alloc = std::allocator<StringType>>
  Offset<Vector<Offset<String>>> CreateVectorOfStrings(
      const std::vector<StringType, Alloc> &v) {
    return CreateVectorOfStrings(v.cbegin(), v.cend());
  }

  /// @brief Serialize a collection of Strings into a FlatBuffer `vector`.
  /// This is a convenience function for a common case.
  /// @param begin The beginning iterator of the collection
  /// @param end The ending iterator of the collection
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<class It>
  Offset<Vector<Offset<String>>> CreateVectorOfStrings(It begin, It end) {
    auto distance = std::distance(begin, end);
    FLATBUFFERS_ASSERT(distance >= 0);
    auto size = static_cast<size_t>(distance);
    auto scratch_buffer_usage = size * sizeof(Offset<String>);
    // If there is not enough space to store the offsets, there definitely won't
    // be enough space to store all the strings. So ensuring space for the
    // scratch region is OK, for if it fails, it would have failed later.
    buf_.ensure_space(scratch_buffer_usage);
    for (auto it = begin; it != end; ++it) {
      buf_.scratch_push_small(CreateString(*it));
    }
    StartVector<Offset<String>>(size);
    for (size_t i = 1; i <= size; i++) {
      // Note we re-evaluate the buf location each iteration to account for any
      // underlying buffer resizing that may occur.
      PushElement(*reinterpret_cast<Offset<String> *>(
          buf_.scratch_end() - i * sizeof(Offset<String>)));
    }
    buf_.scratch_pop(scratch_buffer_usage);
    return Offset<Vector<Offset<String>>>(EndVector(size));
  }

  /// @brief Serialize an array of structs into a FlatBuffer `vector`.
  /// @tparam T The data type of the struct array elements.
  /// @param[in] v A pointer to the array of type `T` to serialize into the
  /// buffer as a `vector`.
  /// @param[in] len The number of elements to serialize.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, template<typename...> class OffsetT = Offset,
           template<typename...> class VectorT = Vector>
  OffsetT<VectorT<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
    // The type of the length field in the vector.
    typedef typename VectorT<T>::size_type LenT;
    typedef typename OffsetT<VectorT<const T *>>::offset_type offset_type;

    StartVector<OffsetT, LenT>(len, sizeof(T), AlignOf<T>());
    if (len > 0) {
      PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
    }
    return OffsetT<VectorT<const T *>>(EndVector<LenT, offset_type>(len));
  }

  /// @brief Serialize an array of structs into a FlatBuffer `vector`.
  /// @tparam T The data type of the struct array elements.
  /// @param[in] filler A function that takes the current iteration
  /// 0..vector_size-1 and a pointer to the struct that must be filled.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  /// This is mostly useful when flatbuffers are generated with mutation
  /// accessors.
  template<typename T>
  Offset<Vector<const T *>> CreateVectorOfStructs(
      size_t vector_size, const std::function<void(size_t i, T *)> &filler) {
    T *structs = StartVectorOfStructs<T>(vector_size);
    for (size_t i = 0; i < vector_size; i++) {
      filler(i, structs);
      structs++;
    }
    return EndVectorOfStructs<T>(vector_size);
  }

  /// @brief Serialize an array of structs into a FlatBuffer `vector`.
  /// @tparam T The data type of the struct array elements.
  /// @param[in] f A function that takes the current iteration 0..vector_size-1,
  /// a pointer to the struct that must be filled and the state argument.
  /// @param[in] state Arbitrary state to pass to f.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  /// This is mostly useful when flatbuffers are generated with mutation
  /// accessors.
  template<typename T, typename F, typename S>
  Offset<Vector<const T *>> CreateVectorOfStructs(size_t vector_size, F f,
                                                  S *state) {
    T *structs = StartVectorOfStructs<T>(vector_size);
    for (size_t i = 0; i < vector_size; i++) {
      f(i, structs, state);
      structs++;
    }
    return EndVectorOfStructs<T>(vector_size);
  }

  /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`.
  /// @tparam T The data type of the `std::vector` struct elements.
  /// @param[in] v A const reference to the `std::vector` of structs to
  /// serialize into the buffer as a `vector`.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, template<typename...> class OffsetT = Offset,
           template<typename...> class VectorT = Vector,
           typename Alloc = std::allocator<T>>
  OffsetT<VectorT<const T *>> CreateVectorOfStructs(
      const std::vector<T, Alloc> &v) {
    return CreateVectorOfStructs<T, OffsetT, VectorT>(data(v), v.size());
  }

  template<template<typename...> class VectorT = Vector64, int &..., typename T>
  Offset64<VectorT<const T *>> CreateVectorOfStructs64(
      const std::vector<T> &v) {
    return CreateVectorOfStructs<T, Offset64, VectorT>(data(v), v.size());
  }

  /// @brief Serialize an array of native structs into a FlatBuffer `vector`.
  /// @tparam T The data type of the struct array elements.
  /// @tparam S The data type of the native struct array elements.
  /// @param[in] v A pointer to the array of type `S` to serialize into the
  /// buffer as a `vector`.
  /// @param[in] len The number of elements to serialize.
  /// @param[in] pack_func Pointer to a function to convert the native struct
  /// to the FlatBuffer struct.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, typename S>
  Offset<Vector<const T *>> CreateVectorOfNativeStructs(
      const S *v, size_t len, T (*const pack_func)(const S &)) {
    FLATBUFFERS_ASSERT(pack_func);
    auto structs = StartVectorOfStructs<T>(len);
    for (size_t i = 0; i < len; i++) { structs[i] = pack_func(v[i]); }
    return EndVectorOfStructs<T>(len);
  }

  /// @brief Serialize an array of native structs into a FlatBuffer `vector`.
  /// @tparam T The data type of the struct array elements.
  /// @tparam S The data type of the native struct array elements.
  /// @param[in] v A pointer to the array of type `S` to serialize into the
  /// buffer as a `vector`.
  /// @param[in] len The number of elements to serialize.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, typename S>
  Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
                                                        size_t len) {
    extern T Pack(const S &);
    return CreateVectorOfNativeStructs(v, len, Pack);
  }

  /// @brief Serialize a `std::vector` of native structs into a FlatBuffer
  /// `vector`.
  /// @tparam T The data type of the `std::vector` struct elements.
  /// @tparam S The data type of the `std::vector` native struct elements.
  /// @param[in] v A const reference to the `std::vector` of structs to
  /// serialize into the buffer as a `vector`.
  /// @param[in] pack_func Pointer to a function to convert the native struct
  /// to the FlatBuffer struct.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, typename S, typename Alloc = std::allocator<T>>
  Offset<Vector<const T *>> CreateVectorOfNativeStructs(
      const std::vector<S, Alloc> &v, T (*const pack_func)(const S &)) {
    return CreateVectorOfNativeStructs<T, S>(data(v), v.size(), pack_func);
  }

  /// @brief Serialize a `std::vector` of native structs into a FlatBuffer
  /// `vector`.
  /// @tparam T The data type of the `std::vector` struct elements.
  /// @tparam S The data type of the `std::vector` native struct elements.
  /// @param[in] v A const reference to the `std::vector` of structs to
  /// serialize into the buffer as a `vector`.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, typename S, typename Alloc = std::allocator<S>>
  Offset<Vector<const T *>> CreateVectorOfNativeStructs(
      const std::vector<S, Alloc> &v) {
    return CreateVectorOfNativeStructs<T, S>(data(v), v.size());
  }

  /// @cond FLATBUFFERS_INTERNAL
  template<typename T> struct StructKeyComparator {
    bool operator()(const T &a, const T &b) const {
      return a.KeyCompareLessThan(&b);
    }
  };
  /// @endcond

  /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`
  /// in sorted order.
  /// @tparam T The data type of the `std::vector` struct elements.
  /// @param[in] v A const reference to the `std::vector` of structs to
  /// serialize into the buffer as a `vector`.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, typename Alloc = std::allocator<T>>
  Offset<Vector<const T *>> CreateVectorOfSortedStructs(
      std::vector<T, Alloc> *v) {
    return CreateVectorOfSortedStructs(data(*v), v->size());
  }

  /// @brief Serialize a `std::vector` of native structs into a FlatBuffer
  /// `vector` in sorted order.
  /// @tparam T The data type of the `std::vector` struct elements.
  /// @tparam S The data type of the `std::vector` native struct elements.
  /// @param[in] v A const reference to the `std::vector` of structs to
  /// serialize into the buffer as a `vector`.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, typename S, typename Alloc = std::allocator<T>>
  Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(
      std::vector<S, Alloc> *v) {
    return CreateVectorOfSortedNativeStructs<T, S>(data(*v), v->size());
  }

  /// @brief Serialize an array of structs into a FlatBuffer `vector` in sorted
  /// order.
  /// @tparam T The data type of the struct array elements.
  /// @param[in] v A pointer to the array of type `T` to serialize into the
  /// buffer as a `vector`.
  /// @param[in] len The number of elements to serialize.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T>
  Offset<Vector<const T *>> CreateVectorOfSortedStructs(T *v, size_t len) {
    std::stable_sort(v, v + len, StructKeyComparator<T>());
    return CreateVectorOfStructs(v, len);
  }

  /// @brief Serialize an array of native structs into a FlatBuffer `vector` in
  /// sorted order.
  /// @tparam T The data type of the struct array elements.
  /// @tparam S The data type of the native struct array elements.
  /// @param[in] v A pointer to the array of type `S` to serialize into the
  /// buffer as a `vector`.
  /// @param[in] len The number of elements to serialize.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, typename S>
  Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(S *v,
                                                              size_t len) {
    extern T Pack(const S &);
    auto structs = StartVectorOfStructs<T>(len);
    for (size_t i = 0; i < len; i++) { structs[i] = Pack(v[i]); }
    std::stable_sort(structs, structs + len, StructKeyComparator<T>());
    return EndVectorOfStructs<T>(len);
  }

  /// @cond FLATBUFFERS_INTERNAL
  template<typename T> struct TableKeyComparator {
    explicit TableKeyComparator(vector_downward<SizeT> &buf) : buf_(buf) {}
    TableKeyComparator(const TableKeyComparator &other) : buf_(other.buf_) {}
    bool operator()(const Offset<T> &a, const Offset<T> &b) const {
      auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
      auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
      return table_a->KeyCompareLessThan(table_b);
    }
    vector_downward<SizeT> &buf_;

   private:
    FLATBUFFERS_DELETE_FUNC(
        TableKeyComparator &operator=(const TableKeyComparator &other));
  };
  /// @endcond

  /// @brief Serialize an array of `table` offsets as a `vector` in the buffer
  /// in sorted order.
  /// @tparam T The data type that the offset refers to.
  /// @param[in] v An array of type `Offset<T>` that contains the `table`
  /// offsets to store in the buffer in sorted order.
  /// @param[in] len The number of elements to store in the `vector`.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T>
  Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T> *v,
                                                       size_t len) {
    std::stable_sort(v, v + len, TableKeyComparator<T>(buf_));
    return CreateVector(v, len);
  }

  /// @brief Serialize an array of `table` offsets as a `vector` in the buffer
  /// in sorted order.
  /// @tparam T The data type that the offset refers to.
  /// @param[in] v An array of type `Offset<T>` that contains the `table`
  /// offsets to store in the buffer in sorted order.
  /// @return Returns a typed `Offset` into the serialized data indicating
  /// where the vector is stored.
  template<typename T, typename Alloc = std::allocator<T>>
  Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
      std::vector<Offset<T>, Alloc> *v) {
    return CreateVectorOfSortedTables(data(*v), v->size());
  }

  /// @brief Specialized version of `CreateVector` for non-copying use cases.
  /// Write the data any time later to the returned buffer pointer `buf`.
  /// @param[in] len The number of elements to store in the `vector`.
  /// @param[in] elemsize The size of each element in the `vector`.
  /// @param[out] buf A pointer to a `uint8_t` pointer that can be
  /// written to at a later time to serialize the data into a `vector`
  /// in the buffer.
  uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
                                      size_t alignment, uint8_t **buf) {
    NotNested();
    StartVector(len, elemsize, alignment);
    buf_.make_space(len * elemsize);
    const uoffset_t vec_start = GetSizeRelative32BitRegion();
    auto vec_end = EndVector(len);
    *buf = buf_.data_at(vec_start);
    return vec_end;
  }

  FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]])
  uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
                                      uint8_t **buf) {
    return CreateUninitializedVector(len, elemsize, elemsize, buf);
  }

  /// @brief Specialized version of `CreateVector` for non-copying use cases.
  /// Write the data any time later to the returned buffer pointer `buf`.
  /// @tparam T The data type of the data that will be stored in the buffer
  /// as a `vector`.
  /// @param[in] len The number of elements to store in the `vector`.
  /// @param[out] buf A pointer to a pointer of type `T` that can be
  /// written to at a later time to serialize the data into a `vector`
  /// in the buffer.
  template<typename T>
  Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) {
    AssertScalarT<T>();
    return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
                                     reinterpret_cast<uint8_t **>(buf));
  }

  template<typename T>
  Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
                                                               T **buf) {
    return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
                                     reinterpret_cast<uint8_t **>(buf));
  }

  // @brief Create a vector of scalar type T given as input a vector of scalar
  // type U, useful with e.g. pre "enum class" enums, or any existing scalar
  // data of the wrong type.
  template<typename T, typename U>
  Offset<Vector<T>> CreateVectorScalarCast(const U *v, size_t len) {
    AssertScalarT<T>();
    AssertScalarT<U>();
    StartVector<T>(len);
    for (auto i = len; i > 0;) { PushElement(static_cast<T>(v[--i])); }
    return Offset<Vector<T>>(EndVector(len));
  }

  /// @brief Write a struct by itself, typically to be part of a union.
  template<typename T> Offset<const T *> CreateStruct(const T &structobj) {
    NotNested();
    Align(AlignOf<T>());
    buf_.push_small(structobj);
    return Offset<const T *>(
        CalculateOffset<typename Offset<const T *>::offset_type>());
  }

  /// @brief Finish serializing a buffer by writing the root offset.
  /// @param[in] file_identifier If a `file_identifier` is given, the buffer
  /// will be prefixed with a standard FlatBuffers file header.
  template<typename T>
  void Finish(Offset<T> root, const char *file_identifier = nullptr) {
    Finish(root.o, file_identifier, false);
  }

  /// @brief Finish a buffer with a 32 bit size field pre-fixed (size of the
  /// buffer following the size field). These buffers are NOT compatible
  /// with standard buffers created by Finish, i.e. you can't call GetRoot
  /// on them, you have to use GetSizePrefixedRoot instead.
  /// All >32 bit quantities in this buffer will be aligned when the whole
  /// size pre-fixed buffer is aligned.
  /// These kinds of buffers are useful for creating a stream of FlatBuffers.
  template<typename T>
  void FinishSizePrefixed(Offset<T> root,
                          const char *file_identifier = nullptr) {
    Finish(root.o, file_identifier, true);
  }

  void SwapBufAllocator(FlatBufferBuilderImpl &other) {
    buf_.swap_allocator(other.buf_);
  }

  /// @brief The length of a FlatBuffer file header.
  static const size_t kFileIdentifierLength =
      ::flatbuffers::kFileIdentifierLength;

 protected:
  // You shouldn't really be copying instances of this class.
  FlatBufferBuilderImpl(const FlatBufferBuilderImpl &);
  FlatBufferBuilderImpl &operator=(const FlatBufferBuilderImpl &);

  void Finish(uoffset_t root, const char *file_identifier, bool size_prefix) {
    // A buffer can only be finished once. To reuse a builder use `clear()`.
    FLATBUFFERS_ASSERT(!finished);

    NotNested();
    buf_.clear_scratch();

    const size_t prefix_size = size_prefix ? sizeof(SizeT) : 0;
    // Make sure we track the alignment of the size prefix.
    TrackMinAlign(prefix_size);

    const size_t root_offset_size = sizeof(uoffset_t);
    const size_t file_id_size = file_identifier ? kFileIdentifierLength : 0;

    // This will cause the whole buffer to be aligned.
    PreAlign(prefix_size + root_offset_size + file_id_size, minalign_);

    if (file_identifier) {
      FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength);
      PushBytes(reinterpret_cast<const uint8_t *>(file_identifier),
                kFileIdentifierLength);
    }
    PushElement(ReferTo(root));  // Location of root.
    if (size_prefix) { PushElement(GetSize()); }
    finished = true;
  }

  struct FieldLoc {
    uoffset_t off;
    voffset_t id;
  };

  vector_downward<SizeT> buf_;

  // Accumulating offsets of table members while it is being built.
  // We store these in the scratch pad of buf_, after the vtable offsets.
  uoffset_t num_field_loc;
  // Track how much of the vtable is in use, so we can output the most compact
  // possible vtable.
  voffset_t max_voffset_;

  // This is the length of the 64-bit region of the buffer. The buffer supports
  // 64-bit offsets by forcing serialization of those elements in the "tail"
  // region of the buffer (i.e. "64-bit region"). To properly keep track of
  // offsets that are referenced from the tail of the buffer to not overflow
  // their size (e.g. Offset is a uint32_t type), the boundary of the 32-/64-bit
  // regions must be tracked.
  //
  // [    Complete FlatBuffer     ]
  // [32-bit region][64-bit region]
  //               ^              ^
  //               |              Tail of the buffer.
  //               |
  //               Tail of the 32-bit region of the buffer.
  //
  // This keeps track of the size of the 64-bit region so that the tail of the
  // 32-bit region can be calculated as `GetSize() - length_of_64_bit_region_`.
  //
  // This will remain 0 if no 64-bit offset types are added to the buffer.
  size_t length_of_64_bit_region_;

  // Ensure objects are not nested.
  bool nested;

  // Ensure the buffer is finished before it is being accessed.
  bool finished;

  size_t minalign_;

  bool force_defaults_;  // Serialize values equal to their defaults anyway.

  bool dedup_vtables_;

  struct StringOffsetCompare {
    explicit StringOffsetCompare(const vector_downward<SizeT> &buf)
        : buf_(&buf) {}
    bool operator()(const Offset<String> &a, const Offset<String> &b) const {
      auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
      auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
      return StringLessThan(stra->data(), stra->size(), strb->data(),
                            strb->size());
    }
    const vector_downward<SizeT> *buf_;
  };

  // For use with CreateSharedString. Instantiated on first use only.
  typedef std::set<Offset<String>, StringOffsetCompare> StringOffsetMap;
  StringOffsetMap *string_pool;

 private:
  void CanAddOffset64() {
    // If you hit this assertion, you are attempting to add a 64-bit offset to
    // a 32-bit only builder. This is because the builder has overloads that
    // differ only on the offset size returned: e.g.:
    //
    //   FlatBufferBuilder builder;
    //   Offset64<String> string_offset = builder.CreateString<Offset64>();
    //
    // Either use a 64-bit aware builder, or don't try to create an Offset64
    // return type.
    //
    // TODO(derekbailey): we can probably do more enable_if to avoid this
    // looking like its possible to the user.
    static_assert(Is64Aware, "cannot add 64-bit offset to a 32-bit builder");

    // If you hit this assertion, you are attempting to add an 64-bit offset
    // item after already serializing a 32-bit item. All 64-bit offsets have to
    // added to the tail of the buffer before any 32-bit items can be added.
    // Otherwise some items might not be addressable due to the maximum range of
    // the 32-bit offset.
    FLATBUFFERS_ASSERT(GetSize() == length_of_64_bit_region_);
  }

  /// @brief Store a string in the buffer, which can contain any binary data.
  /// @param[in] str A const char pointer to the data to be stored as a string.
  /// @param[in] len The number of bytes that should be stored from `str`.
  /// @return Returns the offset in the buffer where the string starts.
  void CreateStringImpl(const char *str, size_t len) {
    NotNested();
    PreAlign<uoffset_t>(len + 1);  // Always 0-terminated.
    buf_.fill(1);
    PushBytes(reinterpret_cast<const uint8_t *>(str), len);
    PushElement(static_cast<uoffset_t>(len));
  }

  // Allocates space for a vector of structures.
  // Must be completed with EndVectorOfStructs().
  template<typename T, template<typename> class OffsetT = Offset>
  T *StartVectorOfStructs(size_t vector_size) {
    StartVector<OffsetT>(vector_size, sizeof(T), AlignOf<T>());
    return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
  }

  // End the vector of structures in the flatbuffers.
  // Vector should have previously be started with StartVectorOfStructs().
  template<typename T, template<typename> class OffsetT = Offset>
  OffsetT<Vector<const T *>> EndVectorOfStructs(size_t vector_size) {
    return OffsetT<Vector<const T *>>(
        EndVector<typename Vector<const T *>::size_type,
                  typename OffsetT<Vector<const T *>>::offset_type>(
            vector_size));
  }

  template<typename T>
  typename std::enable_if<std::is_same<T, uoffset_t>::value, T>::type
  CalculateOffset() {
    // Default to the end of the 32-bit region. This may or may not be the end
    // of the buffer, depending on if any 64-bit offsets have been added.
    return GetSizeRelative32BitRegion();
  }

  // Specializations to handle the 64-bit CalculateOffset, which is relative to
  // end of the buffer.
  template<typename T>
  typename std::enable_if<std::is_same<T, uoffset64_t>::value, T>::type
  CalculateOffset() {
    // This should never be compiled in when not using a 64-bit builder.
    static_assert(Is64Aware, "invalid 64-bit offset in 32-bit builder");

    // Store how big the 64-bit region of the buffer is, so we can determine
    // where the 32/64 bit boundary is.
    length_of_64_bit_region_ = GetSize();

    return length_of_64_bit_region_;
  }
};
/// @}

// Hack to `FlatBufferBuilder` mean `FlatBufferBuilder<false>` or
// `FlatBufferBuilder<>`, where the template < > syntax is required.
using FlatBufferBuilder = FlatBufferBuilderImpl<false>;
using FlatBufferBuilder64 = FlatBufferBuilderImpl<true>;

// These are external due to GCC not allowing them in the class.
// See: https://stackoverflow.com/q/8061456/868247
template<>
template<>
inline Offset64<String> FlatBufferBuilder64::CreateString(const char *str,
                                                          size_t len) {
  CanAddOffset64();
  CreateStringImpl(str, len);
  return Offset64<String>(
      CalculateOffset<typename Offset64<String>::offset_type>());
}

// Used to distinguish from real Offsets.
template<typename T = void> struct EmptyOffset {};

// TODO(derekbailey): it would be nice to combine these two methods.
template<>
template<>
inline void FlatBufferBuilder64::StartVector<Offset64, uint32_t>(
    size_t len, size_t elemsize, size_t alignment) {
  CanAddOffset64();
  StartVector<EmptyOffset, uint32_t>(len, elemsize, alignment);
}

template<>
template<>
inline void FlatBufferBuilder64::StartVector<Offset64, uint64_t>(
    size_t len, size_t elemsize, size_t alignment) {
  CanAddOffset64();
  StartVector<EmptyOffset, uint64_t>(len, elemsize, alignment);
}

/// Helpers to get a typed pointer to objects that are currently being built.
/// @warning Creating new objects will lead to reallocations and invalidates
/// the pointer!
template<typename T>
T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
  return reinterpret_cast<T *>(fbb.GetCurrentBufferPointer() + fbb.GetSize() -
                               offset.o);
}

template<typename T>
const T *GetTemporaryPointer(const FlatBufferBuilder &fbb, Offset<T> offset) {
  return GetMutableTemporaryPointer<T>(fbb, offset);
}

}  // namespace flatbuffers

#endif  // FLATBUFFERS_FLATBUFFER_BUILDER_H_
