diff --git a/include/flatbuffers/reflection_generated.h b/include/flatbuffers/reflection_generated.h
new file mode 100644
index 0000000..0e73a0f
--- /dev/null
+++ b/include/flatbuffers/reflection_generated.h
@@ -0,0 +1,1195 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_
+#define FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace reflection {
+
+struct Type;
+
+struct KeyValue;
+
+struct EnumVal;
+
+struct Enum;
+
+struct Field;
+
+struct Object;
+
+struct RPCCall;
+
+struct Service;
+
+struct Schema;
+
+enum BaseType {
+  None = 0,
+  UType = 1,
+  Bool = 2,
+  Byte = 3,
+  UByte = 4,
+  Short = 5,
+  UShort = 6,
+  Int = 7,
+  UInt = 8,
+  Long = 9,
+  ULong = 10,
+  Float = 11,
+  Double = 12,
+  String = 13,
+  Vector = 14,
+  Obj = 15,
+  Union = 16,
+  Array = 17
+};
+
+inline const BaseType (&EnumValuesBaseType())[18] {
+  static const BaseType values[] = {
+    None,
+    UType,
+    Bool,
+    Byte,
+    UByte,
+    Short,
+    UShort,
+    Int,
+    UInt,
+    Long,
+    ULong,
+    Float,
+    Double,
+    String,
+    Vector,
+    Obj,
+    Union,
+    Array
+  };
+  return values;
+}
+
+inline const char * const *EnumNamesBaseType() {
+  static const char * const names[19] = {
+    "None",
+    "UType",
+    "Bool",
+    "Byte",
+    "UByte",
+    "Short",
+    "UShort",
+    "Int",
+    "UInt",
+    "Long",
+    "ULong",
+    "Float",
+    "Double",
+    "String",
+    "Vector",
+    "Obj",
+    "Union",
+    "Array",
+    nullptr
+  };
+  return names;
+}
+
+inline const char *EnumNameBaseType(BaseType e) {
+  if (e < None || e > Array) return "";
+  const size_t index = static_cast<size_t>(e);
+  return EnumNamesBaseType()[index];
+}
+
+struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_BASE_TYPE = 4,
+    VT_ELEMENT = 6,
+    VT_INDEX = 8,
+    VT_FIXED_LENGTH = 10
+  };
+  reflection::BaseType base_type() const {
+    return static_cast<reflection::BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0));
+  }
+  reflection::BaseType element() const {
+    return static_cast<reflection::BaseType>(GetField<int8_t>(VT_ELEMENT, 0));
+  }
+  int32_t index() const {
+    return GetField<int32_t>(VT_INDEX, -1);
+  }
+  uint16_t fixed_length() const {
+    return GetField<uint16_t>(VT_FIXED_LENGTH, 0);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyField<int8_t>(verifier, VT_BASE_TYPE) &&
+           VerifyField<int8_t>(verifier, VT_ELEMENT) &&
+           VerifyField<int32_t>(verifier, VT_INDEX) &&
+           VerifyField<uint16_t>(verifier, VT_FIXED_LENGTH) &&
+           verifier.EndTable();
+  }
+};
+
+struct TypeBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_base_type(reflection::BaseType base_type) {
+    fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0);
+  }
+  void add_element(reflection::BaseType element) {
+    fbb_.AddElement<int8_t>(Type::VT_ELEMENT, static_cast<int8_t>(element), 0);
+  }
+  void add_index(int32_t index) {
+    fbb_.AddElement<int32_t>(Type::VT_INDEX, index, -1);
+  }
+  void add_fixed_length(uint16_t fixed_length) {
+    fbb_.AddElement<uint16_t>(Type::VT_FIXED_LENGTH, fixed_length, 0);
+  }
+  explicit TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  TypeBuilder &operator=(const TypeBuilder &);
+  flatbuffers::Offset<Type> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Type>(end);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Type> CreateType(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    reflection::BaseType base_type = reflection::None,
+    reflection::BaseType element = reflection::None,
+    int32_t index = -1,
+    uint16_t fixed_length = 0) {
+  TypeBuilder builder_(_fbb);
+  builder_.add_index(index);
+  builder_.add_fixed_length(fixed_length);
+  builder_.add_element(element);
+  builder_.add_base_type(base_type);
+  return builder_.Finish();
+}
+
+struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_KEY = 4,
+    VT_VALUE = 6
+  };
+  const flatbuffers::String *key() const {
+    return GetPointer<const flatbuffers::String *>(VT_KEY);
+  }
+  bool KeyCompareLessThan(const KeyValue *o) const {
+    return *key() < *o->key();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(key()->c_str(), val);
+  }
+  const flatbuffers::String *value() const {
+    return GetPointer<const flatbuffers::String *>(VT_VALUE);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_KEY) &&
+           verifier.VerifyString(key()) &&
+           VerifyOffset(verifier, VT_VALUE) &&
+           verifier.VerifyString(value()) &&
+           verifier.EndTable();
+  }
+};
+
+struct KeyValueBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_key(flatbuffers::Offset<flatbuffers::String> key) {
+    fbb_.AddOffset(KeyValue::VT_KEY, key);
+  }
+  void add_value(flatbuffers::Offset<flatbuffers::String> value) {
+    fbb_.AddOffset(KeyValue::VT_VALUE, value);
+  }
+  explicit KeyValueBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  KeyValueBuilder &operator=(const KeyValueBuilder &);
+  flatbuffers::Offset<KeyValue> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<KeyValue>(end);
+    fbb_.Required(o, KeyValue::VT_KEY);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<KeyValue> CreateKeyValue(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> key = 0,
+    flatbuffers::Offset<flatbuffers::String> value = 0) {
+  KeyValueBuilder builder_(_fbb);
+  builder_.add_value(value);
+  builder_.add_key(key);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *key = nullptr,
+    const char *value = nullptr) {
+  auto key__ = key ? _fbb.CreateString(key) : 0;
+  auto value__ = value ? _fbb.CreateString(value) : 0;
+  return reflection::CreateKeyValue(
+      _fbb,
+      key__,
+      value__);
+}
+
+struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_VALUE = 6,
+    VT_OBJECT = 8,
+    VT_UNION_TYPE = 10,
+    VT_DOCUMENTATION = 12
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  int64_t value() const {
+    return GetField<int64_t>(VT_VALUE, 0);
+  }
+  bool KeyCompareLessThan(const EnumVal *o) const {
+    return value() < o->value();
+  }
+  int KeyCompareWithValue(int64_t val) const {
+    return static_cast<int>(value() > val) - static_cast<int>(value() < val);
+  }
+  const reflection::Object *object() const {
+    return GetPointer<const reflection::Object *>(VT_OBJECT);
+  }
+  const reflection::Type *union_type() const {
+    return GetPointer<const reflection::Type *>(VT_UNION_TYPE);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyField<int64_t>(verifier, VT_VALUE) &&
+           VerifyOffset(verifier, VT_OBJECT) &&
+           verifier.VerifyTable(object()) &&
+           VerifyOffset(verifier, VT_UNION_TYPE) &&
+           verifier.VerifyTable(union_type()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct EnumValBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(EnumVal::VT_NAME, name);
+  }
+  void add_value(int64_t value) {
+    fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0);
+  }
+  void add_object(flatbuffers::Offset<reflection::Object> object) {
+    fbb_.AddOffset(EnumVal::VT_OBJECT, object);
+  }
+  void add_union_type(flatbuffers::Offset<reflection::Type> union_type) {
+    fbb_.AddOffset(EnumVal::VT_UNION_TYPE, union_type);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(EnumVal::VT_DOCUMENTATION, documentation);
+  }
+  explicit EnumValBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  EnumValBuilder &operator=(const EnumValBuilder &);
+  flatbuffers::Offset<EnumVal> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<EnumVal>(end);
+    fbb_.Required(o, EnumVal::VT_NAME);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<EnumVal> CreateEnumVal(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    int64_t value = 0,
+    flatbuffers::Offset<reflection::Object> object = 0,
+    flatbuffers::Offset<reflection::Type> union_type = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  EnumValBuilder builder_(_fbb);
+  builder_.add_value(value);
+  builder_.add_documentation(documentation);
+  builder_.add_union_type(union_type);
+  builder_.add_object(object);
+  builder_.add_name(name);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    int64_t value = 0,
+    flatbuffers::Offset<reflection::Object> object = 0,
+    flatbuffers::Offset<reflection::Type> union_type = 0,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateEnumVal(
+      _fbb,
+      name__,
+      value,
+      object,
+      union_type,
+      documentation__);
+}
+
+struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_VALUES = 6,
+    VT_IS_UNION = 8,
+    VT_UNDERLYING_TYPE = 10,
+    VT_ATTRIBUTES = 12,
+    VT_DOCUMENTATION = 14
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const Enum *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *values() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *>(VT_VALUES);
+  }
+  bool is_union() const {
+    return GetField<uint8_t>(VT_IS_UNION, 0) != 0;
+  }
+  const reflection::Type *underlying_type() const {
+    return GetPointer<const reflection::Type *>(VT_UNDERLYING_TYPE);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffsetRequired(verifier, VT_VALUES) &&
+           verifier.VerifyVector(values()) &&
+           verifier.VerifyVectorOfTables(values()) &&
+           VerifyField<uint8_t>(verifier, VT_IS_UNION) &&
+           VerifyOffsetRequired(verifier, VT_UNDERLYING_TYPE) &&
+           verifier.VerifyTable(underlying_type()) &&
+           VerifyOffset(verifier, VT_ATTRIBUTES) &&
+           verifier.VerifyVector(attributes()) &&
+           verifier.VerifyVectorOfTables(attributes()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct EnumBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Enum::VT_NAME, name);
+  }
+  void add_values(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values) {
+    fbb_.AddOffset(Enum::VT_VALUES, values);
+  }
+  void add_is_union(bool is_union) {
+    fbb_.AddElement<uint8_t>(Enum::VT_IS_UNION, static_cast<uint8_t>(is_union), 0);
+  }
+  void add_underlying_type(flatbuffers::Offset<reflection::Type> underlying_type) {
+    fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type);
+  }
+  void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+    fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(Enum::VT_DOCUMENTATION, documentation);
+  }
+  explicit EnumBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  EnumBuilder &operator=(const EnumBuilder &);
+  flatbuffers::Offset<Enum> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Enum>(end);
+    fbb_.Required(o, Enum::VT_NAME);
+    fbb_.Required(o, Enum::VT_VALUES);
+    fbb_.Required(o, Enum::VT_UNDERLYING_TYPE);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Enum> CreateEnum(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values = 0,
+    bool is_union = false,
+    flatbuffers::Offset<reflection::Type> underlying_type = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  EnumBuilder builder_(_fbb);
+  builder_.add_documentation(documentation);
+  builder_.add_attributes(attributes);
+  builder_.add_underlying_type(underlying_type);
+  builder_.add_values(values);
+  builder_.add_name(name);
+  builder_.add_is_union(is_union);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Enum> CreateEnumDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    const std::vector<flatbuffers::Offset<reflection::EnumVal>> *values = nullptr,
+    bool is_union = false,
+    flatbuffers::Offset<reflection::Type> underlying_type = 0,
+    const std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto values__ = values ? _fbb.CreateVector<flatbuffers::Offset<reflection::EnumVal>>(*values) : 0;
+  auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<reflection::KeyValue>>(*attributes) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateEnum(
+      _fbb,
+      name__,
+      values__,
+      is_union,
+      underlying_type,
+      attributes__,
+      documentation__);
+}
+
+struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_TYPE = 6,
+    VT_ID = 8,
+    VT_OFFSET = 10,
+    VT_DEFAULT_INTEGER = 12,
+    VT_DEFAULT_REAL = 14,
+    VT_DEPRECATED = 16,
+    VT_REQUIRED = 18,
+    VT_KEY = 20,
+    VT_ATTRIBUTES = 22,
+    VT_DOCUMENTATION = 24
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const Field *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const reflection::Type *type() const {
+    return GetPointer<const reflection::Type *>(VT_TYPE);
+  }
+  uint16_t id() const {
+    return GetField<uint16_t>(VT_ID, 0);
+  }
+  uint16_t offset() const {
+    return GetField<uint16_t>(VT_OFFSET, 0);
+  }
+  int64_t default_integer() const {
+    return GetField<int64_t>(VT_DEFAULT_INTEGER, 0);
+  }
+  double default_real() const {
+    return GetField<double>(VT_DEFAULT_REAL, 0.0);
+  }
+  bool deprecated() const {
+    return GetField<uint8_t>(VT_DEPRECATED, 0) != 0;
+  }
+  bool required() const {
+    return GetField<uint8_t>(VT_REQUIRED, 0) != 0;
+  }
+  bool key() const {
+    return GetField<uint8_t>(VT_KEY, 0) != 0;
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffsetRequired(verifier, VT_TYPE) &&
+           verifier.VerifyTable(type()) &&
+           VerifyField<uint16_t>(verifier, VT_ID) &&
+           VerifyField<uint16_t>(verifier, VT_OFFSET) &&
+           VerifyField<int64_t>(verifier, VT_DEFAULT_INTEGER) &&
+           VerifyField<double>(verifier, VT_DEFAULT_REAL) &&
+           VerifyField<uint8_t>(verifier, VT_DEPRECATED) &&
+           VerifyField<uint8_t>(verifier, VT_REQUIRED) &&
+           VerifyField<uint8_t>(verifier, VT_KEY) &&
+           VerifyOffset(verifier, VT_ATTRIBUTES) &&
+           verifier.VerifyVector(attributes()) &&
+           verifier.VerifyVectorOfTables(attributes()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct FieldBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Field::VT_NAME, name);
+  }
+  void add_type(flatbuffers::Offset<reflection::Type> type) {
+    fbb_.AddOffset(Field::VT_TYPE, type);
+  }
+  void add_id(uint16_t id) {
+    fbb_.AddElement<uint16_t>(Field::VT_ID, id, 0);
+  }
+  void add_offset(uint16_t offset) {
+    fbb_.AddElement<uint16_t>(Field::VT_OFFSET, offset, 0);
+  }
+  void add_default_integer(int64_t default_integer) {
+    fbb_.AddElement<int64_t>(Field::VT_DEFAULT_INTEGER, default_integer, 0);
+  }
+  void add_default_real(double default_real) {
+    fbb_.AddElement<double>(Field::VT_DEFAULT_REAL, default_real, 0.0);
+  }
+  void add_deprecated(bool deprecated) {
+    fbb_.AddElement<uint8_t>(Field::VT_DEPRECATED, static_cast<uint8_t>(deprecated), 0);
+  }
+  void add_required(bool required) {
+    fbb_.AddElement<uint8_t>(Field::VT_REQUIRED, static_cast<uint8_t>(required), 0);
+  }
+  void add_key(bool key) {
+    fbb_.AddElement<uint8_t>(Field::VT_KEY, static_cast<uint8_t>(key), 0);
+  }
+  void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+    fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(Field::VT_DOCUMENTATION, documentation);
+  }
+  explicit FieldBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  FieldBuilder &operator=(const FieldBuilder &);
+  flatbuffers::Offset<Field> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Field>(end);
+    fbb_.Required(o, Field::VT_NAME);
+    fbb_.Required(o, Field::VT_TYPE);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Field> CreateField(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<reflection::Type> type = 0,
+    uint16_t id = 0,
+    uint16_t offset = 0,
+    int64_t default_integer = 0,
+    double default_real = 0.0,
+    bool deprecated = false,
+    bool required = false,
+    bool key = false,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  FieldBuilder builder_(_fbb);
+  builder_.add_default_real(default_real);
+  builder_.add_default_integer(default_integer);
+  builder_.add_documentation(documentation);
+  builder_.add_attributes(attributes);
+  builder_.add_type(type);
+  builder_.add_name(name);
+  builder_.add_offset(offset);
+  builder_.add_id(id);
+  builder_.add_key(key);
+  builder_.add_required(required);
+  builder_.add_deprecated(deprecated);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Field> CreateFieldDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    flatbuffers::Offset<reflection::Type> type = 0,
+    uint16_t id = 0,
+    uint16_t offset = 0,
+    int64_t default_integer = 0,
+    double default_real = 0.0,
+    bool deprecated = false,
+    bool required = false,
+    bool key = false,
+    const std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<reflection::KeyValue>>(*attributes) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateField(
+      _fbb,
+      name__,
+      type,
+      id,
+      offset,
+      default_integer,
+      default_real,
+      deprecated,
+      required,
+      key,
+      attributes__,
+      documentation__);
+}
+
+struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_FIELDS = 6,
+    VT_IS_STRUCT = 8,
+    VT_MINALIGN = 10,
+    VT_BYTESIZE = 12,
+    VT_ATTRIBUTES = 14,
+    VT_DOCUMENTATION = 16
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const Object *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *fields() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *>(VT_FIELDS);
+  }
+  bool is_struct() const {
+    return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0;
+  }
+  int32_t minalign() const {
+    return GetField<int32_t>(VT_MINALIGN, 0);
+  }
+  int32_t bytesize() const {
+    return GetField<int32_t>(VT_BYTESIZE, 0);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffsetRequired(verifier, VT_FIELDS) &&
+           verifier.VerifyVector(fields()) &&
+           verifier.VerifyVectorOfTables(fields()) &&
+           VerifyField<uint8_t>(verifier, VT_IS_STRUCT) &&
+           VerifyField<int32_t>(verifier, VT_MINALIGN) &&
+           VerifyField<int32_t>(verifier, VT_BYTESIZE) &&
+           VerifyOffset(verifier, VT_ATTRIBUTES) &&
+           verifier.VerifyVector(attributes()) &&
+           verifier.VerifyVectorOfTables(attributes()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct ObjectBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Object::VT_NAME, name);
+  }
+  void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields) {
+    fbb_.AddOffset(Object::VT_FIELDS, fields);
+  }
+  void add_is_struct(bool is_struct) {
+    fbb_.AddElement<uint8_t>(Object::VT_IS_STRUCT, static_cast<uint8_t>(is_struct), 0);
+  }
+  void add_minalign(int32_t minalign) {
+    fbb_.AddElement<int32_t>(Object::VT_MINALIGN, minalign, 0);
+  }
+  void add_bytesize(int32_t bytesize) {
+    fbb_.AddElement<int32_t>(Object::VT_BYTESIZE, bytesize, 0);
+  }
+  void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+    fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(Object::VT_DOCUMENTATION, documentation);
+  }
+  explicit ObjectBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  ObjectBuilder &operator=(const ObjectBuilder &);
+  flatbuffers::Offset<Object> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Object>(end);
+    fbb_.Required(o, Object::VT_NAME);
+    fbb_.Required(o, Object::VT_FIELDS);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Object> CreateObject(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields = 0,
+    bool is_struct = false,
+    int32_t minalign = 0,
+    int32_t bytesize = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  ObjectBuilder builder_(_fbb);
+  builder_.add_documentation(documentation);
+  builder_.add_attributes(attributes);
+  builder_.add_bytesize(bytesize);
+  builder_.add_minalign(minalign);
+  builder_.add_fields(fields);
+  builder_.add_name(name);
+  builder_.add_is_struct(is_struct);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Object> CreateObjectDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    const std::vector<flatbuffers::Offset<reflection::Field>> *fields = nullptr,
+    bool is_struct = false,
+    int32_t minalign = 0,
+    int32_t bytesize = 0,
+    const std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto fields__ = fields ? _fbb.CreateVector<flatbuffers::Offset<reflection::Field>>(*fields) : 0;
+  auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<reflection::KeyValue>>(*attributes) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateObject(
+      _fbb,
+      name__,
+      fields__,
+      is_struct,
+      minalign,
+      bytesize,
+      attributes__,
+      documentation__);
+}
+
+struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_REQUEST = 6,
+    VT_RESPONSE = 8,
+    VT_ATTRIBUTES = 10,
+    VT_DOCUMENTATION = 12
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const RPCCall *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const reflection::Object *request() const {
+    return GetPointer<const reflection::Object *>(VT_REQUEST);
+  }
+  const reflection::Object *response() const {
+    return GetPointer<const reflection::Object *>(VT_RESPONSE);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffsetRequired(verifier, VT_REQUEST) &&
+           verifier.VerifyTable(request()) &&
+           VerifyOffsetRequired(verifier, VT_RESPONSE) &&
+           verifier.VerifyTable(response()) &&
+           VerifyOffset(verifier, VT_ATTRIBUTES) &&
+           verifier.VerifyVector(attributes()) &&
+           verifier.VerifyVectorOfTables(attributes()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct RPCCallBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(RPCCall::VT_NAME, name);
+  }
+  void add_request(flatbuffers::Offset<reflection::Object> request) {
+    fbb_.AddOffset(RPCCall::VT_REQUEST, request);
+  }
+  void add_response(flatbuffers::Offset<reflection::Object> response) {
+    fbb_.AddOffset(RPCCall::VT_RESPONSE, response);
+  }
+  void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+    fbb_.AddOffset(RPCCall::VT_ATTRIBUTES, attributes);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(RPCCall::VT_DOCUMENTATION, documentation);
+  }
+  explicit RPCCallBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  RPCCallBuilder &operator=(const RPCCallBuilder &);
+  flatbuffers::Offset<RPCCall> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<RPCCall>(end);
+    fbb_.Required(o, RPCCall::VT_NAME);
+    fbb_.Required(o, RPCCall::VT_REQUEST);
+    fbb_.Required(o, RPCCall::VT_RESPONSE);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<RPCCall> CreateRPCCall(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<reflection::Object> request = 0,
+    flatbuffers::Offset<reflection::Object> response = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  RPCCallBuilder builder_(_fbb);
+  builder_.add_documentation(documentation);
+  builder_.add_attributes(attributes);
+  builder_.add_response(response);
+  builder_.add_request(request);
+  builder_.add_name(name);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    flatbuffers::Offset<reflection::Object> request = 0,
+    flatbuffers::Offset<reflection::Object> response = 0,
+    const std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<reflection::KeyValue>>(*attributes) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateRPCCall(
+      _fbb,
+      name__,
+      request,
+      response,
+      attributes__,
+      documentation__);
+}
+
+struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_NAME = 4,
+    VT_CALLS = 6,
+    VT_ATTRIBUTES = 8,
+    VT_DOCUMENTATION = 10
+  };
+  const flatbuffers::String *name() const {
+    return GetPointer<const flatbuffers::String *>(VT_NAME);
+  }
+  bool KeyCompareLessThan(const Service *o) const {
+    return *name() < *o->name();
+  }
+  int KeyCompareWithValue(const char *val) const {
+    return strcmp(name()->c_str(), val);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *calls() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *>(VT_CALLS);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_NAME) &&
+           verifier.VerifyString(name()) &&
+           VerifyOffset(verifier, VT_CALLS) &&
+           verifier.VerifyVector(calls()) &&
+           verifier.VerifyVectorOfTables(calls()) &&
+           VerifyOffset(verifier, VT_ATTRIBUTES) &&
+           verifier.VerifyVector(attributes()) &&
+           verifier.VerifyVectorOfTables(attributes()) &&
+           VerifyOffset(verifier, VT_DOCUMENTATION) &&
+           verifier.VerifyVector(documentation()) &&
+           verifier.VerifyVectorOfStrings(documentation()) &&
+           verifier.EndTable();
+  }
+};
+
+struct ServiceBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+    fbb_.AddOffset(Service::VT_NAME, name);
+  }
+  void add_calls(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls) {
+    fbb_.AddOffset(Service::VT_CALLS, calls);
+  }
+  void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+    fbb_.AddOffset(Service::VT_ATTRIBUTES, attributes);
+  }
+  void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+    fbb_.AddOffset(Service::VT_DOCUMENTATION, documentation);
+  }
+  explicit ServiceBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  ServiceBuilder &operator=(const ServiceBuilder &);
+  flatbuffers::Offset<Service> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Service>(end);
+    fbb_.Required(o, Service::VT_NAME);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Service> CreateService(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::String> name = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+  ServiceBuilder builder_(_fbb);
+  builder_.add_documentation(documentation);
+  builder_.add_attributes(attributes);
+  builder_.add_calls(calls);
+  builder_.add_name(name);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Service> CreateServiceDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const char *name = nullptr,
+    const std::vector<flatbuffers::Offset<reflection::RPCCall>> *calls = nullptr,
+    const std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+    const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+  auto name__ = name ? _fbb.CreateString(name) : 0;
+  auto calls__ = calls ? _fbb.CreateVector<flatbuffers::Offset<reflection::RPCCall>>(*calls) : 0;
+  auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<reflection::KeyValue>>(*attributes) : 0;
+  auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+  return reflection::CreateService(
+      _fbb,
+      name__,
+      calls__,
+      attributes__,
+      documentation__);
+}
+
+struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+    VT_OBJECTS = 4,
+    VT_ENUMS = 6,
+    VT_FILE_IDENT = 8,
+    VT_FILE_EXT = 10,
+    VT_ROOT_TABLE = 12,
+    VT_SERVICES = 14
+  };
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *objects() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *>(VT_OBJECTS);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *enums() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *>(VT_ENUMS);
+  }
+  const flatbuffers::String *file_ident() const {
+    return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT);
+  }
+  const flatbuffers::String *file_ext() const {
+    return GetPointer<const flatbuffers::String *>(VT_FILE_EXT);
+  }
+  const reflection::Object *root_table() const {
+    return GetPointer<const reflection::Object *>(VT_ROOT_TABLE);
+  }
+  const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *services() const {
+    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *>(VT_SERVICES);
+  }
+  bool Verify(flatbuffers::Verifier &verifier) const {
+    return VerifyTableStart(verifier) &&
+           VerifyOffsetRequired(verifier, VT_OBJECTS) &&
+           verifier.VerifyVector(objects()) &&
+           verifier.VerifyVectorOfTables(objects()) &&
+           VerifyOffsetRequired(verifier, VT_ENUMS) &&
+           verifier.VerifyVector(enums()) &&
+           verifier.VerifyVectorOfTables(enums()) &&
+           VerifyOffset(verifier, VT_FILE_IDENT) &&
+           verifier.VerifyString(file_ident()) &&
+           VerifyOffset(verifier, VT_FILE_EXT) &&
+           verifier.VerifyString(file_ext()) &&
+           VerifyOffset(verifier, VT_ROOT_TABLE) &&
+           verifier.VerifyTable(root_table()) &&
+           VerifyOffset(verifier, VT_SERVICES) &&
+           verifier.VerifyVector(services()) &&
+           verifier.VerifyVectorOfTables(services()) &&
+           verifier.EndTable();
+  }
+};
+
+struct SchemaBuilder {
+  flatbuffers::FlatBufferBuilder &fbb_;
+  flatbuffers::uoffset_t start_;
+  void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects) {
+    fbb_.AddOffset(Schema::VT_OBJECTS, objects);
+  }
+  void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums) {
+    fbb_.AddOffset(Schema::VT_ENUMS, enums);
+  }
+  void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) {
+    fbb_.AddOffset(Schema::VT_FILE_IDENT, file_ident);
+  }
+  void add_file_ext(flatbuffers::Offset<flatbuffers::String> file_ext) {
+    fbb_.AddOffset(Schema::VT_FILE_EXT, file_ext);
+  }
+  void add_root_table(flatbuffers::Offset<reflection::Object> root_table) {
+    fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table);
+  }
+  void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services) {
+    fbb_.AddOffset(Schema::VT_SERVICES, services);
+  }
+  explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+        : fbb_(_fbb) {
+    start_ = fbb_.StartTable();
+  }
+  SchemaBuilder &operator=(const SchemaBuilder &);
+  flatbuffers::Offset<Schema> Finish() {
+    const auto end = fbb_.EndTable(start_);
+    auto o = flatbuffers::Offset<Schema>(end);
+    fbb_.Required(o, Schema::VT_OBJECTS);
+    fbb_.Required(o, Schema::VT_ENUMS);
+    return o;
+  }
+};
+
+inline flatbuffers::Offset<Schema> CreateSchema(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums = 0,
+    flatbuffers::Offset<flatbuffers::String> file_ident = 0,
+    flatbuffers::Offset<flatbuffers::String> file_ext = 0,
+    flatbuffers::Offset<reflection::Object> root_table = 0,
+    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services = 0) {
+  SchemaBuilder builder_(_fbb);
+  builder_.add_services(services);
+  builder_.add_root_table(root_table);
+  builder_.add_file_ext(file_ext);
+  builder_.add_file_ident(file_ident);
+  builder_.add_enums(enums);
+  builder_.add_objects(objects);
+  return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Schema> CreateSchemaDirect(
+    flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<flatbuffers::Offset<reflection::Object>> *objects = nullptr,
+    const std::vector<flatbuffers::Offset<reflection::Enum>> *enums = nullptr,
+    const char *file_ident = nullptr,
+    const char *file_ext = nullptr,
+    flatbuffers::Offset<reflection::Object> root_table = 0,
+    const std::vector<flatbuffers::Offset<reflection::Service>> *services = nullptr) {
+  auto objects__ = objects ? _fbb.CreateVector<flatbuffers::Offset<reflection::Object>>(*objects) : 0;
+  auto enums__ = enums ? _fbb.CreateVector<flatbuffers::Offset<reflection::Enum>>(*enums) : 0;
+  auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0;
+  auto file_ext__ = file_ext ? _fbb.CreateString(file_ext) : 0;
+  auto services__ = services ? _fbb.CreateVector<flatbuffers::Offset<reflection::Service>>(*services) : 0;
+  return reflection::CreateSchema(
+      _fbb,
+      objects__,
+      enums__,
+      file_ident__,
+      file_ext__,
+      root_table,
+      services__);
+}
+
+inline const reflection::Schema *GetSchema(const void *buf) {
+  return flatbuffers::GetRoot<reflection::Schema>(buf);
+}
+
+inline const reflection::Schema *GetSizePrefixedSchema(const void *buf) {
+  return flatbuffers::GetSizePrefixedRoot<reflection::Schema>(buf);
+}
+
+inline const char *SchemaIdentifier() {
+  return "BFBS";
+}
+
+inline bool SchemaBufferHasIdentifier(const void *buf) {
+  return flatbuffers::BufferHasIdentifier(
+      buf, SchemaIdentifier());
+}
+
+inline bool VerifySchemaBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier());
+}
+
+inline bool VerifySizePrefixedSchemaBuffer(
+    flatbuffers::Verifier &verifier) {
+  return verifier.VerifySizePrefixedBuffer<reflection::Schema>(SchemaIdentifier());
+}
+
+inline const char *SchemaExtension() {
+  return "bfbs";
+}
+
+inline void FinishSchemaBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<reflection::Schema> root) {
+  fbb.Finish(root, SchemaIdentifier());
+}
+
+inline void FinishSizePrefixedSchemaBuffer(
+    flatbuffers::FlatBufferBuilder &fbb,
+    flatbuffers::Offset<reflection::Schema> root) {
+  fbb.FinishSizePrefixed(root, SchemaIdentifier());
+}
+
+}  // namespace reflection
+
+#endif  // FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_
