diff --git a/src/reflection.cpp b/src/reflection.cpp
index 6bba28c..9abfd9f 100644
--- a/src/reflection.cpp
+++ b/src/reflection.cpp
@@ -22,6 +22,238 @@
 
 namespace flatbuffers {
 
+namespace {
+
+static void CopyInline(FlatBufferBuilder &fbb, const reflection::Field &fielddef,
+                const Table &table, size_t align, size_t size) {
+  fbb.Align(align);
+  fbb.PushBytes(table.GetStruct<const uint8_t *>(fielddef.offset()), size);
+  fbb.TrackField(fielddef.offset(), fbb.GetSize());
+}
+
+static bool VerifyStruct(flatbuffers::Verifier &v,
+                  const flatbuffers::Table &parent_table,
+                  voffset_t field_offset, const reflection::Object &obj,
+                  bool required) {
+  auto offset = parent_table.GetOptionalFieldOffset(field_offset);
+  if (required && !offset) { return false; }
+
+  return !offset ||
+         v.VerifyFieldStruct(reinterpret_cast<const uint8_t *>(&parent_table),
+                             offset, obj.bytesize(), obj.minalign());
+}
+
+static bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
+                           const flatbuffers::Table &parent_table,
+                           voffset_t field_offset,
+                           const reflection::Object &obj, bool required) {
+  auto p = parent_table.GetPointer<const uint8_t *>(field_offset);
+  if (required && !p) { return false; }
+
+  return !p || v.VerifyVectorOrString(p, obj.bytesize());
+}
+
+// forward declare to resolve cyclic deps between VerifyObject and VerifyVector
+static bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
+                  const reflection::Object &obj,
+                  const flatbuffers::Table *table, bool required);
+
+static bool VerifyUnion(flatbuffers::Verifier &v, const reflection::Schema &schema,
+                 uint8_t utype, const uint8_t *elem,
+                 const reflection::Field &union_field) {
+  if (!utype) return true;  // Not present.
+  auto fb_enum = schema.enums()->Get(union_field.type()->index());
+  if (utype >= fb_enum->values()->size()) return false;
+  auto elem_type = fb_enum->values()->Get(utype)->union_type();
+  switch (elem_type->base_type()) {
+    case reflection::Obj: {
+      auto elem_obj = schema.objects()->Get(elem_type->index());
+      if (elem_obj->is_struct()) {
+        return v.VerifyFromPointer(elem, elem_obj->bytesize());
+      } else {
+        return VerifyObject(v, schema, *elem_obj,
+                            reinterpret_cast<const flatbuffers::Table *>(elem),
+                            true);
+      }
+    }
+    case reflection::String:
+      return v.VerifyString(
+          reinterpret_cast<const flatbuffers::String *>(elem));
+    default: return false;
+  }
+}
+
+static bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
+                  const flatbuffers::Table &table,
+                  const reflection::Field &vec_field) {
+  FLATBUFFERS_ASSERT(vec_field.type()->base_type() == reflection::Vector);
+  if (!table.VerifyField<uoffset_t>(v, vec_field.offset(), sizeof(uoffset_t)))
+    return false;
+
+  switch (vec_field.type()->element()) {
+    case reflection::UType:
+      return v.VerifyVector(flatbuffers::GetFieldV<uint8_t>(table, vec_field));
+    case reflection::Bool:
+    case reflection::Byte:
+    case reflection::UByte:
+      return v.VerifyVector(flatbuffers::GetFieldV<int8_t>(table, vec_field));
+    case reflection::Short:
+    case reflection::UShort:
+      return v.VerifyVector(flatbuffers::GetFieldV<int16_t>(table, vec_field));
+    case reflection::Int:
+    case reflection::UInt:
+      return v.VerifyVector(flatbuffers::GetFieldV<int32_t>(table, vec_field));
+    case reflection::Long:
+    case reflection::ULong:
+      return v.VerifyVector(flatbuffers::GetFieldV<int64_t>(table, vec_field));
+    case reflection::Float:
+      return v.VerifyVector(flatbuffers::GetFieldV<float>(table, vec_field));
+    case reflection::Double:
+      return v.VerifyVector(flatbuffers::GetFieldV<double>(table, vec_field));
+    case reflection::String: {
+      auto vec_string =
+          flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::String>>(
+              table, vec_field);
+      if (v.VerifyVector(vec_string) && v.VerifyVectorOfStrings(vec_string)) {
+        return true;
+      } else {
+        return false;
+      }
+    }
+    case reflection::Obj: {
+      auto obj = schema.objects()->Get(vec_field.type()->index());
+      if (obj->is_struct()) {
+        return VerifyVectorOfStructs(v, table, vec_field.offset(), *obj,
+                                     vec_field.required());
+      } else {
+        auto vec =
+            flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::Table>>(
+                table, vec_field);
+        if (!v.VerifyVector(vec)) return false;
+        if (!vec) return true;
+        for (uoffset_t j = 0; j < vec->size(); j++) {
+          if (!VerifyObject(v, schema, *obj, vec->Get(j), true)) {
+            return false;
+          }
+        }
+        return true;
+      }
+    }
+    case reflection::Union: {
+      auto vec = flatbuffers::GetFieldV<flatbuffers::Offset<uint8_t>>(
+          table, vec_field);
+      if (!v.VerifyVector(vec)) return false;
+      if (!vec) return true;
+      auto type_vec = table.GetPointer<Vector<uint8_t> *>(vec_field.offset() -
+                                                          sizeof(voffset_t));
+      if (!v.VerifyVector(type_vec)) return false;
+      for (uoffset_t j = 0; j < vec->size(); j++) {
+        //  get union type from the prev field
+        auto utype = type_vec->Get(j);
+        auto elem = vec->Get(j);
+        if (!VerifyUnion(v, schema, utype, elem, vec_field)) return false;
+      }
+      return true;
+    }
+    case reflection::Vector:
+    case reflection::None:
+    default: FLATBUFFERS_ASSERT(false); return false;
+  }
+}
+
+static bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
+                  const reflection::Object &obj,
+                  const flatbuffers::Table *table, bool required) {
+  if (!table) return !required;
+  if (!table->VerifyTableStart(v)) return false;
+  for (uoffset_t i = 0; i < obj.fields()->size(); i++) {
+    auto field_def = obj.fields()->Get(i);
+    switch (field_def->type()->base_type()) {
+      case reflection::None: FLATBUFFERS_ASSERT(false); break;
+      case reflection::UType:
+        if (!table->VerifyField<uint8_t>(v, field_def->offset(),
+                                         sizeof(uint8_t)))
+          return false;
+        break;
+      case reflection::Bool:
+      case reflection::Byte:
+      case reflection::UByte:
+        if (!table->VerifyField<int8_t>(v, field_def->offset(), sizeof(int8_t)))
+          return false;
+        break;
+      case reflection::Short:
+      case reflection::UShort:
+        if (!table->VerifyField<int16_t>(v, field_def->offset(),
+                                         sizeof(int16_t)))
+          return false;
+        break;
+      case reflection::Int:
+      case reflection::UInt:
+        if (!table->VerifyField<int32_t>(v, field_def->offset(),
+                                         sizeof(int32_t)))
+          return false;
+        break;
+      case reflection::Long:
+      case reflection::ULong:
+        if (!table->VerifyField<int64_t>(v, field_def->offset(),
+                                         sizeof(int64_t)))
+          return false;
+        break;
+      case reflection::Float:
+        if (!table->VerifyField<float>(v, field_def->offset(), sizeof(float)))
+          return false;
+        break;
+      case reflection::Double:
+        if (!table->VerifyField<double>(v, field_def->offset(), sizeof(double)))
+          return false;
+        break;
+      case reflection::String:
+        if (!table->VerifyField<uoffset_t>(v, field_def->offset(),
+                                           sizeof(uoffset_t)) ||
+            !v.VerifyString(flatbuffers::GetFieldS(*table, *field_def))) {
+          return false;
+        }
+        break;
+      case reflection::Vector:
+        if (!VerifyVector(v, schema, *table, *field_def)) return false;
+        break;
+      case reflection::Obj: {
+        auto child_obj = schema.objects()->Get(field_def->type()->index());
+        if (child_obj->is_struct()) {
+          if (!VerifyStruct(v, *table, field_def->offset(), *child_obj,
+                            field_def->required())) {
+            return false;
+          }
+        } else {
+          if (!VerifyObject(v, schema, *child_obj,
+                            flatbuffers::GetFieldT(*table, *field_def),
+                            field_def->required())) {
+            return false;
+          }
+        }
+        break;
+      }
+      case reflection::Union: {
+        //  get union type from the prev field
+        voffset_t utype_offset = field_def->offset() - sizeof(voffset_t);
+        auto utype = table->GetField<uint8_t>(utype_offset, 0);
+        auto uval = reinterpret_cast<const uint8_t *>(
+            flatbuffers::GetFieldT(*table, *field_def));
+        if (!VerifyUnion(v, schema, utype, uval, *field_def)) { return false; }
+        break;
+      }
+      default: FLATBUFFERS_ASSERT(false); break;
+    }
+  }
+
+  if (!v.EndTable()) return false;
+
+  return true;
+}
+
+
+} // namespace
+
 int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data) {
   // clang-format off
   #define FLATBUFFERS_GET(T) static_cast<int64_t>(ReadScalar<T>(data))
@@ -120,6 +352,23 @@
   }
 }
 
+void ForAllFields(const reflection::Object *object, bool reverse,
+                  std::function<void(const reflection::Field *)> func) {
+  std::vector<uint32_t> field_to_id_map;
+  field_to_id_map.resize(object->fields()->size());
+
+  // Create the mapping of field ID to the index into the vector.
+  for (uint32_t i = 0; i < object->fields()->size(); ++i) {
+    auto field = object->fields()->Get(i);
+    field_to_id_map[field->id()] = i;
+  }
+
+  for (size_t i = 0; i < field_to_id_map.size(); ++i) {
+    func(object->fields()->Get(
+        field_to_id_map[reverse ? field_to_id_map.size() - i + 1 : i]));
+  }
+}
+
 void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val) {
   // clang-format off
   #define FLATBUFFERS_SET(T) WriteScalar(data, static_cast<T>(val))
@@ -367,12 +616,8 @@
   return flatbuf.data() + insertion_point + root_offset;
 }
 
-void CopyInline(FlatBufferBuilder &fbb, const reflection::Field &fielddef,
-                const Table &table, size_t align, size_t size) {
-  fbb.Align(align);
-  fbb.PushBytes(table.GetStruct<const uint8_t *>(fielddef.offset()), size);
-  fbb.TrackField(fielddef.offset(), fbb.GetSize());
-}
+
+
 
 Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
                                 const reflection::Schema &schema,
@@ -498,231 +743,22 @@
   }
 }
 
-bool VerifyStruct(flatbuffers::Verifier &v,
-                  const flatbuffers::Table &parent_table,
-                  voffset_t field_offset, const reflection::Object &obj,
-                  bool required) {
-  auto offset = parent_table.GetOptionalFieldOffset(field_offset);
-  if (required && !offset) { return false; }
-
-  return !offset ||
-         v.VerifyFieldStruct(reinterpret_cast<const uint8_t *>(&parent_table),
-                             offset, obj.bytesize(), obj.minalign());
-}
-
-bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
-                           const flatbuffers::Table &parent_table,
-                           voffset_t field_offset,
-                           const reflection::Object &obj, bool required) {
-  auto p = parent_table.GetPointer<const uint8_t *>(field_offset);
-  if (required && !p) { return false; }
-
-  return !p || v.VerifyVectorOrString(p, obj.bytesize());
-}
-
-// forward declare to resolve cyclic deps between VerifyObject and VerifyVector
-bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
-                  const reflection::Object &obj,
-                  const flatbuffers::Table *table, bool required);
-
-bool VerifyUnion(flatbuffers::Verifier &v, const reflection::Schema &schema,
-                 uint8_t utype, const uint8_t *elem,
-                 const reflection::Field &union_field) {
-  if (!utype) return true;  // Not present.
-  auto fb_enum = schema.enums()->Get(union_field.type()->index());
-  if (utype >= fb_enum->values()->size()) return false;
-  auto elem_type = fb_enum->values()->Get(utype)->union_type();
-  switch (elem_type->base_type()) {
-    case reflection::Obj: {
-      auto elem_obj = schema.objects()->Get(elem_type->index());
-      if (elem_obj->is_struct()) {
-        return v.VerifyFromPointer(elem, elem_obj->bytesize());
-      } else {
-        return VerifyObject(v, schema, *elem_obj,
-                            reinterpret_cast<const flatbuffers::Table *>(elem),
-                            true);
-      }
-    }
-    case reflection::String:
-      return v.VerifyString(
-          reinterpret_cast<const flatbuffers::String *>(elem));
-    default: return false;
-  }
-}
-
-bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
-                  const flatbuffers::Table &table,
-                  const reflection::Field &vec_field) {
-  FLATBUFFERS_ASSERT(vec_field.type()->base_type() == reflection::Vector);
-  if (!table.VerifyField<uoffset_t>(v, vec_field.offset(), sizeof(uoffset_t)))
-    return false;
-
-  switch (vec_field.type()->element()) {
-    case reflection::UType:
-      return v.VerifyVector(flatbuffers::GetFieldV<uint8_t>(table, vec_field));
-    case reflection::Bool:
-    case reflection::Byte:
-    case reflection::UByte:
-      return v.VerifyVector(flatbuffers::GetFieldV<int8_t>(table, vec_field));
-    case reflection::Short:
-    case reflection::UShort:
-      return v.VerifyVector(flatbuffers::GetFieldV<int16_t>(table, vec_field));
-    case reflection::Int:
-    case reflection::UInt:
-      return v.VerifyVector(flatbuffers::GetFieldV<int32_t>(table, vec_field));
-    case reflection::Long:
-    case reflection::ULong:
-      return v.VerifyVector(flatbuffers::GetFieldV<int64_t>(table, vec_field));
-    case reflection::Float:
-      return v.VerifyVector(flatbuffers::GetFieldV<float>(table, vec_field));
-    case reflection::Double:
-      return v.VerifyVector(flatbuffers::GetFieldV<double>(table, vec_field));
-    case reflection::String: {
-      auto vec_string =
-          flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::String>>(
-              table, vec_field);
-      if (v.VerifyVector(vec_string) && v.VerifyVectorOfStrings(vec_string)) {
-        return true;
-      } else {
-        return false;
-      }
-    }
-    case reflection::Obj: {
-      auto obj = schema.objects()->Get(vec_field.type()->index());
-      if (obj->is_struct()) {
-        return VerifyVectorOfStructs(v, table, vec_field.offset(), *obj,
-                                     vec_field.required());
-      } else {
-        auto vec =
-            flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::Table>>(
-                table, vec_field);
-        if (!v.VerifyVector(vec)) return false;
-        if (!vec) return true;
-        for (uoffset_t j = 0; j < vec->size(); j++) {
-          if (!VerifyObject(v, schema, *obj, vec->Get(j), true)) {
-            return false;
-          }
-        }
-        return true;
-      }
-    }
-    case reflection::Union: {
-      auto vec = flatbuffers::GetFieldV<flatbuffers::Offset<uint8_t>>(
-          table, vec_field);
-      if (!v.VerifyVector(vec)) return false;
-      if (!vec) return true;
-      auto type_vec = table.GetPointer<Vector<uint8_t> *>(vec_field.offset() -
-                                                          sizeof(voffset_t));
-      if (!v.VerifyVector(type_vec)) return false;
-      for (uoffset_t j = 0; j < vec->size(); j++) {
-        //  get union type from the prev field
-        auto utype = type_vec->Get(j);
-        auto elem = vec->Get(j);
-        if (!VerifyUnion(v, schema, utype, elem, vec_field)) return false;
-      }
-      return true;
-    }
-    case reflection::Vector:
-    case reflection::None:
-    default: FLATBUFFERS_ASSERT(false); return false;
-  }
-}
-
-bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
-                  const reflection::Object &obj,
-                  const flatbuffers::Table *table, bool required) {
-  if (!table) return !required;
-  if (!table->VerifyTableStart(v)) return false;
-  for (uoffset_t i = 0; i < obj.fields()->size(); i++) {
-    auto field_def = obj.fields()->Get(i);
-    switch (field_def->type()->base_type()) {
-      case reflection::None: FLATBUFFERS_ASSERT(false); break;
-      case reflection::UType:
-        if (!table->VerifyField<uint8_t>(v, field_def->offset(),
-                                         sizeof(uint8_t)))
-          return false;
-        break;
-      case reflection::Bool:
-      case reflection::Byte:
-      case reflection::UByte:
-        if (!table->VerifyField<int8_t>(v, field_def->offset(), sizeof(int8_t)))
-          return false;
-        break;
-      case reflection::Short:
-      case reflection::UShort:
-        if (!table->VerifyField<int16_t>(v, field_def->offset(),
-                                         sizeof(int16_t)))
-          return false;
-        break;
-      case reflection::Int:
-      case reflection::UInt:
-        if (!table->VerifyField<int32_t>(v, field_def->offset(),
-                                         sizeof(int32_t)))
-          return false;
-        break;
-      case reflection::Long:
-      case reflection::ULong:
-        if (!table->VerifyField<int64_t>(v, field_def->offset(),
-                                         sizeof(int64_t)))
-          return false;
-        break;
-      case reflection::Float:
-        if (!table->VerifyField<float>(v, field_def->offset(), sizeof(float)))
-          return false;
-        break;
-      case reflection::Double:
-        if (!table->VerifyField<double>(v, field_def->offset(), sizeof(double)))
-          return false;
-        break;
-      case reflection::String:
-        if (!table->VerifyField<uoffset_t>(v, field_def->offset(),
-                                           sizeof(uoffset_t)) ||
-            !v.VerifyString(flatbuffers::GetFieldS(*table, *field_def))) {
-          return false;
-        }
-        break;
-      case reflection::Vector:
-        if (!VerifyVector(v, schema, *table, *field_def)) return false;
-        break;
-      case reflection::Obj: {
-        auto child_obj = schema.objects()->Get(field_def->type()->index());
-        if (child_obj->is_struct()) {
-          if (!VerifyStruct(v, *table, field_def->offset(), *child_obj,
-                            field_def->required())) {
-            return false;
-          }
-        } else {
-          if (!VerifyObject(v, schema, *child_obj,
-                            flatbuffers::GetFieldT(*table, *field_def),
-                            field_def->required())) {
-            return false;
-          }
-        }
-        break;
-      }
-      case reflection::Union: {
-        //  get union type from the prev field
-        voffset_t utype_offset = field_def->offset() - sizeof(voffset_t);
-        auto utype = table->GetField<uint8_t>(utype_offset, 0);
-        auto uval = reinterpret_cast<const uint8_t *>(
-            flatbuffers::GetFieldT(*table, *field_def));
-        if (!VerifyUnion(v, schema, utype, uval, *field_def)) { return false; }
-        break;
-      }
-      default: FLATBUFFERS_ASSERT(false); break;
-    }
-  }
-
-  if (!v.EndTable()) return false;
-
-  return true;
-}
 
 bool Verify(const reflection::Schema &schema, const reflection::Object &root,
-            const uint8_t *buf, size_t length, uoffset_t max_depth /*= 64*/,
-            uoffset_t max_tables /*= 1000000*/) {
+            const uint8_t *const buf, const size_t length,
+            const uoffset_t max_depth, const uoffset_t max_tables) {
   Verifier v(buf, length, max_depth, max_tables);
-  return VerifyObject(v, schema, root, flatbuffers::GetAnyRoot(buf), true);
+  return VerifyObject(v, schema, root, flatbuffers::GetAnyRoot(buf),
+                      /*required=*/true);
+}
+
+bool VerifySizePrefixed(const reflection::Schema &schema,
+                        const reflection::Object &root,
+                        const uint8_t *const buf, const size_t length,
+                        const uoffset_t max_depth, const uoffset_t max_tables) {
+  Verifier v(buf, length, max_depth, max_tables);
+  return VerifyObject(v, schema, root, flatbuffers::GetAnySizePrefixedRoot(buf),
+                      /*required=*/true);
 }
 
 }  // namespace flatbuffers
