[C++] Refactor to conform to Google C++ style guide (#5608)
[platform/upstream/flatbuffers.git] / src / idl_gen_kotlin.cpp
index d11599f..b12e554 100644 (file)
 
 #include <functional>
 #include <unordered_set>
+
 #include "flatbuffers/code_generators.h"
 #include "flatbuffers/flatbuffers.h"
 #include "flatbuffers/idl.h"
 #include "flatbuffers/util.h"
 #if defined(FLATBUFFERS_CPP98_STL)
-#include <cctype>
+#  include <cctype>
 #endif  // defined(FLATBUFFERS_CPP98_STL)
 
 namespace flatbuffers {
@@ -35,21 +36,20 @@ static TypedFloatConstantGenerator KotlinFloatGen("Double.", "Float.", "NaN",
                                                   "POSITIVE_INFINITY",
                                                   "NEGATIVE_INFINITY");
 
-static const CommentConfig comment_config = {"/**", " *", " */"};
+static const CommentConfig comment_config = { "/**", " *", " */" };
 static const std::string ident_pad = "    ";
 static const char *keywords[] = {
-    "package",  "as",     "typealias", "class",  "this",   "super",
-    "val",      "var",    "fun",       "for",    "null",   "true",
-    "false",    "is",     "in",        "throw",  "return", "break",
-    "continue", "object", "if",        "try",    "else",   "while",
-    "do",       "when",   "interface", "typeof", "Any",    "Character"};
+  "package",  "as",     "typealias", "class",  "this",   "super",
+  "val",      "var",    "fun",       "for",    "null",   "true",
+  "false",    "is",     "in",        "throw",  "return", "break",
+  "continue", "object", "if",        "try",    "else",   "while",
+  "do",       "when",   "interface", "typeof", "Any",    "Character"
+};
 
 // Escape Keywords
 static std::string Esc(const std::string &name) {
   for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
-    if (name == keywords[i]) {
-      return MakeCamel(name + "_", false);
-    }
+    if (name == keywords[i]) { return MakeCamel(name + "_", false); }
   }
 
   return MakeCamel(name, false);
@@ -145,1380 +145,1298 @@ class KotlinGenerator : public BaseGenerator {
     #KTYPE,
         FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
     #undef FLATBUFFERS_TD
-        };
-        return kotlin_typename[type];
+      // clang-format on
+    };
+    return kotlin_typename[type];
+  }
 
+  std::string GenTypePointer(const Type &type) const {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: return "String";
+      case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
+      case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def);
+      default: return "Table";
     }
+  }
 
-    std::string GenTypePointer(const Type &type) const {
-        switch (type.base_type) {
-        case BASE_TYPE_STRING:
-            return "String";
-        case BASE_TYPE_VECTOR:
-            return GenTypeGet(type.VectorType());
-        case BASE_TYPE_STRUCT:
-            return WrapInNameSpace(*type.struct_def);
-        default:
-            return "Table";
-        }
-    }
+  std::string GenTypeGet(const Type &type) const {
+    return IsScalar(type.base_type) ? GenTypeBasic(type.base_type)
+                                    : GenTypePointer(type);
+  }
 
-    std::string GenTypeGet(const Type &type) const {
-        return IsScalar(type.base_type) ? GenTypeBasic(type.base_type)
-                                        : GenTypePointer(type);
-    }
+  std::string GenEnumDefaultValue(const FieldDef &field) const {
+    auto &value = field.value;
+    FLATBUFFERS_ASSERT(value.type.enum_def);
+    auto &enum_def = *value.type.enum_def;
+    auto enum_val = enum_def.FindByValue(value.constant);
+    return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name)
+                    : value.constant;
+  }
 
-    std::string GenEnumDefaultValue(const FieldDef &field) const {
-        auto &value = field.value;
-        FLATBUFFERS_ASSERT(value.type.enum_def);
-        auto &enum_def = *value.type.enum_def;
-        auto enum_val = enum_def.FindByValue(value.constant);
-        return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name)
-                        : value.constant;
+  // Generate default values to compare against a default value when
+  // `force_defaults` is `false`.
+  // Main differences are:
+  // - Floats are upcasted to doubles
+  // - Unsigned are casted to signed
+  std::string GenFBBDefaultValue(const FieldDef &field) const {
+    auto out = GenDefaultValue(field, true);
+    // All FlatBufferBuilder default floating point values are doubles
+    if (field.value.type.base_type == BASE_TYPE_FLOAT) {
+      if (out.find("Float") != std::string::npos) {
+        out.replace(0, 5, "Double");
+      }
     }
+    // Guarantee all values are doubles
+    if (out.back() == 'f') out.pop_back();
+    return out;
+  }
 
-
-     // Generate default values to compare against a default value when
-     // `force_defaults` is `false`.
-     // Main differences are:
-     // - Floats are upcasted to doubles
-     // - Unsigned are casted to signed
-    std::string GenFBBDefaultValue(const FieldDef &field) const {
-        auto out = GenDefaultValue(field, true);
-        // All FlatBufferBuilder default floating point values are doubles
-        if (field.value.type.base_type == BASE_TYPE_FLOAT) {
-            if (out.find("Float") != std::string::npos) {
-                out.replace(0, 5, "Double");
-            }
-        }
-        //Guarantee all values are doubles
-        if (out.back() == 'f')
-            out.pop_back();
-        return out;
+  // FlatBufferBuilder only store signed types, so this function
+  // returns a cast for unsigned values
+  std::string GenFBBValueCast(const FieldDef &field) const {
+    if (IsUnsigned(field.value.type.base_type)) {
+      return CastToSigned(field.value.type);
     }
+    return "";
+  }
 
-
-    // FlatBufferBuilder only store signed types, so this function
-    // returns a cast for unsigned values
-    std::string GenFBBValueCast(const FieldDef &field) const {
-        if (IsUnsigned(field.value.type.base_type)) {
-            return CastToSigned(field.value.type);
-        }
-        return "";
+  std::string GenDefaultValue(const FieldDef &field,
+                              bool force_signed = false) const {
+    auto &value = field.value;
+    auto base_type = field.value.type.base_type;
+    if (IsFloat(base_type)) {
+      auto val = KotlinFloatGen.GenFloatConstant(field);
+      if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') {
+        val.pop_back();
+      }
+      return val;
     }
 
-    std::string GenDefaultValue(const FieldDef &field,
-                                bool force_signed = false) const {
-        auto &value = field.value;
-        auto base_type = field.value.type.base_type;
-        if (IsFloat(base_type)) {
-            auto val = KotlinFloatGen.GenFloatConstant(field);
-            if (base_type == BASE_TYPE_DOUBLE &&
-                    val.back() == 'f') {
-                val.pop_back();
-            }
-            return val;
-        }
-
-        if (base_type  == BASE_TYPE_BOOL) {
-            return value.constant == "0" ? "false" : "true";
-        }
+    if (base_type == BASE_TYPE_BOOL) {
+      return value.constant == "0" ? "false" : "true";
+    }
 
-        std::string suffix = "";
+    std::string suffix = "";
 
-        if (base_type == BASE_TYPE_LONG || !force_signed) {
-            suffix = LiteralSuffix(base_type);
-        }
-        return value.constant + suffix;
+    if (base_type == BASE_TYPE_LONG || !force_signed) {
+      suffix = LiteralSuffix(base_type);
     }
+    return value.constant + suffix;
+  }
 
-    void GenEnum(EnumDef &enum_def, CodeWriter &writer) const {
-        if (enum_def.generated) return;
-
-        GenerateComment(enum_def.doc_comment, writer, &comment_config);
-
-        writer += "@Suppress(\"unused\")";
-        writer += "@ExperimentalUnsignedTypes";
-        writer += "class " + Esc(enum_def.name) + " private constructor() {";
-        writer.IncrementIdentLevel();
-
-        GenerateCompanionObject(writer, [&](){
-            // Write all properties
-            auto vals = enum_def.Vals();
-            for (auto it = vals.begin(); it != vals.end(); ++it) {
-                auto &ev = **it;
-                auto field_type = GenTypeBasic(enum_def.underlying_type.base_type);
-                auto val = enum_def.ToString(ev);
-                auto suffix = LiteralSuffix(enum_def.underlying_type.base_type);
-                writer.SetValue("name", Esc(ev.name));
-                writer.SetValue("type", field_type);
-                writer.SetValue("val", val + suffix);
-                GenerateComment(ev.doc_comment, writer, &comment_config);
-                writer += "const val {{name}}: {{type}} = {{val}}";
-            }
+  void GenEnum(EnumDef &enum_def, CodeWriter &writer) const {
+    if (enum_def.generated) return;
+
+    GenerateComment(enum_def.doc_comment, writer, &comment_config);
+
+    writer += "@Suppress(\"unused\")";
+    writer += "@ExperimentalUnsignedTypes";
+    writer += "class " + Esc(enum_def.name) + " private constructor() {";
+    writer.IncrementIdentLevel();
+
+    GenerateCompanionObject(writer, [&]() {
+      // Write all properties
+      auto vals = enum_def.Vals();
+      for (auto it = vals.begin(); it != vals.end(); ++it) {
+        auto &ev = **it;
+        auto field_type = GenTypeBasic(enum_def.underlying_type.base_type);
+        auto val = enum_def.ToString(ev);
+        auto suffix = LiteralSuffix(enum_def.underlying_type.base_type);
+        writer.SetValue("name", Esc(ev.name));
+        writer.SetValue("type", field_type);
+        writer.SetValue("val", val + suffix);
+        GenerateComment(ev.doc_comment, writer, &comment_config);
+        writer += "const val {{name}}: {{type}} = {{val}}";
+      }
 
-            // Generate a generate string table for enum values.
-            // Problem is, if values are very sparse that could generate really
-            // big tables. Ideally in that case we generate a map lookup
-            // instead, but for the moment we simply don't output a table at all.
-            auto range = enum_def.Distance();
-            // Average distance between values above which we consider a table
-            // "too sparse". Change at will.
-            static const uint64_t kMaxSparseness = 5;
-            if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
-                GeneratePropertyOneLine(writer, "names", "Array<String>",
-                               [&](){
-                    writer += "arrayOf(\\";
-                    auto val = enum_def.Vals().front();
-                    for (auto it = vals.begin(); it != vals.end(); ++it) {
-                        auto ev = *it;
-                        for (auto k = enum_def.Distance(val, ev); k > 1; --k)
-                            writer += "\"\", \\";
-                        val = ev;
-                        writer += "\"" + (*it)->name + "\"\\";
-                        if (it+1 != vals.end()) {
-                            writer += ", \\";
-                        }
-                    }
-                    writer += ")";
-                });
-                GenerateFunOneLine(writer, "name", "e: Int", "String", [&](){
-                    writer += "names[e\\";
-                    if (enum_def.MinValue()->IsNonZero())
-                        writer += " - " + enum_def.MinValue()->name + ".toInt()\\";
-                    writer += "]";
-                });
-            }
+      // Generate a generate string table for enum values.
+      // Problem is, if values are very sparse that could generate really
+      // big tables. Ideally in that case we generate a map lookup
+      // instead, but for the moment we simply don't output a table at all.
+      auto range = enum_def.Distance();
+      // Average distance between values above which we consider a table
+      // "too sparse". Change at will.
+      static const uint64_t kMaxSparseness = 5;
+      if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
+        GeneratePropertyOneLine(writer, "names", "Array<String>", [&]() {
+          writer += "arrayOf(\\";
+          auto val = enum_def.Vals().front();
+          for (auto it = vals.begin(); it != vals.end(); ++it) {
+            auto ev = *it;
+            for (auto k = enum_def.Distance(val, ev); k > 1; --k)
+              writer += "\"\", \\";
+            val = ev;
+            writer += "\"" + (*it)->name + "\"\\";
+            if (it + 1 != vals.end()) { writer += ", \\"; }
+          }
+          writer += ")";
+        });
+        GenerateFunOneLine(writer, "name", "e: Int", "String", [&]() {
+          writer += "names[e\\";
+          if (enum_def.MinValue()->IsNonZero())
+            writer += " - " + enum_def.MinValue()->name + ".toInt()\\";
+          writer += "]";
         });
-        writer.DecrementIdentLevel();
-        writer += "}";
+      }
+    });
+    writer.DecrementIdentLevel();
+    writer += "}";
+  }
+
+  // Returns the function name that is able to read a value of the given type.
+  std::string ByteBufferGetter(const Type &type,
+                               std::string bb_var_name) const {
+    switch (type.base_type) {
+      case BASE_TYPE_STRING: return "__string";
+      case BASE_TYPE_STRUCT: return "__struct";
+      case BASE_TYPE_UNION: return "__union";
+      case BASE_TYPE_VECTOR:
+        return ByteBufferGetter(type.VectorType(), bb_var_name);
+      case BASE_TYPE_INT:
+      case BASE_TYPE_UINT: return bb_var_name + ".getInt";
+      case BASE_TYPE_SHORT:
+      case BASE_TYPE_USHORT: return bb_var_name + ".getShort";
+      case BASE_TYPE_ULONG:
+      case BASE_TYPE_LONG: return bb_var_name + ".getLong";
+      case BASE_TYPE_FLOAT: return bb_var_name + ".getFloat";
+      case BASE_TYPE_DOUBLE: return bb_var_name + ".getDouble";
+      case BASE_TYPE_CHAR:
+      case BASE_TYPE_UCHAR:
+      case BASE_TYPE_NONE:
+      case BASE_TYPE_UTYPE: return bb_var_name + ".get";
+      case BASE_TYPE_BOOL: return "0.toByte() != " + bb_var_name + ".get";
+      default:
+        return bb_var_name + ".get" + MakeCamel(GenTypeBasic(type.base_type));
     }
+  }
 
-    // Returns the function name that is able to read a value of the given type.
-    std::string ByteBufferGetter(const Type &type, std::string bb_var_name) const {
-        switch (type.base_type) {
-        case BASE_TYPE_STRING:
-            return "__string";
-        case BASE_TYPE_STRUCT:
-            return "__struct";
-        case BASE_TYPE_UNION:
-            return "__union";
-        case BASE_TYPE_VECTOR:
-            return ByteBufferGetter(type.VectorType(), bb_var_name);
+  std::string ByteBufferSetter(const Type &type) const {
+    if (IsScalar(type.base_type)) {
+      switch (type.base_type) {
         case BASE_TYPE_INT:
-        case BASE_TYPE_UINT:
-            return bb_var_name + ".getInt";
+        case BASE_TYPE_UINT: return "bb.putInt";
         case BASE_TYPE_SHORT:
-        case BASE_TYPE_USHORT:
-            return bb_var_name + ".getShort";
+        case BASE_TYPE_USHORT: return "bb.putShort";
         case BASE_TYPE_ULONG:
-        case BASE_TYPE_LONG:
-            return bb_var_name + ".getLong";
-        case BASE_TYPE_FLOAT:
-            return bb_var_name + ".getFloat";
-        case BASE_TYPE_DOUBLE:
-            return bb_var_name + ".getDouble";
+        case BASE_TYPE_LONG: return "bb.putLong";
+        case BASE_TYPE_FLOAT: return "bb.putFloat";
+        case BASE_TYPE_DOUBLE: return "bb.putDouble";
         case BASE_TYPE_CHAR:
         case BASE_TYPE_UCHAR:
-        case BASE_TYPE_NONE:
-        case BASE_TYPE_UTYPE:
-            return bb_var_name + ".get";
         case BASE_TYPE_BOOL:
-            return "0.toByte() != " + bb_var_name + ".get";
-        default:
-            return bb_var_name + ".get" + MakeCamel(GenTypeBasic(type.base_type));
-        }
+        case BASE_TYPE_NONE:
+        case BASE_TYPE_UTYPE: return "bb.put";
+        default: return "bb.put" + MakeCamel(GenTypeBasic(type.base_type));
+      }
     }
+    return "";
+  }
 
-    std::string ByteBufferSetter(const Type &type) const {
-        if (IsScalar(type.base_type)) {
-            switch (type.base_type) {
-            case BASE_TYPE_INT:
-            case BASE_TYPE_UINT:
-                return "bb.putInt";
-            case BASE_TYPE_SHORT:
-            case BASE_TYPE_USHORT:
-                return "bb.putShort";
-            case BASE_TYPE_ULONG:
-            case BASE_TYPE_LONG:
-                return "bb.putLong";
-            case BASE_TYPE_FLOAT:
-                return "bb.putFloat";
-            case BASE_TYPE_DOUBLE:
-                return "bb.putDouble";
-            case BASE_TYPE_CHAR:
-            case BASE_TYPE_UCHAR:
-            case BASE_TYPE_BOOL:
-            case BASE_TYPE_NONE:
-            case BASE_TYPE_UTYPE:
-                return "bb.put";
-            default:
-                return "bb.put" + MakeCamel(GenTypeBasic(type.base_type));
-            }
-        }
-        return "";
-    }
+  // Returns the function name that is able to read a value of the given type.
+  std::string GenLookupByKey(flatbuffers::FieldDef *key_field,
+                             const std::string &bb_var_name,
+                             const char *num = nullptr) const {
+    auto type = key_field->value.type;
+    return ByteBufferGetter(type, bb_var_name) + "(" +
+           GenOffsetGetter(key_field, num) + ")";
+  }
 
-    // Returns the function name that is able to read a value of the given type.
-    std::string GenLookupByKey(flatbuffers::FieldDef *key_field,
-                               const std::string &bb_var_name,
-                               const char *num = nullptr) const {
-        auto type = key_field->value.type;
-        return ByteBufferGetter(type, bb_var_name) + "(" + GenOffsetGetter(key_field, num) + ")";
+  // Returns the method name for use with add/put calls.
+  static std::string GenMethod(const Type &type) {
+    return IsScalar(type.base_type) ? ToSignedType(type)
+                                    : (IsStruct(type) ? "Struct" : "Offset");
+  }
 
+  // Recursively generate arguments for a constructor, to deal with nested
+  // structs.
+  static void GenStructArgs(const StructDef &struct_def, CodeWriter &writer,
+                            const char *nameprefix) {
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (IsStruct(field.value.type)) {
+        // Generate arguments for a struct inside a struct. To ensure
+        // names don't clash, and to make it obvious these arguments are
+        // constructing a nested struct, prefix the name with the field
+        // name.
+        GenStructArgs(*field.value.type.struct_def, writer,
+                      (nameprefix + (field.name + "_")).c_str());
+      } else {
+        writer += std::string(", ") + nameprefix + "\\";
+        writer += MakeCamel(field.name) + ": \\";
+        writer += GenTypeBasic(field.value.type.base_type) + "\\";
+      }
     }
+  }
 
-    // Returns the method name for use with add/put calls.
-    static std::string GenMethod(const Type &type) {
-        return IsScalar(type.base_type) ? ToSignedType(type)
-                                        : (IsStruct(type) ? "Struct" : "Offset");
+  // Recusively generate struct construction statements of the form:
+  // builder.putType(name);
+  // and insert manual padding.
+  static void GenStructBody(const StructDef &struct_def, CodeWriter &writer,
+                            const char *nameprefix) {
+    writer.SetValue("align", NumToString(struct_def.minalign));
+    writer.SetValue("size", NumToString(struct_def.bytesize));
+    writer += "builder.prep({{align}}, {{size}})";
+    auto fields_vec = struct_def.fields.vec;
+    for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) {
+      auto &field = **it;
+
+      if (field.padding) {
+        writer.SetValue("pad", NumToString(field.padding));
+        writer += "builder.pad({{pad}})";
+      }
+      if (IsStruct(field.value.type)) {
+        GenStructBody(*field.value.type.struct_def, writer,
+                      (nameprefix + (field.name + "_")).c_str());
+      } else {
+        writer.SetValue("type", GenMethod(field.value.type));
+        writer.SetValue("argname", nameprefix + MakeCamel(field.name, false));
+        writer.SetValue("cast", CastToSigned(field.value.type));
+        writer += "builder.put{{type}}({{argname}}{{cast}})";
+      }
     }
+  }
 
-    // Recursively generate arguments for a constructor, to deal with nested
-    // structs.
-    static void GenStructArgs(const StructDef &struct_def, CodeWriter &writer,
-                              const char *nameprefix) {
-        for (auto it = struct_def.fields.vec.begin();
-             it != struct_def.fields.vec.end(); ++it) {
-            auto &field = **it;
-            if (IsStruct(field.value.type)) {
-                // Generate arguments for a struct inside a struct. To ensure
-                // names don't clash, and to make it obvious these arguments are
-                // constructing a nested struct, prefix the name with the field
-                // name.
-                GenStructArgs(*field.value.type.struct_def, writer,
-                              (nameprefix + (field.name + "_")).c_str());
-            } else {
-                writer += std::string(", ") + nameprefix + "\\";
-                writer += MakeCamel(field.name) + ": \\";
-                writer += GenTypeBasic(field.value.type.base_type) + "\\";
-            }
-        }
+  std::string GenByteBufferLength(const char *bb_name) const {
+    std::string bb_len = bb_name;
+    bb_len += ".capacity()";
+    return bb_len;
+  }
+
+  std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
+                              const char *num = nullptr) const {
+    std::string key_offset =
+        "__offset(" + NumToString(key_field->value.offset) + ", ";
+    if (num) {
+      key_offset += num;
+      key_offset += ", _bb)";
+    } else {
+      key_offset += GenByteBufferLength("bb");
+      key_offset += " - tableOffset, bb)";
     }
+    return key_offset;
+  }
 
-    // Recusively generate struct construction statements of the form:
-    // builder.putType(name);
-    // and insert manual padding.
-    static void GenStructBody(const StructDef &struct_def, CodeWriter &writer,
-                              const char *nameprefix) {
-        writer.SetValue("align", NumToString(struct_def.minalign));
-        writer.SetValue("size", NumToString(struct_def.bytesize));
-        writer += "builder.prep({{align}}, {{size}})";
-        auto fields_vec = struct_def.fields.vec;
-        for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) {
-            auto &field = **it;
+  void GenStruct(StructDef &struct_def, CodeWriter &writer) const {
+    if (struct_def.generated) return;
 
-            if (field.padding) {
-                writer.SetValue("pad", NumToString(field.padding));
-                writer += "builder.pad({{pad}})";
-            }
-            if (IsStruct(field.value.type)) {
-                GenStructBody(*field.value.type.struct_def, writer,
-                              (nameprefix + (field.name + "_")).c_str());
-            } else {
-                writer.SetValue("type", GenMethod(field.value.type));
-                writer.SetValue("argname", nameprefix +
-                              MakeCamel(field.name, false));
-                writer.SetValue("cast", CastToSigned(field.value.type));
-                writer += "builder.put{{type}}({{argname}}{{cast}})";
-            }
-        }
-    }
+    GenerateComment(struct_def.doc_comment, writer, &comment_config);
+    auto fixed = struct_def.fixed;
 
-    std::string GenByteBufferLength(const char *bb_name) const {
-        std::string bb_len = bb_name;
-        bb_len += ".capacity()";
-        return bb_len;
-    }
+    writer.SetValue("struct_name", Esc(struct_def.name));
+    writer.SetValue("superclass", fixed ? "Struct" : "Table");
 
-    std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
-                                const char *num = nullptr) const {
-        std::string key_offset = "__offset(" +
-                NumToString(key_field->value.offset) + ", ";
-        if (num) {
-            key_offset += num;
-            key_offset += ", _bb)";
-        } else {
-            key_offset += GenByteBufferLength("bb");
-            key_offset += " - tableOffset, bb)";
-        }
-        return key_offset;
-    }
+    writer += "@Suppress(\"unused\")";
+    writer += "@ExperimentalUnsignedTypes";
+    writer += "class {{struct_name}} : {{superclass}}() {\n";
 
-    void GenStruct(StructDef &struct_def, CodeWriter &writer) const {
-        if (struct_def.generated) return;
+    writer.IncrementIdentLevel();
 
-        GenerateComment(struct_def.doc_comment, writer, &comment_config);
-        auto fixed = struct_def.fixed;
+    {
+      // Generate the __init() method that sets the field in a pre-existing
+      // accessor object. This is to allow object reuse.
+      GenerateFun(writer, "__init", "_i: Int, _bb: ByteBuffer", "",
+                  [&]() { writer += "__reset(_i, _bb)"; });
 
-        writer.SetValue("struct_name", Esc(struct_def.name));
-        writer.SetValue("superclass", fixed ? "Struct" : "Table");
+      // Generate assign method
+      GenerateFun(writer, "__assign", "_i: Int, _bb: ByteBuffer",
+                  Esc(struct_def.name), [&]() {
+                    writer += "__init(_i, _bb)";
+                    writer += "return this";
+                  });
 
-        writer += "@Suppress(\"unused\")";
-        writer += "@ExperimentalUnsignedTypes";
-        writer += "class {{struct_name}} : {{superclass}}() {\n";
+      // Generate all getters
+      GenerateStructGetters(struct_def, writer);
 
-        writer.IncrementIdentLevel();
+      // Generate Static Fields
+      GenerateCompanionObject(writer, [&]() {
+        if (!struct_def.fixed) {
+          FieldDef *key_field = nullptr;
 
-        {
-            // Generate the __init() method that sets the field in a pre-existing
-            // accessor object. This is to allow object reuse.
-            GenerateFun(writer, "__init", "_i: Int, _bb: ByteBuffer", "", [&]() {
-                writer += "__reset(_i, _bb)";
-            });
+          // Generate verson check method.
+          // Force compile time error if not using the same version
+          // runtime.
+          GenerateFunOneLine(writer, "validateVersion", "", "", [&]() {
+            writer += "Constants.FLATBUFFERS_1_11_1()";
+          });
 
-            // Generate assign method
-            GenerateFun(writer, "__assign", "_i: Int, _bb: ByteBuffer",
-                        Esc(struct_def.name), [&]() {
-                writer += "__init(_i, _bb)";
-                writer += "return this";
-            });
+          GenerateGetRootAsAccessors(Esc(struct_def.name), writer);
+          GenerateBufferHasIdentifier(struct_def, writer);
+          GenerateTableCreator(struct_def, writer);
 
-            // Generate all getters
-            GenerateStructGetters(struct_def, writer);
+          GenerateStartStructMethod(struct_def, writer);
 
-            // Generate Static Fields
-            GenerateCompanionObject(writer, [&](){
+          // Static Add for fields
+          auto fields = struct_def.fields.vec;
+          int field_pos = -1;
+          for (auto it = fields.begin(); it != fields.end(); ++it) {
+            auto &field = **it;
+            field_pos++;
+            if (field.deprecated) continue;
+            if (field.key) key_field = &field;
+            GenerateAddField(NumToString(field_pos), field, writer);
+
+            if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+              auto vector_type = field.value.type.VectorType();
+              if (!IsStruct(vector_type)) {
+                GenerateCreateVectorField(field, writer);
+              }
+              GenerateStartVectorField(field, writer);
+            }
+          }
+
+          GenerateEndStructMethod(struct_def, writer);
+          auto file_identifier = parser_.file_identifier_;
+          if (parser_.root_struct_def_ == &struct_def) {
+            GenerateFinishStructBuffer(struct_def, file_identifier, writer);
+            GenerateFinishSizePrefixed(struct_def, file_identifier, writer);
+          }
+
+          if (struct_def.has_key) {
+            GenerateLookupByKey(key_field, struct_def, writer);
+          }
+        } else {
+          GenerateStaticConstructor(struct_def, writer);
+        }
+      });
+    }
 
-                if (!struct_def.fixed) {
-                    FieldDef *key_field = nullptr;
+    // class closing
+    writer.DecrementIdentLevel();
+    writer += "}";
+  }
 
-                    // Generate verson check method.
-                    // Force compile time error if not using the same version
-                    // runtime.
-                    GenerateFunOneLine(writer, "validateVersion", "", "", [&](){
-                        writer += "Constants.FLATBUFFERS_1_11_1()";
-                    });
+  // TODO: move key_field to reference instead of pointer
+  void GenerateLookupByKey(FieldDef *key_field, StructDef &struct_def,
+                           CodeWriter &writer) const {
+    std::stringstream params;
+    params << "obj: " << Esc(struct_def.name) << "?"
+           << ", ";
+    params << "vectorLocation: Int, ";
+    params << "key: " << GenTypeGet(key_field->value.type) << ", ";
+    params << "bb: ByteBuffer";
+
+    auto statements = [&]() {
+      auto base_type = key_field->value.type.base_type;
+      writer.SetValue("struct_name", Esc(struct_def.name));
+      if (base_type == BASE_TYPE_STRING) {
+        writer +=
+            "val byteKey = key."
+            "toByteArray(Table.UTF8_CHARSET.get()!!)";
+      }
+      writer += "var span = bb.getInt(vectorLocation - 4)";
+      writer += "var start = 0";
+      writer += "while (span != 0) {";
+      writer.IncrementIdentLevel();
+      writer += "var middle = span / 2";
+      writer +=
+          "val tableOffset = __indirect(vector"
+          "Location + 4 * (start + middle), bb)";
+      if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+        writer += "val comp = compareStrings(\\";
+        writer += GenOffsetGetter(key_field) + "\\";
+        writer += ", byteKey, bb)";
+      } else {
+        auto cast = CastToUsigned(key_field->value.type);
+        auto get_val = GenLookupByKey(key_field, "bb");
+        writer += "val value = " + get_val + cast;
+        writer += "val comp = value.compareTo(key)";
+      }
+      writer += "when {";
+      writer.IncrementIdentLevel();
+      writer += "comp > 0 -> span = middle";
+      writer += "comp < 0 -> {";
+      writer.IncrementIdentLevel();
+      writer += "middle++";
+      writer += "start += middle";
+      writer += "span -= middle";
+      writer.DecrementIdentLevel();
+      writer += "}";  // end comp < 0
+      writer += "else -> {";
+      writer.IncrementIdentLevel();
+      writer += "return (obj ?: {{struct_name}}()).__assign(tableOffset, bb)";
+      writer.DecrementIdentLevel();
+      writer += "}";  // end else
+      writer.DecrementIdentLevel();
+      writer += "}";  // end when
+      writer.DecrementIdentLevel();
+      writer += "}";  // end while
+      writer += "return null";
+    };
+    GenerateFun(writer, "__lookup_by_key", params.str(),
+                Esc(struct_def.name) + "?", statements);
+  }
 
-                    GenerateGetRootAsAccessors(Esc(struct_def.name), writer);
-                    GenerateBufferHasIdentifier(struct_def, writer);
-                    GenerateTableCreator(struct_def, writer);
-
-                    GenerateStartStructMethod(struct_def, writer);
-
-                    // Static Add for fields
-                    auto fields = struct_def.fields.vec;
-                    int field_pos = -1;
-                    for (auto it = fields.begin(); it != fields.end(); ++it) {
-                        auto &field = **it;
-                        field_pos++;
-                        if (field.deprecated) continue;
-                        if (field.key) key_field = &field;
-                        GenerateAddField(NumToString(field_pos), field, writer);
-
-                        if (field.value.type.base_type == BASE_TYPE_VECTOR) {
-                            auto vector_type = field.value.type.VectorType();
-                            if (!IsStruct(vector_type)) {
-                                GenerateCreateVectorField(field, writer);
-                            }
-                            GenerateStartVectorField(field, writer);
-                        }
-                    }
-
-                    GenerateEndStructMethod(struct_def, writer);
-                    auto file_identifier = parser_.file_identifier_;
-                    if (parser_.root_struct_def_ == &struct_def) {
-                        GenerateFinishStructBuffer(struct_def,
-                                                   file_identifier,
-                                                   writer);
-                        GenerateFinishSizePrefixed(struct_def,
-                                                   file_identifier,
-                                                   writer);
-                    }
-
-                    if (struct_def.has_key) {
-                        GenerateLookupByKey(key_field, struct_def, writer);
-                    }
-                } else {
-                    GenerateStaticConstructor(struct_def, writer);
-                }
-            });
-        }
+  void GenerateFinishSizePrefixed(StructDef &struct_def,
+                                  const std::string &identifier,
+                                  CodeWriter &writer) const {
+    auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
+    auto params = "builder: FlatBufferBuilder, offset: Int";
+    auto method_name = "finishSizePrefixed" + Esc(struct_def.name) + "Buffer";
+    GenerateFunOneLine(writer, method_name, params, "", [&]() {
+      writer += "builder.finishSizePrefixed(offset" + id + ")";
+    });
+  }
+  void GenerateFinishStructBuffer(StructDef &struct_def,
+                                  const std::string &identifier,
+                                  CodeWriter &writer) const {
+    auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
+    auto params = "builder: FlatBufferBuilder, offset: Int";
+    auto method_name = "finish" + Esc(struct_def.name) + "Buffer";
+    GenerateFunOneLine(writer, method_name, params, "",
+                       [&]() { writer += "builder.finish(offset" + id + ")"; });
+  }
 
-        // class closing
-        writer.DecrementIdentLevel();
-        writer += "}";
-    }
+  void GenerateEndStructMethod(StructDef &struct_def,
+                               CodeWriter &writer) const {
+    // Generate end{{TableName}}(builder: FlatBufferBuilder) method
+    auto name = "end" + Esc(struct_def.name);
+    auto params = "builder: FlatBufferBuilder";
+    auto returns = "Int";
+    auto field_vec = struct_def.fields.vec;
+
+    GenerateFun(writer, name, params, returns, [&]() {
+      writer += "val o = builder.endTable()";
+      writer.IncrementIdentLevel();
+      for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
+        auto &field = **it;
+        if (field.deprecated || !field.required) { continue; }
+        writer.SetValue("offset", NumToString(field.value.offset));
+        writer += "builder.required(o, {{offset}})";
+      }
+      writer.DecrementIdentLevel();
+      writer += "return o";
+    });
+  }
 
-    // TODO: move key_field to reference instead of pointer
-    void GenerateLookupByKey(FieldDef *key_field, StructDef &struct_def,
-                             CodeWriter &writer) const {
-        std::stringstream params;
-        params << "obj: " << Esc(struct_def.name) << "?" << ", ";
-        params << "vectorLocation: Int, ";
-        params << "key: " <<  GenTypeGet(key_field->value.type) << ", ";
-        params << "bb: ByteBuffer";
-
-        auto statements = [&]() {
-            auto base_type = key_field->value.type.base_type;
-            writer.SetValue("struct_name", Esc(struct_def.name));
-            if (base_type == BASE_TYPE_STRING) {
-                writer += "val byteKey = key."
-                        "toByteArray(Table.UTF8_CHARSET.get()!!)";
-            }
-            writer += "var span = bb.getInt(vectorLocation - 4)";
-            writer += "var start = 0";
-            writer += "while (span != 0) {";
-            writer.IncrementIdentLevel();
-            writer += "var middle = span / 2";
-            writer += "val tableOffset = __indirect(vector"
-                    "Location + 4 * (start + middle), bb)";
-            if (key_field->value.type.base_type == BASE_TYPE_STRING) {
-                writer += "val comp = compareStrings(\\";
-                writer += GenOffsetGetter(key_field) + "\\";
-                writer += ", byteKey, bb)";
-            } else {
-                auto cast = CastToUsigned(key_field->value.type);
-                auto get_val = GenLookupByKey(key_field, "bb");
-                writer += "val value = " + get_val + cast;
-                writer += "val comp = value.compareTo(key)";
-            }
-            writer += "when {";
-            writer.IncrementIdentLevel();
-            writer += "comp > 0 -> span = middle";
-            writer += "comp < 0 -> {";
-            writer.IncrementIdentLevel();
-            writer += "middle++";
-            writer += "start += middle";
-            writer += "span -= middle";
-            writer.DecrementIdentLevel();
-            writer += "}"; // end comp < 0
-            writer += "else -> {";
-            writer.IncrementIdentLevel();
-            writer += "return (obj ?: {{struct_name}}()).__assign(tableOffset, bb)";
-            writer.DecrementIdentLevel();
-            writer += "}"; // end else
-            writer.DecrementIdentLevel();
-            writer += "}"; // end when
-            writer.DecrementIdentLevel();
-            writer += "}"; // end while
-            writer += "return null";
-        };
-        GenerateFun(writer, "__lookup_by_key",
-                    params.str(),
-                    Esc(struct_def.name) + "?",
-                    statements);
-    }
+  // Generate a method to create a vector from a Kotlin array.
+  void GenerateCreateVectorField(FieldDef &field, CodeWriter &writer) const {
+    auto vector_type = field.value.type.VectorType();
+    auto method_name = "create" + MakeCamel(Esc(field.name)) + "Vector";
+    auto params = "builder: FlatBufferBuilder, data: " +
+                  GenTypeBasic(vector_type.base_type) + "Array";
+    writer.SetValue("size", NumToString(InlineSize(vector_type)));
+    writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
+    writer.SetValue("root", GenMethod(vector_type));
+    writer.SetValue("cast", CastToSigned(vector_type));
+
+    GenerateFun(writer, method_name, params, "Int", [&]() {
+      writer += "builder.startVector({{size}}, data.size, {{align}})";
+      writer += "for (i in data.size - 1 downTo 0) {";
+      writer.IncrementIdentLevel();
+      writer += "builder.add{{root}}(data[i]{{cast}})";
+      writer.DecrementIdentLevel();
+      writer += "}";
+      writer += "return builder.endVector()";
+    });
+  }
 
-    void GenerateFinishSizePrefixed(StructDef &struct_def,
-                                                const std::string &identifier,
-                                                CodeWriter &writer) const {
-        auto id = identifier.length() > 0  ? ", \"" + identifier + "\"" : "";
-        auto params = "builder: FlatBufferBuilder, offset: Int";
-        auto method_name = "finishSizePrefixed" + Esc(struct_def.name) + "Buffer";
-        GenerateFunOneLine(writer, method_name, params, "", [&]() {
-            writer += "builder.finishSizePrefixed(offset" + id  + ")";
-        });
-    }
-    void GenerateFinishStructBuffer(StructDef &struct_def,
-                                    const std::string &identifier,
-                                    CodeWriter &writer) const {
-        auto id = identifier.length() > 0  ? ", \"" + identifier + "\"" : "";
-        auto params = "builder: FlatBufferBuilder, offset: Int";
-        auto method_name = "finish" + Esc(struct_def.name) + "Buffer";
-        GenerateFunOneLine(writer, method_name, params, "", [&]() {
-            writer += "builder.finish(offset" + id + ")";
+  void GenerateStartVectorField(FieldDef &field, CodeWriter &writer) const {
+    // Generate a method to start a vector, data to be added manually
+    // after.
+    auto vector_type = field.value.type.VectorType();
+    auto params = "builder: FlatBufferBuilder, numElems: Int";
+    writer.SetValue("size", NumToString(InlineSize(vector_type)));
+    writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
+
+    GenerateFunOneLine(
+        writer, "start" + MakeCamel(Esc(field.name) + "Vector", true), params,
+        "", [&]() {
+          writer += "builder.startVector({{size}}, numElems, {{align}})";
         });
-    }
+  }
 
-    void GenerateEndStructMethod(StructDef &struct_def, CodeWriter &writer) const {
-        // Generate end{{TableName}}(builder: FlatBufferBuilder) method
-        auto name = "end" + Esc(struct_def.name);
-        auto params = "builder: FlatBufferBuilder";
-        auto returns = "Int";
-        auto field_vec = struct_def.fields.vec;
-
-        GenerateFun(writer, name, params, returns, [&](){
-            writer += "val o = builder.endTable()";
-            writer.IncrementIdentLevel();
-            for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
-                auto &field = **it;
-                if (field.deprecated || !field.required) {
-                    continue;
-                }
-                writer.SetValue("offset", NumToString(field.value.offset));
-                writer += "builder.required(o, {{offset}})";
-            }
-            writer.DecrementIdentLevel();
-            writer += "return o";
-        });
-    }
+  void GenerateAddField(std::string field_pos, FieldDef &field,
+                        CodeWriter &writer) const {
+    auto field_type = GenTypeBasic(field.value.type.base_type);
+    auto secondArg = MakeCamel(Esc(field.name), false) + ": " + field_type;
+    GenerateFunOneLine(writer, "add" + MakeCamel(Esc(field.name), true),
+                       "builder: FlatBufferBuilder, " + secondArg, "", [&]() {
+                         auto method = GenMethod(field.value.type);
+                         writer.SetValue("field_name",
+                                         MakeCamel(Esc(field.name), false));
+                         writer.SetValue("method_name", method);
+                         writer.SetValue("pos", field_pos);
+                         writer.SetValue("default", GenFBBDefaultValue(field));
+                         writer.SetValue("cast", GenFBBValueCast(field));
+
+                         writer += "builder.add{{method_name}}({{pos}}, \\";
+                         writer += "{{field_name}}{{cast}}, {{default}})";
+                       });
+  }
 
-    // Generate a method to create a vector from a Kotlin array.
-    void GenerateCreateVectorField(FieldDef &field, CodeWriter &writer) const {
-        auto vector_type = field.value.type.VectorType();
-        auto method_name = "create" + MakeCamel(Esc(field.name)) + "Vector";
-        auto params = "builder: FlatBufferBuilder, data: " +
-                GenTypeBasic(vector_type.base_type) + "Array";
-        writer.SetValue("size", NumToString(InlineSize(vector_type)));
-        writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
-        writer.SetValue("root", GenMethod(vector_type));
-        writer.SetValue("cast", CastToSigned(vector_type));
-
-        GenerateFun(writer, method_name, params, "Int", [&](){
-            writer += "builder.startVector({{size}}, data.size, {{align}})";
-            writer += "for (i in data.size - 1 downTo 0) {";
-            writer.IncrementIdentLevel();
-            writer += "builder.add{{root}}(data[i]{{cast}})";
-            writer.DecrementIdentLevel();
-            writer += "}";
-            writer += "return builder.endVector()";
-        });
+  static std::string ToSignedType(const Type &type) {
+    switch (type.base_type) {
+      case BASE_TYPE_UINT: return GenTypeBasic(BASE_TYPE_INT);
+      case BASE_TYPE_ULONG: return GenTypeBasic(BASE_TYPE_LONG);
+      case BASE_TYPE_UCHAR:
+      case BASE_TYPE_NONE:
+      case BASE_TYPE_UTYPE: return GenTypeBasic(BASE_TYPE_CHAR);
+      case BASE_TYPE_USHORT: return GenTypeBasic(BASE_TYPE_SHORT);
+      case BASE_TYPE_VECTOR: return ToSignedType(type.VectorType());
+      default: return GenTypeBasic(type.base_type);
     }
+  }
 
-    void GenerateStartVectorField(FieldDef &field, CodeWriter &writer) const {
-        // Generate a method to start a vector, data to be added manually
-        // after.
-        auto vector_type = field.value.type.VectorType();
-        auto params = "builder: FlatBufferBuilder, numElems: Int";
-        writer.SetValue("size", NumToString(InlineSize(vector_type)));
-        writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
-
-        GenerateFunOneLine(writer,
-                           "start" + MakeCamel(Esc(field.name) + "Vector", true),
-                           params,
-                           "",
-                           [&]() {
-            writer += "builder.startVector({{size}}, numElems, {{align}})";
-        });
-    }
+  static std::string FlexBufferBuilderCast(const std::string &method,
+                                           FieldDef &field, bool isFirst) {
+    auto field_type = GenTypeBasic(field.value.type.base_type);
+    std::string to_type;
+    if (method == "Boolean")
+      to_type = "Boolean";
+    else if (method == "Long")
+      to_type = "Long";
+    else if (method == "Int" || method == "Offset" || method == "Struct")
+      to_type = "Int";
+    else if (method == "Byte" || method.empty())
+      to_type = isFirst ? "Byte" : "Int";
+    else if (method == "Short")
+      to_type = isFirst ? "Short" : "Int";
+    else if (method == "Double")
+      to_type = "Double";
+    else if (method == "Float")
+      to_type = isFirst ? "Float" : "Double";
+    else if (method == "UByte")
+
+      if (field_type != to_type) return ".to" + to_type + "()";
+    return "";
+  }
 
-    void GenerateAddField(std::string field_pos, FieldDef &field,
-                          CodeWriter &writer) const {
-        auto field_type = GenTypeBasic(field.value.type.base_type);
-        auto secondArg = MakeCamel(Esc(field.name), false) + ": " + field_type;
-        GenerateFunOneLine(writer, "add" + MakeCamel(Esc(field.name), true),
-                           "builder: FlatBufferBuilder, " + secondArg, "", [&](){
-            auto method = GenMethod(field.value.type);
-            writer.SetValue("field_name", MakeCamel(Esc(field.name), false));
-            writer.SetValue("method_name", method);
-            writer.SetValue("pos", field_pos);
-            writer.SetValue("default", GenFBBDefaultValue(field));
-            writer.SetValue("cast", GenFBBValueCast(field));
-
-            writer += "builder.add{{method_name}}({{pos}}, \\";
-            writer += "{{field_name}}{{cast}}, {{default}})";
-        });
-    }
+  // fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11)
+  void GenerateStartStructMethod(StructDef &struct_def,
+                                 CodeWriter &code) const {
+    GenerateFunOneLine(code, "start" + Esc(struct_def.name),
+                       "builder: FlatBufferBuilder", "", [&]() {
+                         code += "builder.startTable(" +
+                                 NumToString(struct_def.fields.vec.size()) +
+                                 ")";
+                       });
+  }
 
-    static std::string ToSignedType(const Type & type) {
-        switch(type.base_type) {
-        case BASE_TYPE_UINT:
-            return GenTypeBasic(BASE_TYPE_INT);
-        case BASE_TYPE_ULONG:
-            return GenTypeBasic(BASE_TYPE_LONG);
-        case BASE_TYPE_UCHAR:
-        case BASE_TYPE_NONE:
-        case BASE_TYPE_UTYPE:
-            return GenTypeBasic(BASE_TYPE_CHAR);
-        case BASE_TYPE_USHORT:
-            return GenTypeBasic(BASE_TYPE_SHORT);
-        case BASE_TYPE_VECTOR:
-            return ToSignedType(type.VectorType());
-        default:
-            return GenTypeBasic(type.base_type);
-        }
+  void GenerateTableCreator(StructDef &struct_def, CodeWriter &writer) const {
+    // Generate a method that creates a table in one go. This is only possible
+    // when the table has no struct fields, since those have to be created
+    // inline, and there's no way to do so in Java.
+    bool has_no_struct_fields = true;
+    int num_fields = 0;
+    auto fields_vec = struct_def.fields.vec;
+
+    for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      if (IsStruct(field.value.type)) {
+        has_no_struct_fields = false;
+      } else {
+        num_fields++;
+      }
     }
+    // JVM specifications restrict default constructor params to be < 255.
+    // Longs and doubles take up 2 units, so we set the limit to be < 127.
+    if (has_no_struct_fields && num_fields && num_fields < 127) {
+      // Generate a table constructor of the form:
+      // public static int createName(FlatBufferBuilder builder, args...)
+
+      auto name = "create" + Esc(struct_def.name);
+      std::stringstream params;
+      params << "builder: FlatBufferBuilder";
+      for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+        auto &field = **it;
+        if (field.deprecated) continue;
+        params << ", " << MakeCamel(Esc(field.name), false);
+        if (!IsScalar(field.value.type.base_type)) {
+          params << "Offset: ";
+        } else {
+          params << ": ";
+        }
+        params << GenTypeBasic(field.value.type.base_type);
+      }
 
-    static std::string FlexBufferBuilderCast(const std::string &method,
-                                      FieldDef &field,
-                                      bool isFirst) {
-        auto field_type = GenTypeBasic(field.value.type.base_type);
-        std::string to_type;
-        if (method == "Boolean")
-            to_type = "Boolean";
-        else if (method == "Long")
-            to_type = "Long";
-        else if (method == "Int" || method == "Offset" || method == "Struct")
-            to_type = "Int";
-        else if (method == "Byte" || method.empty())
-            to_type =  isFirst ? "Byte" : "Int";
-        else if (method == "Short")
-            to_type =  isFirst ? "Short" : "Int";
-        else if (method == "Double")
-            to_type =  "Double";
-        else if (method == "Float")
-            to_type =  isFirst ? "Float" : "Double";
-        else if (method == "UByte")
-
-        if (field_type != to_type)
-            return ".to" + to_type + "()";
-        return "";
-    }
+      GenerateFun(writer, name, params.str(), "Int", [&]() {
+        writer.SetValue("vec_size", NumToString(fields_vec.size()));
 
-    // fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11)
-    void GenerateStartStructMethod(StructDef &struct_def, CodeWriter &code) const {
-        GenerateFunOneLine(code, "start" + Esc(struct_def.name),
-                           "builder: FlatBufferBuilder", "", [&] () {
-            code += "builder.startTable("+ NumToString(struct_def.fields.vec.size()) + ")";
-        });
+        writer += "builder.startTable({{vec_size}})";
+
+        auto sortbysize = struct_def.sortbysize;
+        auto largest = sortbysize ? sizeof(largest_scalar_t) : 1;
+        for (size_t size = largest; size; size /= 2) {
+          for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) {
+            auto &field = **it;
+            auto base_type_size = SizeOf(field.value.type.base_type);
+            if (!field.deprecated && (!sortbysize || size == base_type_size)) {
+              writer.SetValue("camel_field_name",
+                              MakeCamel(Esc(field.name), true));
+              writer.SetValue("field_name", MakeCamel(Esc(field.name), false));
+
+              writer += "add{{camel_field_name}}(builder, {{field_name}}\\";
+              if (!IsScalar(field.value.type.base_type)) {
+                writer += "Offset\\";
+              }
+              writer += ")";
+            }
+          }
+        }
+        writer += "return end{{struct_name}}(builder)";
+      });
     }
+  }
+  void GenerateBufferHasIdentifier(StructDef &struct_def,
+                                   CodeWriter &writer) const {
+    auto file_identifier = parser_.file_identifier_;
+    // Check if a buffer has the identifier.
+    if (parser_.root_struct_def_ != &struct_def || !file_identifier.length())
+      return;
+    auto name = MakeCamel(Esc(struct_def.name), false);
+    GenerateFunOneLine(writer, name + "BufferHasIdentifier", "_bb: ByteBuffer",
+                       "Boolean", [&]() {
+                         writer += "__has_identifier(_bb, \"" +
+                                   file_identifier + "\")";
+                       });
+  }
 
-    void GenerateTableCreator(StructDef &struct_def, CodeWriter &writer) const {
-        // Generate a method that creates a table in one go. This is only possible
-        // when the table has no struct fields, since those have to be created
-        // inline, and there's no way to do so in Java.
-        bool has_no_struct_fields = true;
-        int num_fields = 0;
-        auto fields_vec = struct_def.fields.vec;
+  void GenerateStructGetters(StructDef &struct_def, CodeWriter &writer) const {
+    auto fields_vec = struct_def.fields.vec;
+    FieldDef *key_field = nullptr;
+    for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      if (field.key) key_field = &field;
+
+      GenerateComment(field.doc_comment, writer, &comment_config);
+
+      auto field_name = MakeCamel(Esc(field.name), false);
+      auto field_type = GenTypeGet(field.value.type);
+      auto field_default_value = GenDefaultValue(field);
+      auto return_type = GenTypeGet(field.value.type);
+      auto bbgetter = ByteBufferGetter(field.value.type, "bb");
+      auto ucast = CastToUsigned(field);
+      auto offset_val = NumToString(field.value.offset);
+      auto offset_prefix =
+          "val o = __offset(" + offset_val + "); return o != 0 ? ";
+      auto value_base_type = field.value.type.base_type;
+      // Most field accessors need to retrieve and test the field offset
+      // first, this is the offset value for that:
+      writer.SetValue("offset", NumToString(field.value.offset));
+      writer.SetValue("return_type", return_type);
+      writer.SetValue("field_type", field_type);
+      writer.SetValue("field_name", field_name);
+      writer.SetValue("field_default", field_default_value);
+      writer.SetValue("bbgetter", bbgetter);
+      writer.SetValue("ucast", ucast);
+
+      auto opt_ret_type = return_type + "?";
+      // Generate the accessors that don't do object reuse.
+      if (value_base_type == BASE_TYPE_STRUCT) {
+        // Calls the accessor that takes an accessor object with a
+        // new object.
+        // val pos
+        //     get() = pos(Vec3())
+        GenerateGetterOneLine(writer, field_name, opt_ret_type, [&]() {
+          writer += "{{field_name}}({{field_type}}())";
+        });
+      } else if (value_base_type == BASE_TYPE_VECTOR &&
+                 field.value.type.element == BASE_TYPE_STRUCT) {
+        // Accessors for vectors of structs also take accessor objects,
+        // this generates a variant without that argument.
+        // ex: fun weapons(j: Int) = weapons(Weapon(), j)
+        GenerateFunOneLine(writer, field_name, "j: Int", opt_ret_type, [&]() {
+          writer += "{{field_name}}({{return_type}}(), j)";
+        });
+      }
 
-        for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
-            auto &field = **it;
-            if (field.deprecated) continue;
-            if (IsStruct(field.value.type)) {
-                has_no_struct_fields = false;
+      if (IsScalar(value_base_type)) {
+        if (struct_def.fixed) {
+          GenerateGetterOneLine(writer, field_name, return_type, [&]() {
+            writer += "{{bbgetter}}(bb_pos + {{offset}}){{ucast}}";
+          });
+        } else {
+          GenerateGetter(writer, field_name, return_type, [&]() {
+            writer += "val o = __offset({{offset}})";
+            writer +=
+                "return if(o != 0) {{bbgetter}}"
+                "(o + bb_pos){{ucast}} else "
+                "{{field_default}}";
+          });
+        }
+      } else {
+        switch (value_base_type) {
+          case BASE_TYPE_STRUCT:
+            if (struct_def.fixed) {
+              // create getter with object reuse
+              // ex:
+              // fun pos(obj: Vec3) : Vec3? = obj.__assign(bb_pos + 4, bb)
+              // ? adds nullability annotation
+              GenerateFunOneLine(
+                  writer, field_name, "obj: " + field_type, return_type + "?",
+                  [&]() { writer += "obj.__assign(bb_pos + {{offset}}, bb)"; });
             } else {
-                num_fields++;
+              // create getter with object reuse
+              // ex:
+              //  fun pos(obj: Vec3) : Vec3? {
+              //      val o = __offset(4)
+              //      return if(o != 0) {
+              //          obj.__assign(o + bb_pos, bb)
+              //      else {
+              //          null
+              //      }
+              //  }
+              // ? adds nullability annotation
+              GenerateFun(
+                  writer, field_name, "obj: " + field_type, return_type + "?",
+                  [&]() {
+                    auto fixed = field.value.type.struct_def->fixed;
+
+                    writer.SetValue("seek", Indirect("o + bb_pos", fixed));
+                    OffsetWrapper(
+                        writer, offset_val,
+                        [&]() { writer += "obj.__assign({{seek}}, bb)"; },
+                        [&]() { writer += "null"; });
+                  });
             }
-        }
-        // JVM specifications restrict default constructor params to be < 255.
-        // Longs and doubles take up 2 units, so we set the limit to be < 127.
-        if (has_no_struct_fields && num_fields && num_fields < 127) {
-            // Generate a table constructor of the form:
-            // public static int createName(FlatBufferBuilder builder, args...)
-
-            auto name = "create" + Esc(struct_def.name);
-            std::stringstream params;
-            params << "builder: FlatBufferBuilder";
-            for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
-                auto &field = **it;
-                if (field.deprecated) continue;
-                params << ", " << MakeCamel(Esc(field.name), false);
-                if (!IsScalar(field.value.type.base_type)){
-                    params << "Offset: ";
-                } else {
-                    params << ": ";
-                }
-                params << GenTypeBasic(field.value.type.base_type);
+            break;
+          case BASE_TYPE_STRING:
+            // create string getter
+            // e.g.
+            // val Name : String?
+            //     get() = {
+            //         val o = __offset(10)
+            //         return if (o != 0) __string(o + bb_pos) else null
+            //     }
+            // ? adds nullability annotation
+            GenerateGetter(writer, field_name, return_type + "?", [&]() {
+              writer += "val o = __offset({{offset}})";
+              writer += "return if (o != 0) __string(o + bb_pos) else null";
+            });
+            break;
+          case BASE_TYPE_VECTOR: {
+            // e.g.
+            // fun inventory(j: Int) : UByte {
+            //     val o = __offset(14)
+            //     return if (o != 0) {
+            //         bb.get(__vector(o) + j * 1).toUByte()
+            //     } else {
+            //        0
+            //     }
+            // }
+
+            auto vectortype = field.value.type.VectorType();
+            std::string params = "j: Int";
+            std::string nullable = IsScalar(vectortype.base_type) ? "" : "?";
+
+            if (vectortype.base_type == BASE_TYPE_STRUCT ||
+                vectortype.base_type == BASE_TYPE_UNION) {
+              params = "obj: " + field_type + ", j: Int";
             }
 
-            GenerateFun(writer, name, params.str(), "Int", [&]() {
-                writer.SetValue("vec_size", NumToString(fields_vec.size()));
-
-                writer += "builder.startTable({{vec_size}})";
-
-                auto sortbysize = struct_def.sortbysize;
-                auto largest = sortbysize ? sizeof(largest_scalar_t) : 1;
-                for (size_t size = largest; size; size /= 2) {
-                    for (auto it = fields_vec.rbegin(); it != fields_vec.rend();
-                         ++it) {
-                        auto &field = **it;
-                        auto base_type_size = SizeOf(field.value.type.base_type);
-                        if (!field.deprecated &&
-                                (!sortbysize || size == base_type_size)) {
-                            writer.SetValue("camel_field_name",
-                                          MakeCamel(Esc(field.name), true));
-                            writer.SetValue("field_name",
-                                          MakeCamel(Esc(field.name), false));
-
-                            writer += "add{{camel_field_name}}(builder, {{field_name}}\\";
-                            if (!IsScalar(field.value.type.base_type)){
-                                writer += "Offset\\";
-                            }
-                            writer += ")";
-                        }
-                    }
+            auto ret_type = return_type + nullable;
+            GenerateFun(writer, field_name, params, ret_type, [&]() {
+              auto inline_size = NumToString(InlineSize(vectortype));
+              auto index = "__vector(o) + j * " + inline_size;
+              auto not_found = NotFoundReturn(field.value.type.element);
+              auto found = "";
+              writer.SetValue("index", index);
+              switch (vectortype.base_type) {
+                case BASE_TYPE_STRUCT: {
+                  bool fixed = vectortype.struct_def->fixed;
+                  writer.SetValue("index", Indirect(index, fixed));
+                  found = "obj.__assign({{index}}, bb)";
+                  break;
                 }
-              writer += "return end{{struct_name}}(builder)";
+                case BASE_TYPE_UNION:
+                  found = "{{bbgetter}}(obj, {{index}} - bb_pos){{ucast}}";
+                  break;
+                default: found = "{{bbgetter}}({{index}}){{ucast}}";
+              }
+              OffsetWrapper(
+                  writer, offset_val, [&]() { writer += found; },
+                  [&]() { writer += not_found; });
             });
+            break;
+          }
+          case BASE_TYPE_UNION:
+            GenerateFun(writer, field_name, "obj: " + field_type,
+                        return_type + "?", [&]() {
+                          writer += OffsetWrapperOneLine(
+                              offset_val, bbgetter + "(obj, o + bb_pos)",
+                              "null");
+                        });
+            break;
+          default: FLATBUFFERS_ASSERT(0);
         }
+      }
 
-    }
-    void GenerateBufferHasIdentifier(StructDef &struct_def,
-                                     CodeWriter &writer) const {
-        auto file_identifier = parser_.file_identifier_;
-        // Check if a buffer has the identifier.
-        if (parser_.root_struct_def_ != &struct_def || !file_identifier.length())
-            return;
-        auto name = MakeCamel(Esc(struct_def.name), false);
-        GenerateFunOneLine(writer, name + "BufferHasIdentifier",
-                           "_bb: ByteBuffer",
-                           "Boolean",
-                           [&]() {
-            writer += "__has_identifier(_bb, \"" + file_identifier + "\")";
+      if (value_base_type == BASE_TYPE_VECTOR) {
+        // Generate Lenght functions for vectors
+        GenerateGetter(writer, field_name + "Length", "Int", [&]() {
+          writer += OffsetWrapperOneLine(offset_val, "__vector_len(o)", "0");
         });
-    }
-
-    void GenerateStructGetters(StructDef &struct_def, CodeWriter &writer) const {
-        auto fields_vec = struct_def.fields.vec;
-        FieldDef *key_field = nullptr;
-        for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
-            auto &field = **it;
-            if (field.deprecated) continue;
-            if (field.key) key_field = &field;
 
-            GenerateComment(field.doc_comment, writer, &comment_config);
-
-            auto field_name = MakeCamel(Esc(field.name), false);
-            auto field_type = GenTypeGet(field.value.type);
-            auto field_default_value = GenDefaultValue(field);
-            auto return_type = GenTypeGet(field.value.type);
-            auto bbgetter = ByteBufferGetter(field.value.type, "bb");
-            auto ucast = CastToUsigned(field);
-            auto offset_val = NumToString(field.value.offset);
-            auto offset_prefix = "val o = __offset(" + offset_val
-                                 + "); return o != 0 ? ";
-            auto value_base_type = field.value.type.base_type;
-            // Most field accessors need to retrieve and test the field offset
-            // first, this is the offset value for that:
-            writer.SetValue("offset", NumToString(field.value.offset));
-            writer.SetValue("return_type", return_type);
-            writer.SetValue("field_type", field_type);
-            writer.SetValue("field_name", field_name);
-            writer.SetValue("field_default", field_default_value);
-            writer.SetValue("bbgetter", bbgetter);
-            writer.SetValue("ucast", ucast);
-
-            auto opt_ret_type = return_type + "?";
-            // Generate the accessors that don't do object reuse.
-            if (value_base_type == BASE_TYPE_STRUCT) {
-                // Calls the accessor that takes an accessor object with a
-                // new object.
-                // val pos
-                //     get() = pos(Vec3())
-                GenerateGetterOneLine(writer, field_name, opt_ret_type, [&](){
-                    writer += "{{field_name}}({{field_type}}())";
-                });
-            } else if (value_base_type == BASE_TYPE_VECTOR &&
-                       field.value.type.element == BASE_TYPE_STRUCT) {
-                // Accessors for vectors of structs also take accessor objects,
-                // this generates a variant without that argument.
-                // ex: fun weapons(j: Int) = weapons(Weapon(), j)
-                GenerateFunOneLine(writer, field_name, "j: Int", opt_ret_type, [&](){
-                    writer += "{{field_name}}({{return_type}}(), j)";
-                });
+        // See if we should generate a by-key accessor.
+        if (field.value.type.element == BASE_TYPE_STRUCT &&
+            !field.value.type.struct_def->fixed) {
+          auto &sd = *field.value.type.struct_def;
+          auto &fields = sd.fields.vec;
+          for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
+            auto &kfield = **kit;
+            if (kfield.key) {
+              auto qualified_name = WrapInNameSpace(sd);
+              auto name = MakeCamel(Esc(field.name), false) + "ByKey";
+              auto params = "key: " + GenTypeGet(kfield.value.type);
+              auto rtype = qualified_name + "?";
+              GenerateFun(writer, name, params, rtype, [&]() {
+                OffsetWrapper(
+                    writer, offset_val,
+                    [&]() {
+                      writer += qualified_name +
+                                ".__lookup_by_key(null, __vector(o), key, bb)";
+                    },
+                    [&]() { writer += "null"; });
+              });
+
+              auto param2 = "obj: " + qualified_name +
+                            ", key: " + GenTypeGet(kfield.value.type);
+              GenerateFun(writer, name, param2, rtype, [&]() {
+                OffsetWrapper(
+                    writer, offset_val,
+                    [&]() {
+                      writer += qualified_name +
+                                ".__lookup_by_key(obj, __vector(o), key, bb)";
+                    },
+                    [&]() { writer += "null"; });
+              });
+
+              break;
             }
+          }
+        }
+      }
 
-            if (IsScalar(value_base_type)) {
-                if (struct_def.fixed) {
-                    GenerateGetterOneLine(writer, field_name, return_type, [&](){
-                        writer += "{{bbgetter}}(bb_pos + {{offset}}){{ucast}}";
-                    });
-                } else {
-                    GenerateGetter(writer, field_name, return_type, [&](){
-                        writer += "val o = __offset({{offset}})";
-                        writer += "return if(o != 0) {{bbgetter}}"
-                                  "(o + bb_pos){{ucast}} else "
-                                  "{{field_default}}";
-                    });
-                }
-            } else {
-                switch (value_base_type) {
-                case BASE_TYPE_STRUCT:
-                    if (struct_def.fixed) {
-                        // create getter with object reuse
-                        // ex:
-                        // fun pos(obj: Vec3) : Vec3? = obj.__assign(bb_pos + 4, bb)
-                        // ? adds nullability annotation
-                        GenerateFunOneLine(writer,
-                                           field_name, "obj: " + field_type ,
-                                           return_type + "?", [&](){
-                            writer += "obj.__assign(bb_pos + {{offset}}, bb)";
-                        });
-                    } else {
-                        // create getter with object reuse
-                        // ex:
-                        //  fun pos(obj: Vec3) : Vec3? {
-                        //      val o = __offset(4)
-                        //      return if(o != 0) {
-                        //          obj.__assign(o + bb_pos, bb)
-                        //      else {
-                        //          null
-                        //      }
-                        //  }
-                        // ? adds nullability annotation
-                        GenerateFun(writer, field_name, "obj: " + field_type,
-                                    return_type + "?", [&](){
-                            auto fixed = field.value.type.struct_def->fixed;
-
-                            writer.SetValue("seek", Indirect("o + bb_pos", fixed));
-                            OffsetWrapper(writer,
-                                          offset_val,
-                                          [&]() { writer += "obj.__assign({{seek}}, bb)"; },
-                                          [&]() { writer += "null"; });
-                        });
-                    }
-                    break;
-                case BASE_TYPE_STRING:
-                    // create string getter
-                    // e.g.
-                    // val Name : String?
-                    //     get() = {
-                    //         val o = __offset(10)
-                    //         return if (o != 0) __string(o + bb_pos) else null
-                    //     }
-                    // ? adds nullability annotation
-                    GenerateGetter(writer, field_name, return_type + "?", [&](){
-
-                        writer += "val o = __offset({{offset}})";
-                        writer += "return if (o != 0) __string(o + bb_pos) else null";
-                    });
-                    break;
-                case BASE_TYPE_VECTOR: {
-                    // e.g.
-                    // fun inventory(j: Int) : UByte {
-                    //     val o = __offset(14)
-                    //     return if (o != 0) {
-                    //         bb.get(__vector(o) + j * 1).toUByte()
-                    //     } else {
-                    //        0
-                    //     }
-                    // }
-
-                    auto vectortype = field.value.type.VectorType();
-                    std::string params = "j: Int";
-                    std::string nullable = IsScalar(vectortype.base_type) ? ""
-                                                                          : "?";
-
-                    if (vectortype.base_type == BASE_TYPE_STRUCT ||
-                            vectortype.base_type == BASE_TYPE_UNION) {
-                        params = "obj: " + field_type + ", j: Int";
-                    }
-
-                    auto ret_type = return_type + nullable;
-                    GenerateFun(writer, field_name, params, ret_type, [&](){
-                        auto inline_size = NumToString(InlineSize(vectortype));
-                        auto index = "__vector(o) + j * " + inline_size;
-                        auto not_found = NotFoundReturn(field.value.type.element);
-                        auto found = "";
-                        writer.SetValue("index", index);
-                        switch(vectortype.base_type) {
-                        case BASE_TYPE_STRUCT: {
-                            bool fixed = vectortype.struct_def->fixed;
-                            writer.SetValue("index", Indirect(index, fixed));
-                            found = "obj.__assign({{index}}, bb)";
-                            break;
-                        }
-                        case BASE_TYPE_UNION:
-                            found = "{{bbgetter}}(obj, {{index}} - bb_pos){{ucast}}";
-                            break;
-                        default:
-                            found = "{{bbgetter}}({{index}}){{ucast}}";
-                        }
-                        OffsetWrapper(writer, offset_val,
-                                      [&]() { writer += found; } ,
-                                      [&]() { writer += not_found; });
-                    });
-                    break;
-                }
-                case BASE_TYPE_UNION:
-                    GenerateFun(writer, field_name, "obj: " + field_type,
-                                return_type + "?", [&](){
-                        writer += OffsetWrapperOneLine(offset_val,
-                                                       bbgetter + "(obj, o + bb_pos)",
-                                                       "null");
-                    });
-                    break;
-                default:
-                    FLATBUFFERS_ASSERT(0);
-                }
-            }
+      if ((value_base_type == BASE_TYPE_VECTOR &&
+           IsScalar(field.value.type.VectorType().base_type)) ||
+          value_base_type == BASE_TYPE_STRING) {
+        auto end_idx =
+            NumToString(value_base_type == BASE_TYPE_STRING
+                            ? 1
+                            : InlineSize(field.value.type.VectorType()));
+        // Generate a ByteBuffer accessor for strings & vectors of scalars.
+        // e.g.
+        // val inventoryByteBuffer: ByteBuffer
+        //     get =  __vector_as_bytebuffer(14, 1)
+
+        GenerateGetterOneLine(
+            writer, field_name + "AsByteBuffer", "ByteBuffer", [&]() {
+              writer.SetValue("end", end_idx);
+              writer += "__vector_as_bytebuffer({{offset}}, {{end}})";
+            });
 
-            if (value_base_type == BASE_TYPE_VECTOR) {
-                // Generate Lenght functions for vectors
-                GenerateGetter(writer, field_name + "Length", "Int", [&](){
-                    writer += OffsetWrapperOneLine(offset_val,
-                                                   "__vector_len(o)", "0");
-                });
-
-                // See if we should generate a by-key accessor.
-                if (field.value.type.element == BASE_TYPE_STRUCT &&
-                        !field.value.type.struct_def->fixed) {
-                    auto &sd = *field.value.type.struct_def;
-                    auto &fields = sd.fields.vec;
-                    for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
-                        auto &kfield = **kit;
-                        if (kfield.key) {
-                            auto qualified_name = WrapInNameSpace(sd);
-                            auto name = MakeCamel(Esc(field.name), false) + "ByKey";
-                            auto params = "key: " + GenTypeGet(kfield.value.type);
-                            auto rtype = qualified_name + "?";
-                            GenerateFun(writer, name, params, rtype, [&] () {
-                                OffsetWrapper(writer, offset_val,
-                                [&] () {
-                                    writer += qualified_name +
-                                    ".__lookup_by_key(null, __vector(o), key, bb)";
-                                },
-                                [&] () {
-                                    writer += "null";
-                                });
-                            });
-
-                            auto param2 = "obj: " + qualified_name +
-                                    ", key: " +
-                                    GenTypeGet(kfield.value.type);
-                            GenerateFun(writer, name, param2, rtype, [&](){
-                                OffsetWrapper(writer, offset_val,
-                                [&] () {
-                                    writer += qualified_name +
-                                    ".__lookup_by_key(obj, __vector(o), key, bb)";
-                                },
-                                [&]() { writer += "null"; });
-                            });
-
-                            break;
-                        }
-                    }
-                }
-            }
+        // Generate a ByteBuffer accessor for strings & vectors of scalars.
+        // e.g.
+        // fun inventoryInByteBuffer(_bb: Bytebuffer):
+        //     ByteBuffer = __vector_as_bytebuffer(_bb, 14, 1)
+        GenerateFunOneLine(
+            writer, field_name + "InByteBuffer", "_bb: ByteBuffer",
+            "ByteBuffer", [&]() {
+              writer.SetValue("end", end_idx);
+              writer += "__vector_in_bytebuffer(_bb, {{offset}}, {{end}})";
+            });
+      }
 
-            if ((value_base_type == BASE_TYPE_VECTOR &&
-                 IsScalar(field.value.type.VectorType().base_type)) ||
-                    value_base_type == BASE_TYPE_STRING) {
-
-                auto end_idx = NumToString(value_base_type == BASE_TYPE_STRING
-                                           ? 1
-                                           : InlineSize(field.value.type.VectorType()));
-                // Generate a ByteBuffer accessor for strings & vectors of scalars.
-                // e.g.
-                // val inventoryByteBuffer: ByteBuffer
-                //     get =  __vector_as_bytebuffer(14, 1)
-
-                GenerateGetterOneLine(writer, field_name + "AsByteBuffer",
-                                      "ByteBuffer", [&](){
-                    writer.SetValue("end", end_idx);
-                    writer += "__vector_as_bytebuffer({{offset}}, {{end}})";
-                });
-
-                // Generate a ByteBuffer accessor for strings & vectors of scalars.
-                // e.g.
-                // fun inventoryInByteBuffer(_bb: Bytebuffer):
-                //     ByteBuffer = __vector_as_bytebuffer(_bb, 14, 1)
-                GenerateFunOneLine(writer, field_name + "InByteBuffer",
-                                   "_bb: ByteBuffer", "ByteBuffer", [&](){
-                    writer.SetValue("end", end_idx);
-                    writer += "__vector_in_bytebuffer(_bb, {{offset}}, {{end}})";
-                });
-            }
+      // generate object accessors if is nested_flatbuffer
+      // fun testnestedflatbufferAsMonster() : Monster?
+      //{ return testnestedflatbufferAsMonster(new Monster()); }
 
-            // generate object accessors if is nested_flatbuffer
-            //fun testnestedflatbufferAsMonster() : Monster?
-            //{ return testnestedflatbufferAsMonster(new Monster()); }
-
-            if (field.nested_flatbuffer) {
-                auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer);
-                auto nested_method_name =
-                        field_name + "As" +
-                        field.nested_flatbuffer->name;
-
-                GenerateGetterOneLine(writer,
-                                      nested_method_name,
-                                      nested_type_name + "?", [&](){
-                    writer += nested_method_name + "(" + nested_type_name + "())";
-                });
-
-                GenerateFun(writer,
-                            nested_method_name,
-                            "obj: " + nested_type_name,
-                            nested_type_name + "?", [&](){
-                    OffsetWrapper(writer, offset_val,
-                                  [&]() { writer += "obj.__assign(__indirect(__vector(o)), bb)"; },
-                                  [&]() { writer += "null";});
-                });
-            }
+      if (field.nested_flatbuffer) {
+        auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer);
+        auto nested_method_name =
+            field_name + "As" + field.nested_flatbuffer->name;
 
-            // Generate mutators for scalar fields or vectors of scalars.
-            if (parser_.opts.mutable_buffer) {
-                auto value_type = field.value.type;
-                auto underlying_type = value_base_type == BASE_TYPE_VECTOR
-                        ? value_type.VectorType()
-                        : value_type;
-                auto name = "mutate" + MakeCamel(Esc(field.name), true);
-                auto size = NumToString(InlineSize(underlying_type));
-                auto params = Esc(field.name) + ": " + GenTypeGet(underlying_type);
-                // A vector mutator also needs the index of the vector element it should
-                // mutate.
-                if (value_base_type == BASE_TYPE_VECTOR)
-                    params.insert(0, "j: Int, ");
-
-                // Boolean parameters have to be explicitly converted to byte
-                // representation.
-                auto setter_parameter = underlying_type.base_type == BASE_TYPE_BOOL
-                        ? "(if(" + Esc(field.name) + ") 1 else 0).toByte()"
-                        : Esc(field.name);
-
-                auto setter_index = value_base_type == BASE_TYPE_VECTOR
-                        ? "__vector(o) + j * " + size
-                        : (struct_def.fixed
-                           ? "bb_pos + " + offset_val
-                           : "o + bb_pos");
-                if (IsScalar(value_base_type) || (value_base_type == BASE_TYPE_VECTOR &&
-                         IsScalar(value_type.VectorType().base_type))) {
-
-                    auto statements = [&] () {
-                        writer.SetValue("bbsetter", ByteBufferSetter(underlying_type));
-                        writer.SetValue("index", setter_index);
-                        writer.SetValue("params", setter_parameter);
-                        writer.SetValue("cast", CastToSigned(field));
-                        if (struct_def.fixed) {
-                            writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})";
-                        } else {
-                            OffsetWrapper(writer, offset_val, [&](){
-                                writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})";
-                                writer += "true";
-                            }, [&](){ writer += "false";});
-                        }
-                    };
-
-                    if (struct_def.fixed) {
-                        GenerateFunOneLine(writer, name, params, "ByteBuffer",
-                                    statements);
-                    } else {
-                        GenerateFun(writer, name, params, "Boolean",
-                                    statements);
-                    }
-                }
-            }
-        }
-        if (struct_def.has_key && !struct_def.fixed) {
-            // Key Comparison method
-            GenerateOverrideFun(
-                        writer,
-                        "keysCompare",
-                        "o1: Int, o2: Int, _bb: ByteBuffer", "Int", [&]() {
-                if (key_field->value.type.base_type == BASE_TYPE_STRING) {
-                    writer.SetValue("offset", NumToString(key_field->value.offset));
-                    writer += " return compareStrings(__offset({{offset}}, o1, "
-                            "_bb), __offset({{offset}}, o2, _bb), _bb)";
-
-                } else {
-                    auto getter1 = GenLookupByKey(key_field, "_bb", "o1");
-                    auto getter2 = GenLookupByKey(key_field, "_bb", "o2");
-                    writer += "val val_1 = " + getter1;
-                    writer += "val val_2 = " + getter2;
-                    writer += "return (val_1 - val_2).sign";
-                }
+        GenerateGetterOneLine(
+            writer, nested_method_name, nested_type_name + "?", [&]() {
+              writer += nested_method_name + "(" + nested_type_name + "())";
             });
-        }
-    }
 
-    static std::string CastToUsigned(const FieldDef &field) {
-        return CastToUsigned(field.value.type);
-    }
-
-    static std::string CastToUsigned(const Type type) {
-        switch (type.base_type) {
-        case BASE_TYPE_UINT:
-            return ".toUInt()";
-        case BASE_TYPE_UCHAR:
-        case BASE_TYPE_UTYPE:
-            return ".toUByte()";
-        case BASE_TYPE_USHORT:
-            return ".toUShort()";
-        case BASE_TYPE_ULONG:
-            return ".toULong()";
-        case BASE_TYPE_VECTOR:
-            return CastToUsigned(type.VectorType());
-        default:
-            return "";
-        }
-    }
+        GenerateFun(writer, nested_method_name, "obj: " + nested_type_name,
+                    nested_type_name + "?", [&]() {
+                      OffsetWrapper(
+                          writer, offset_val,
+                          [&]() {
+                            writer +=
+                                "obj.__assign(__indirect(__vector(o)), bb)";
+                          },
+                          [&]() { writer += "null"; });
+                    });
+      }
 
-    static std::string CastToSigned(const FieldDef &field) {
-        return CastToSigned(field.value.type);
-    }
+      // Generate mutators for scalar fields or vectors of scalars.
+      if (parser_.opts.mutable_buffer) {
+        auto value_type = field.value.type;
+        auto underlying_type = value_base_type == BASE_TYPE_VECTOR
+                                   ? value_type.VectorType()
+                                   : value_type;
+        auto name = "mutate" + MakeCamel(Esc(field.name), true);
+        auto size = NumToString(InlineSize(underlying_type));
+        auto params = Esc(field.name) + ": " + GenTypeGet(underlying_type);
+        // A vector mutator also needs the index of the vector element it should
+        // mutate.
+        if (value_base_type == BASE_TYPE_VECTOR) params.insert(0, "j: Int, ");
+
+        // Boolean parameters have to be explicitly converted to byte
+        // representation.
+        auto setter_parameter =
+            underlying_type.base_type == BASE_TYPE_BOOL
+                ? "(if(" + Esc(field.name) + ") 1 else 0).toByte()"
+                : Esc(field.name);
+
+        auto setter_index =
+            value_base_type == BASE_TYPE_VECTOR
+                ? "__vector(o) + j * " + size
+                : (struct_def.fixed ? "bb_pos + " + offset_val : "o + bb_pos");
+        if (IsScalar(value_base_type) ||
+            (value_base_type == BASE_TYPE_VECTOR &&
+             IsScalar(value_type.VectorType().base_type))) {
+          auto statements = [&]() {
+            writer.SetValue("bbsetter", ByteBufferSetter(underlying_type));
+            writer.SetValue("index", setter_index);
+            writer.SetValue("params", setter_parameter);
+            writer.SetValue("cast", CastToSigned(field));
+            if (struct_def.fixed) {
+              writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})";
+            } else {
+              OffsetWrapper(
+                  writer, offset_val,
+                  [&]() {
+                    writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})";
+                    writer += "true";
+                  },
+                  [&]() { writer += "false"; });
+            }
+          };
 
-    static std::string CastToSigned(const Type type) {
-        switch (type.base_type) {
-        case BASE_TYPE_UINT:
-            return ".toInt()";
-        case BASE_TYPE_UCHAR:
-        case BASE_TYPE_UTYPE:
-            return ".toByte()";
-        case BASE_TYPE_USHORT:
-            return ".toShort()";
-        case BASE_TYPE_ULONG:
-            return ".toLong()";
-        case BASE_TYPE_VECTOR:
-            return CastToSigned(type.VectorType());
-        default:
-            return "";
+          if (struct_def.fixed) {
+            GenerateFunOneLine(writer, name, params, "ByteBuffer", statements);
+          } else {
+            GenerateFun(writer, name, params, "Boolean", statements);
+          }
         }
+      }
     }
+    if (struct_def.has_key && !struct_def.fixed) {
+      // Key Comparison method
+      GenerateOverrideFun(
+          writer, "keysCompare", "o1: Int, o2: Int, _bb: ByteBuffer", "Int",
+          [&]() {
+            if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+              writer.SetValue("offset", NumToString(key_field->value.offset));
+              writer +=
+                  " return compareStrings(__offset({{offset}}, o1, "
+                  "_bb), __offset({{offset}}, o2, _bb), _bb)";
 
-    static std::string LiteralSuffix(const BaseType type) {
-        switch (type) {
-        case BASE_TYPE_UINT:
-        case BASE_TYPE_UCHAR:
-        case BASE_TYPE_UTYPE:
-        case BASE_TYPE_USHORT:
-            return "u";
-        case BASE_TYPE_ULONG:
-            return "UL";
-        case BASE_TYPE_LONG:
-            return "L";
-        default:
-            return "";
-        }
+            } else {
+              auto getter1 = GenLookupByKey(key_field, "_bb", "o1");
+              auto getter2 = GenLookupByKey(key_field, "_bb", "o2");
+              writer += "val val_1 = " + getter1;
+              writer += "val val_2 = " + getter2;
+              writer += "return (val_1 - val_2).sign";
+            }
+          });
     }
+  }
+
+  static std::string CastToUsigned(const FieldDef &field) {
+    return CastToUsigned(field.value.type);
+  }
 
-    void GenerateCompanionObject(CodeWriter &code,
-                                 const std::function<void()> &callback) const {
-        code += "companion object {";
-        code.IncrementIdentLevel();
-        callback();
-        code.DecrementIdentLevel();
-        code += "}";
+  static std::string CastToUsigned(const Type type) {
+    switch (type.base_type) {
+      case BASE_TYPE_UINT: return ".toUInt()";
+      case BASE_TYPE_UCHAR:
+      case BASE_TYPE_UTYPE: return ".toUByte()";
+      case BASE_TYPE_USHORT: return ".toUShort()";
+      case BASE_TYPE_ULONG: return ".toULong()";
+      case BASE_TYPE_VECTOR: return CastToUsigned(type.VectorType());
+      default: return "";
     }
+  }
 
-    // Generate a documentation comment, if available.
-    void GenerateComment(const std::vector<std::string> &dc, CodeWriter &writer,
-                    const CommentConfig *config) const {
-      if (dc.begin() == dc.end()) {
-        // Don't output empty comment blocks with 0 lines of comment content.
-        return;
-      }
+  static std::string CastToSigned(const FieldDef &field) {
+    return CastToSigned(field.value.type);
+  }
 
-      if (config != nullptr && config->first_line != nullptr) {
-        writer += std::string(config->first_line);
-      }
-      std::string line_prefix =
-          ((config != nullptr && config->content_line_prefix != nullptr)
-               ? config->content_line_prefix
-               : "///");
-      for (auto it = dc.begin(); it != dc.end(); ++it) {
-        writer += line_prefix + *it;
-      }
-      if (config != nullptr && config->last_line != nullptr) {
-        writer += std::string(config->last_line);
-      }
+  static std::string CastToSigned(const Type type) {
+    switch (type.base_type) {
+      case BASE_TYPE_UINT: return ".toInt()";
+      case BASE_TYPE_UCHAR:
+      case BASE_TYPE_UTYPE: return ".toByte()";
+      case BASE_TYPE_USHORT: return ".toShort()";
+      case BASE_TYPE_ULONG: return ".toLong()";
+      case BASE_TYPE_VECTOR: return CastToSigned(type.VectorType());
+      default: return "";
     }
+  }
 
-    static void GenerateGetRootAsAccessors(const std::string &struct_name,
-                                           CodeWriter &writer) {
-        // Generate a special accessor for the table that when used as the root
-        // ex: fun getRootAsMonster(_bb: ByteBuffer): Monster {...}
-        writer.SetValue("gr_name", struct_name);
-        writer.SetValue("gr_method", "getRootAs" + struct_name);
-
-        // create convenience method that doesn't require an existing object
-        writer += "fun {{gr_method}}(_bb: ByteBuffer): {{gr_name}} = \\";
-        writer += "{{gr_method}}(_bb, {{gr_name}}())";
-
-        // create method that allows object reuse
-        // ex: fun Monster getRootAsMonster(_bb: ByteBuffer, obj: Monster) {...}
-        writer += "fun {{gr_method}}"
-                 "(_bb: ByteBuffer, obj: {{gr_name}}): {{gr_name}} {";
-        writer.IncrementIdentLevel();
-        writer += "_bb.order(ByteOrder.LITTLE_ENDIAN)";
-        writer += "return (obj.__assign(_bb.getInt(_bb.position())"
-                 " + _bb.position(), _bb))";
-        writer.DecrementIdentLevel();
-        writer += "}";
+  static std::string LiteralSuffix(const BaseType type) {
+    switch (type) {
+      case BASE_TYPE_UINT:
+      case BASE_TYPE_UCHAR:
+      case BASE_TYPE_UTYPE:
+      case BASE_TYPE_USHORT: return "u";
+      case BASE_TYPE_ULONG: return "UL";
+      case BASE_TYPE_LONG: return "L";
+      default: return "";
     }
+  }
 
-    static void GenerateStaticConstructor(const StructDef &struct_def,
-                                          CodeWriter &code) {
-        // create a struct constructor function
-        auto params = StructConstructorParams(struct_def);
-        GenerateFun(code, "create" + Esc(struct_def.name), params, "Int", [&](){
-            GenStructBody(struct_def, code, "");
-            code += "return builder.offset()";
-        });
-    }
+  void GenerateCompanionObject(CodeWriter &code,
+                               const std::function<void()> &callback) const {
+    code += "companion object {";
+    code.IncrementIdentLevel();
+    callback();
+    code.DecrementIdentLevel();
+    code += "}";
+  }
 
-    static std::string StructConstructorParams(const StructDef &struct_def,
-                                               const std::string &prefix = "") {
-        //builder: FlatBufferBuilder
-        std::stringstream out;
-        auto field_vec = struct_def.fields.vec;
-        if (prefix.empty()) {
-            out << "builder: FlatBufferBuilder";
-        }
-        for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
-            auto &field = **it;
-            if (IsStruct(field.value.type)) {
-                // Generate arguments for a struct inside a struct. To ensure
-                // names don't clash, and to make it obvious these arguments are
-                // constructing a nested struct, prefix the name with the field
-                // name.
-                out << StructConstructorParams(*field.value.type.struct_def,
-                                              prefix + (Esc(field.name) + "_"));
-            } else {
-                out << ", " << prefix << MakeCamel(Esc(field.name), false)
-                    << ": "
-                    << GenTypeBasic(field.value.type.base_type);
-            }
-        }
-        return out.str();
+  // Generate a documentation comment, if available.
+  void GenerateComment(const std::vector<std::string> &dc, CodeWriter &writer,
+                       const CommentConfig *config) const {
+    if (dc.begin() == dc.end()) {
+      // Don't output empty comment blocks with 0 lines of comment content.
+      return;
     }
 
-    static void GeneratePropertyOneLine(CodeWriter &writer,
-                               const std::string &name,
-                               const std::string &type,
-                               const std::function<void()> &body) {
-        // Generates Kotlin getter for properties
-        // e.g.:
-        // val prop: Mytype = x
-        writer.SetValue("_name", name);
-        writer.SetValue("_type", type);
-        writer += "val {{_name}} : {{_type}} = \\";
-        body();
+    if (config != nullptr && config->first_line != nullptr) {
+      writer += std::string(config->first_line);
     }
-    static void GenerateGetterOneLine(CodeWriter &writer,
-                               const std::string &name,
-                               const std::string &type,
-                               const std::function<void()> &body) {
-        // Generates Kotlin getter for properties
-        // e.g.:
-        // val prop: Mytype get() = x
-        writer.SetValue("_name", name);
-        writer.SetValue("_type", type);
-        writer += "val {{_name}} : {{_type}} get() = \\";
-        body();
+    std::string line_prefix =
+        ((config != nullptr && config->content_line_prefix != nullptr)
+             ? config->content_line_prefix
+             : "///");
+    for (auto it = dc.begin(); it != dc.end(); ++it) {
+      writer += line_prefix + *it;
     }
-
-    static void GenerateGetter(CodeWriter &writer,
-                               const std::string &name,
-                               const std::string &type,
-                               const std::function<void()> &body) {
-        // Generates Kotlin getter for properties
-        // e.g.:
-        // val prop: Mytype
-        //     get() = {
-        //       return x
-        //     }
-        writer.SetValue("name", name);
-        writer.SetValue("type", type);
-        writer += "val {{name}} : {{type}}";
-        writer.IncrementIdentLevel();
-        writer += "get() {";
-        writer.IncrementIdentLevel();
-        body();
-        writer.DecrementIdentLevel();
-        writer += "}";
-        writer.DecrementIdentLevel();
+    if (config != nullptr && config->last_line != nullptr) {
+      writer += std::string(config->last_line);
     }
+  }
 
-    static void GenerateFun(CodeWriter &writer,
-                            const std::string &name,
-                            const std::string &params,
-                            const std::string &returnType,
-                            const std::function<void()> &body) {
-        // Generates Kotlin function
-        // e.g.:
-        // fun path(j: Int): Vec3 {
-        //     return path(Vec3(), j)
-        // }
-        auto noreturn = returnType.empty();
-        writer.SetValue("name", name);
-        writer.SetValue("params", params);
-        writer.SetValue("return_type", noreturn ? "" : ": " + returnType);
-        writer += "fun {{name}}({{params}}) {{return_type}} {";
-        writer.IncrementIdentLevel();
-        body();
-        writer.DecrementIdentLevel();
-        writer += "}";
-    }
+  static void GenerateGetRootAsAccessors(const std::string &struct_name,
+                                         CodeWriter &writer) {
+    // Generate a special accessor for the table that when used as the root
+    // ex: fun getRootAsMonster(_bb: ByteBuffer): Monster {...}
+    writer.SetValue("gr_name", struct_name);
+    writer.SetValue("gr_method", "getRootAs" + struct_name);
+
+    // create convenience method that doesn't require an existing object
+    writer += "fun {{gr_method}}(_bb: ByteBuffer): {{gr_name}} = \\";
+    writer += "{{gr_method}}(_bb, {{gr_name}}())";
+
+    // create method that allows object reuse
+    // ex: fun Monster getRootAsMonster(_bb: ByteBuffer, obj: Monster) {...}
+    writer +=
+        "fun {{gr_method}}"
+        "(_bb: ByteBuffer, obj: {{gr_name}}): {{gr_name}} {";
+    writer.IncrementIdentLevel();
+    writer += "_bb.order(ByteOrder.LITTLE_ENDIAN)";
+    writer +=
+        "return (obj.__assign(_bb.getInt(_bb.position())"
+        " + _bb.position(), _bb))";
+    writer.DecrementIdentLevel();
+    writer += "}";
+  }
 
-    static void GenerateFunOneLine(CodeWriter &writer,
-                                   const std::string &name,
-                                   const std::string &params,
-                                   const std::string &returnType,
-                                   const std::function<void()> &body) {
-        // Generates Kotlin function
-        // e.g.:
-        // fun path(j: Int): Vec3 = return path(Vec3(), j)
-        writer.SetValue("name", name);
-        writer.SetValue("params", params);
-        writer.SetValue("return_type_p", returnType.empty() ? "" :
-                                                          " : " + returnType);
-        writer += "fun {{name}}({{params}}){{return_type_p}} = \\";
-        body();
-    }
+  static void GenerateStaticConstructor(const StructDef &struct_def,
+                                        CodeWriter &code) {
+    // create a struct constructor function
+    auto params = StructConstructorParams(struct_def);
+    GenerateFun(code, "create" + Esc(struct_def.name), params, "Int", [&]() {
+      GenStructBody(struct_def, code, "");
+      code += "return builder.offset()";
+    });
+  }
 
-    static void GenerateOverrideFun(CodeWriter &writer,
-                                   const std::string &name,
-                                   const std::string &params,
-                                   const std::string &returnType,
-                                   const std::function<void()> &body) {
-        // Generates Kotlin function
-        // e.g.:
-        // override fun path(j: Int): Vec3 = return path(Vec3(), j)
-        writer += "override \\";
-        GenerateFun(writer, name, params, returnType, body);
+  static std::string StructConstructorParams(const StructDef &struct_def,
+                                             const std::string &prefix = "") {
+    // builder: FlatBufferBuilder
+    std::stringstream out;
+    auto field_vec = struct_def.fields.vec;
+    if (prefix.empty()) { out << "builder: FlatBufferBuilder"; }
+    for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
+      auto &field = **it;
+      if (IsStruct(field.value.type)) {
+        // Generate arguments for a struct inside a struct. To ensure
+        // names don't clash, and to make it obvious these arguments are
+        // constructing a nested struct, prefix the name with the field
+        // name.
+        out << StructConstructorParams(*field.value.type.struct_def,
+                                       prefix + (Esc(field.name) + "_"));
+      } else {
+        out << ", " << prefix << MakeCamel(Esc(field.name), false) << ": "
+            << GenTypeBasic(field.value.type.base_type);
+      }
     }
+    return out.str();
+  }
 
-    static void GenerateOverrideFunOneLine(CodeWriter &writer,
-                                   const std::string &name,
-                                   const std::string &params,
-                                   const std::string &returnType,
-                                   const std::string &statement) {
-        // Generates Kotlin function
-        // e.g.:
-        // override fun path(j: Int): Vec3 = return path(Vec3(), j)
-        writer.SetValue("name", name);
-        writer.SetValue("params", params);
-        writer.SetValue("return_type", returnType.empty() ? "" :
-                                                          " : " + returnType);
-        writer += "override fun {{name}}({{params}}){{return_type}} = \\";
-        writer += statement;
-    }
+  static void GeneratePropertyOneLine(CodeWriter &writer,
+                                      const std::string &name,
+                                      const std::string &type,
+                                      const std::function<void()> &body) {
+    // Generates Kotlin getter for properties
+    // e.g.:
+    // val prop: Mytype = x
+    writer.SetValue("_name", name);
+    writer.SetValue("_type", type);
+    writer += "val {{_name}} : {{_type}} = \\";
+    body();
+  }
+  static void GenerateGetterOneLine(CodeWriter &writer, const std::string &name,
+                                    const std::string &type,
+                                    const std::function<void()> &body) {
+    // Generates Kotlin getter for properties
+    // e.g.:
+    // val prop: Mytype get() = x
+    writer.SetValue("_name", name);
+    writer.SetValue("_type", type);
+    writer += "val {{_name}} : {{_type}} get() = \\";
+    body();
+  }
 
-    static std::string OffsetWrapperOneLine(const std::string &offset,
-                                            const std::string &found,
-                                            const std::string &not_found) {
-        return "val o = __offset(" + offset + "); return if (o != 0) " + found +
-                " else " + not_found;
-    }
+  static void GenerateGetter(CodeWriter &writer, const std::string &name,
+                             const std::string &type,
+                             const std::function<void()> &body) {
+    // Generates Kotlin getter for properties
+    // e.g.:
+    // val prop: Mytype
+    //     get() = {
+    //       return x
+    //     }
+    writer.SetValue("name", name);
+    writer.SetValue("type", type);
+    writer += "val {{name}} : {{type}}";
+    writer.IncrementIdentLevel();
+    writer += "get() {";
+    writer.IncrementIdentLevel();
+    body();
+    writer.DecrementIdentLevel();
+    writer += "}";
+    writer.DecrementIdentLevel();
+  }
 
-    static void OffsetWrapper(CodeWriter &code,
-                       const std::string &offset,
-                       const std::function<void()> &found,
-                       const std::function<void()> &not_found) {
-        code += "val o = __offset(" + offset + ")";
-        code +="return if (o != 0) {";
-        code.IncrementIdentLevel();
-        found();
-        code.DecrementIdentLevel();
-        code += "} else {";
-        code.IncrementIdentLevel();
-        not_found();
-        code.DecrementIdentLevel();
-        code += "}";
-    }
+  static void GenerateFun(CodeWriter &writer, const std::string &name,
+                          const std::string &params,
+                          const std::string &returnType,
+                          const std::function<void()> &body) {
+    // Generates Kotlin function
+    // e.g.:
+    // fun path(j: Int): Vec3 {
+    //     return path(Vec3(), j)
+    // }
+    auto noreturn = returnType.empty();
+    writer.SetValue("name", name);
+    writer.SetValue("params", params);
+    writer.SetValue("return_type", noreturn ? "" : ": " + returnType);
+    writer += "fun {{name}}({{params}}) {{return_type}} {";
+    writer.IncrementIdentLevel();
+    body();
+    writer.DecrementIdentLevel();
+    writer += "}";
+  }
 
-    static std::string Indirect(const std::string &index, bool fixed) {
-        // We apply __indirect() and struct is not fixed.
-        if (!fixed)
-            return "__indirect(" + index + ")";
-        return index;
-    }
+  static void GenerateFunOneLine(CodeWriter &writer, const std::string &name,
+                                 const std::string &params,
+                                 const std::string &returnType,
+                                 const std::function<void()> &body) {
+    // Generates Kotlin function
+    // e.g.:
+    // fun path(j: Int): Vec3 = return path(Vec3(), j)
+    writer.SetValue("name", name);
+    writer.SetValue("params", params);
+    writer.SetValue("return_type_p",
+                    returnType.empty() ? "" : " : " + returnType);
+    writer += "fun {{name}}({{params}}){{return_type_p}} = \\";
+    body();
+  }
 
-    static std::string NotFoundReturn(BaseType el) {
-        switch (el) {
-        case BASE_TYPE_FLOAT:
-           return "0.0f";
-         case BASE_TYPE_DOUBLE:
-            return "0.0";
-        case BASE_TYPE_BOOL:
-            return "false";
-        case BASE_TYPE_LONG:
-        case BASE_TYPE_INT:
-        case BASE_TYPE_CHAR:
-        case BASE_TYPE_SHORT:
-            return "0";
-        case BASE_TYPE_UINT:
-        case BASE_TYPE_UCHAR:
-        case BASE_TYPE_USHORT:
-        case BASE_TYPE_UTYPE:
-            return "0u";
-        case BASE_TYPE_ULONG:
-            return "0uL";
-        default:
-            return "null";
-        }
+  static void GenerateOverrideFun(CodeWriter &writer, const std::string &name,
+                                  const std::string &params,
+                                  const std::string &returnType,
+                                  const std::function<void()> &body) {
+    // Generates Kotlin function
+    // e.g.:
+    // override fun path(j: Int): Vec3 = return path(Vec3(), j)
+    writer += "override \\";
+    GenerateFun(writer, name, params, returnType, body);
+  }
+
+  static void GenerateOverrideFunOneLine(CodeWriter &writer,
+                                         const std::string &name,
+                                         const std::string &params,
+                                         const std::string &returnType,
+                                         const std::string &statement) {
+    // Generates Kotlin function
+    // e.g.:
+    // override fun path(j: Int): Vec3 = return path(Vec3(), j)
+    writer.SetValue("name", name);
+    writer.SetValue("params", params);
+    writer.SetValue("return_type",
+                    returnType.empty() ? "" : " : " + returnType);
+    writer += "override fun {{name}}({{params}}){{return_type}} = \\";
+    writer += statement;
+  }
+
+  static std::string OffsetWrapperOneLine(const std::string &offset,
+                                          const std::string &found,
+                                          const std::string &not_found) {
+    return "val o = __offset(" + offset + "); return if (o != 0) " + found +
+           " else " + not_found;
+  }
+
+  static void OffsetWrapper(CodeWriter &code, const std::string &offset,
+                            const std::function<void()> &found,
+                            const std::function<void()> &not_found) {
+    code += "val o = __offset(" + offset + ")";
+    code += "return if (o != 0) {";
+    code.IncrementIdentLevel();
+    found();
+    code.DecrementIdentLevel();
+    code += "} else {";
+    code.IncrementIdentLevel();
+    not_found();
+    code.DecrementIdentLevel();
+    code += "}";
+  }
+
+  static std::string Indirect(const std::string &index, bool fixed) {
+    // We apply __indirect() and struct is not fixed.
+    if (!fixed) return "__indirect(" + index + ")";
+    return index;
+  }
+
+  static std::string NotFoundReturn(BaseType el) {
+    switch (el) {
+      case BASE_TYPE_FLOAT: return "0.0f";
+      case BASE_TYPE_DOUBLE: return "0.0";
+      case BASE_TYPE_BOOL: return "false";
+      case BASE_TYPE_LONG:
+      case BASE_TYPE_INT:
+      case BASE_TYPE_CHAR:
+      case BASE_TYPE_SHORT: return "0";
+      case BASE_TYPE_UINT:
+      case BASE_TYPE_UCHAR:
+      case BASE_TYPE_USHORT:
+      case BASE_TYPE_UTYPE: return "0u";
+      case BASE_TYPE_ULONG: return "0uL";
+      default: return "null";
     }
+  }
 
-    // This tracks the current namespace used to determine if a type need to be
-    // prefixed by its namespace
-    const Namespace *cur_name_space_;
+  // This tracks the current namespace used to determine if a type need to be
+  // prefixed by its namespace
+  const Namespace *cur_name_space_;
 };
 }  // namespace kotlin
 
 bool GenerateKotlin(const Parser &parser, const std::string &path,
                     const std::string &file_name) {
-    kotlin::KotlinGenerator generator(parser, path, file_name);
-    return generator.generate();
+  kotlin::KotlinGenerator generator(parser, path, file_name);
+  return generator.generate();
 }
 }  // namespace flatbuffers