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

// independent from idl_parser, since this code is not needed for most clients

#include <functional>
#include <unordered_set>

#include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
#include "idl_namer.h"

namespace flatbuffers {

namespace kotlin {

namespace {

typedef std::map<std::string, std::pair<std::string, std::string> > FbbParamMap;
static TypedFloatConstantGenerator KotlinFloatGen("Double.", "Float.", "NaN",
                                                  "POSITIVE_INFINITY",
                                                  "NEGATIVE_INFINITY");

static const CommentConfig comment_config = { "/**", " *", " */" };
static const std::string ident_pad = "    ";
static std::set<std::string> KotlinKeywords() {
  return { "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" };
}

static Namer::Config KotlinDefaultConfig() {
  return { /*types=*/Case::kKeep,
           /*constants=*/Case::kKeep,
           /*methods=*/Case::kLowerCamel,
           /*functions=*/Case::kKeep,
           /*fields=*/Case::kLowerCamel,
           /*variables=*/Case::kLowerCamel,
           /*variants=*/Case::kLowerCamel,
           /*enum_variant_seperator=*/"",  // I.e. Concatenate.
           /*escape_keywords=*/Namer::Config::Escape::BeforeConvertingCase,
           /*namespaces=*/Case::kKeep,
           /*namespace_seperator=*/"__",
           /*object_prefix=*/"",
           /*object_suffix=*/"T",
           /*keyword_prefix=*/"",
           /*keyword_suffix=*/"_",
           /*filenames=*/Case::kKeep,
           /*directories=*/Case::kKeep,
           /*output_path=*/"",
           /*filename_suffix=*/"",
           /*filename_extension=*/".kt" };
}
} // namespace

class KotlinGenerator : public BaseGenerator {
 public:
  KotlinGenerator(const Parser &parser, const std::string &path,
                  const std::string &file_name)
      : BaseGenerator(parser, path, file_name, "", ".", "kt"),
        namer_(WithFlagOptions(KotlinDefaultConfig(), parser.opts, path),
               KotlinKeywords()) {}

  KotlinGenerator &operator=(const KotlinGenerator &);
  bool generate() FLATBUFFERS_OVERRIDE {
    std::string one_file_code;

    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
         ++it) {
      CodeWriter enumWriter(ident_pad);
      auto &enum_def = **it;
      GenEnum(enum_def, enumWriter);
      if (parser_.opts.one_file) {
        one_file_code += enumWriter.ToString();
      } else {
        if (!SaveType(enum_def.name, *enum_def.defined_namespace,
                      enumWriter.ToString(), false))
          return false;
      }
    }

    for (auto it = parser_.structs_.vec.begin();
         it != parser_.structs_.vec.end(); ++it) {
      CodeWriter structWriter(ident_pad);
      auto &struct_def = **it;
      GenStruct(struct_def, structWriter, parser_.opts);
      if (parser_.opts.one_file) {
        one_file_code += structWriter.ToString();
      } else {
        if (!SaveType(struct_def.name, *struct_def.defined_namespace,
                      structWriter.ToString(), true))
          return false;
      }
    }

    if (parser_.opts.one_file) {
      return SaveType(file_name_, *parser_.current_namespace_, one_file_code,
                      true);
    }
    return true;
  }

  // Save out the generated code for a single class while adding
  // declaration boilerplate.
  bool SaveType(const std::string &defname, const Namespace &ns,
                const std::string &classcode, bool needs_includes) const {
    if (!classcode.length()) return true;

    std::string code =
        "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";

    std::string namespace_name = FullNamespace(".", ns);
    if (!namespace_name.empty()) {
      code += "package " + namespace_name;
      code += "\n\n";
    }
    if (needs_includes) {
      code += "import java.nio.*\n";
      code += "import kotlin.math.sign\n";
      code += "import com.google.flatbuffers.*\n\n";
    }
    code += classcode;
    const std::string dirs = namer_.Directories(ns);
    EnsureDirExists(dirs);
    const std::string filename =
        dirs + namer_.File(defname, /*skips=*/SkipFile::Suffix);
    return SaveFile(filename.c_str(), code, false);
  }

  static bool IsEnum(const Type &type) {
    return type.enum_def != nullptr && IsInteger(type.base_type);
  }

  static std::string GenTypeBasic(const BaseType &type) {
    // clang-format off
    static const char * const kotlin_typename[] = {
      #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
              CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE, ...) \
        #KTYPE,
        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
      #undef FLATBUFFERS_TD
    };
    // 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";
    }
  }

  // with the addition of optional scalar types,
  // we are adding the nullable '?' operator to return type of a field.
  std::string GetterReturnType(const FieldDef &field) const {
    auto base_type = field.value.type.base_type;

    auto r_type = GenTypeGet(field.value.type);
    if (field.IsScalarOptional() ||
        // string, structs and unions
        (base_type == BASE_TYPE_STRING || base_type == BASE_TYPE_STRUCT ||
         base_type == BASE_TYPE_UNION) ||
        // vector of anything not scalar
        (base_type == BASE_TYPE_VECTOR &&
         !IsScalar(field.value.type.VectorType().base_type))) {
      r_type += "?";
    }
    return r_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;
  }

  // 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 {
    if (field.IsScalarOptional()) {
      // although default value is null, java API forces us to present a real
      // default value for scalars, while adding a field to the buffer. This is
      // not a problem because the default can be representing just by not
      // calling builder.addMyField()
      switch (field.value.type.base_type) {
        case BASE_TYPE_DOUBLE:
        case BASE_TYPE_FLOAT: return "0.0";
        case BASE_TYPE_BOOL: return "false";
        default: return "0";
      }
    }
    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 "";
  }

  std::string GenDefaultValue(const FieldDef &field,
                              bool force_signed = false) const {
    auto &value = field.value;
    auto base_type = field.value.type.base_type;

    if (field.IsScalarOptional()) { return "null"; }
    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";
    }

    std::string 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 += "class " + namer_.Type(enum_def) + " 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", namer_.LegacyKotlinVariant(ev));
        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 += "]";
            },
            parser_.opts.gen_jvmstatic);
      }
    });
    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 + "." +
               namer_.Method("get", GenTypeBasic(type.base_type));
    }
  }

  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." + namer_.Method("put", 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 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.
  void GenStructArgs(const StructDef &struct_def, CodeWriter &writer,
                     const char *nameprefix) const {
    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 += namer_.Field(field) + ": \\";
        writer += GenTypeBasic(field.value.type.base_type) + "\\";
      }
    }
  }

  // Recusively generate struct construction statements of the form:
  // builder.putType(name);
  // and insert manual padding.
  void GenStructBody(const StructDef &struct_def, CodeWriter &writer,
                     const char *nameprefix) const {
    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 + namer_.Variable(field));
        writer.SetValue("cast", CastToSigned(field.value.type));
        writer += "builder.put{{type}}({{argname}}{{cast}})";
      }
    }
  }

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

  void GenStruct(StructDef &struct_def, CodeWriter &writer,
                 IDLOptions options) const {
    if (struct_def.generated) return;

    GenerateComment(struct_def.doc_comment, writer, &comment_config);
    auto fixed = struct_def.fixed;

    writer.SetValue("struct_name", namer_.Type(struct_def));
    writer.SetValue("superclass", fixed ? "Struct" : "Table");

    writer += "@Suppress(\"unused\")";
    writer += "class {{struct_name}} : {{superclass}}() {\n";

    writer.IncrementIdentLevel();

    {
      // 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 assign method
      GenerateFun(writer, "__assign", "_i: Int, _bb: ByteBuffer",
                  namer_.Type(struct_def), [&]() {
                    writer += "__init(_i, _bb)";
                    writer += "return this";
                  });

      // Generate all getters
      GenerateStructGetters(struct_def, writer);

      // Generate Static Fields
      GenerateCompanionObject(writer, [&]() {
        if (!struct_def.fixed) {
          FieldDef *key_field = nullptr;

          // Generate version check method.
          // Force compile time error if not using the same version
          // runtime.
          GenerateFunOneLine(
              writer, "validateVersion", "", "",
              [&]() { writer += "Constants.FLATBUFFERS_22_10_25()"; },
              options.gen_jvmstatic);

          GenerateGetRootAsAccessors(namer_.Type(struct_def), writer, options);
          GenerateBufferHasIdentifier(struct_def, writer, options);
          GenerateTableCreator(struct_def, writer, options);

          GenerateStartStructMethod(struct_def, writer, options);

          // 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, options);

            if (IsVector(field.value.type)) {
              auto vector_type = field.value.type.VectorType();
              if (!IsStruct(vector_type)) {
                GenerateCreateVectorField(field, writer, options);
              }
              GenerateStartVectorField(field, writer, options);
            }
          }

          GenerateEndStructMethod(struct_def, writer, options);
          auto file_identifier = parser_.file_identifier_;
          if (parser_.root_struct_def_ == &struct_def) {
            GenerateFinishStructBuffer(struct_def, file_identifier, writer,
                                       options);
            GenerateFinishSizePrefixed(struct_def, file_identifier, writer,
                                       options);
          }

          if (struct_def.has_key) {
            GenerateLookupByKey(key_field, struct_def, writer, options);
          }
        } else {
          GenerateStaticConstructor(struct_def, writer, options);
        }
      });
    }

    // class closing
    writer.DecrementIdentLevel();
    writer += "}";
  }

  // TODO: move key_field to reference instead of pointer
  void GenerateLookupByKey(FieldDef *key_field, StructDef &struct_def,
                           CodeWriter &writer, const IDLOptions options) const {
    std::stringstream params;
    params << "obj: " << namer_.Type(struct_def) << "?"
           << ", ";
    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", namer_.Type(struct_def));
      if (base_type == BASE_TYPE_STRING) {
        writer +=
            "val byteKey = key."
            "toByteArray(java.nio.charset.StandardCharsets.UTF_8)";
      }
      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 (IsString(key_field->value.type)) {
        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(),
                namer_.Type(struct_def) + "?", statements,
                options.gen_jvmstatic);
  }

  void GenerateFinishSizePrefixed(StructDef &struct_def,
                                  const std::string &identifier,
                                  CodeWriter &writer,
                                  const IDLOptions options) const {
    auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
    auto params = "builder: FlatBufferBuilder, offset: Int";
    auto method_name =
        namer_.LegacyJavaMethod2("finishSizePrefixed", struct_def, "Buffer");
    GenerateFunOneLine(
        writer, method_name, params, "",
        [&]() { writer += "builder.finishSizePrefixed(offset" + id + ")"; },
        options.gen_jvmstatic);
  }
  void GenerateFinishStructBuffer(StructDef &struct_def,
                                  const std::string &identifier,
                                  CodeWriter &writer,
                                  const IDLOptions options) const {
    auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
    auto params = "builder: FlatBufferBuilder, offset: Int";
    auto method_name =
        namer_.LegacyKotlinMethod("finish", struct_def, "Buffer");
    GenerateFunOneLine(
        writer, method_name, params, "",
        [&]() { writer += "builder.finish(offset" + id + ")"; },
        options.gen_jvmstatic);
  }

  void GenerateEndStructMethod(StructDef &struct_def, CodeWriter &writer,
                               const IDLOptions options) const {
    // Generate end{{TableName}}(builder: FlatBufferBuilder) method
    auto name = namer_.LegacyJavaMethod2("end", struct_def, "");
    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.IsRequired()) { continue; }
            writer.SetValue("offset", NumToString(field.value.offset));
            writer += "builder.required(o, {{offset}})";
          }
          writer.DecrementIdentLevel();
          writer += "return o";
        },
        options.gen_jvmstatic);
  }

  // Generate a method to create a vector from a Kotlin array.
  void GenerateCreateVectorField(FieldDef &field, CodeWriter &writer,
                                 const IDLOptions options) const {
    auto vector_type = field.value.type.VectorType();
    auto method_name = namer_.Method("create", field, "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()";
        },
        options.gen_jvmstatic);
  }

  void GenerateStartVectorField(FieldDef &field, CodeWriter &writer,
                                const IDLOptions options) 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, namer_.Method("start", field, "Vector"), params, "",
        [&]() {
          writer += "builder.startVector({{size}}, numElems, {{align}})";
        },
        options.gen_jvmstatic);
  }

  void GenerateAddField(std::string field_pos, FieldDef &field,
                        CodeWriter &writer, const IDLOptions options) const {
    auto field_type = GenTypeBasic(field.value.type.base_type);
    auto secondArg = namer_.Variable(field.name) + ": " + field_type;

    auto content = [&]() {
      auto method = GenMethod(field.value.type);
      writer.SetValue("field_name", namer_.Field(field));
      writer.SetValue("method_name", method);
      writer.SetValue("pos", field_pos);
      writer.SetValue("default", GenFBBDefaultValue(field));
      writer.SetValue("cast", GenFBBValueCast(field));
      if (field.key) {
        // field has key attribute, so always need to exist
        // even if its value is equal to default.
        // Generated code will bypass default checking
        // resulting in { builder.addShort(name); slot(id); }
        writer += "builder.add{{method_name}}({{field_name}}{{cast}})";
        writer += "builder.slot({{pos}})";
      } else {
        writer += "builder.add{{method_name}}({{pos}}, \\";
        writer += "{{field_name}}{{cast}}, {{default}})";
      }
    };
    auto signature = namer_.LegacyKotlinMethod("add", field, "");
    auto params = "builder: FlatBufferBuilder, " + secondArg;
    if (field.key) {
      GenerateFun(writer, signature, params, "", content,
                  options.gen_jvmstatic);
    } else {
      GenerateFunOneLine(writer, signature, params, "", content,
                         options.gen_jvmstatic);
    }
  }

  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);
    }
  }

  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 "";
  }

  // fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11)
  void GenerateStartStructMethod(StructDef &struct_def, CodeWriter &code,
                                 const IDLOptions options) const {
    GenerateFunOneLine(
        code, namer_.LegacyJavaMethod2("start", struct_def, ""),
        "builder: FlatBufferBuilder", "",
        [&]() {
          code += "builder.startTable(" +
                  NumToString(struct_def.fields.vec.size()) + ")";
        },
        options.gen_jvmstatic);
  }

  void GenerateTableCreator(StructDef &struct_def, CodeWriter &writer,
                            const IDLOptions options) 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 = namer_.LegacyJavaMethod2("create", struct_def, "");
      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 << ", " << namer_.Variable(field);
        if (!IsScalar(field.value.type.base_type)) {
          params << "Offset: ";
        } else {
          params << ": ";
        }
        auto optional = field.IsScalarOptional() ? "?" : "";
        params << GenTypeBasic(field.value.type.base_type) << optional;
      }

      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("field_name", namer_.Field(field));

                  // we wrap on null check for scalar optionals
                  writer += field.IsScalarOptional()
                                ? "{{field_name}}?.run { \\"
                                : "\\";

                  writer += namer_.LegacyKotlinMethod("add", field, "") +
                            "(builder, {{field_name}}\\";
                  if (!IsScalar(field.value.type.base_type)) {
                    writer += "Offset\\";
                  }
                  // we wrap on null check for scalar optionals
                  writer += field.IsScalarOptional() ? ") }" : ")";
                }
              }
            }
            writer += "return end{{struct_name}}(builder)";
          },
          options.gen_jvmstatic);
    }
  }
  void GenerateBufferHasIdentifier(StructDef &struct_def, CodeWriter &writer,
                                   IDLOptions options) 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 = namer_.Function(struct_def);
    GenerateFunOneLine(
        writer, name + "BufferHasIdentifier", "_bb: ByteBuffer", "Boolean",
        [&]() {
          writer += "__has_identifier(_bb, \"" + file_identifier + "\")";
        },
        options.gen_jvmstatic);
  }

  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 = namer_.Field(field);
      auto field_type = GenTypeGet(field.value.type);
      auto field_default_value = GenDefaultValue(field);
      auto return_type = GetterReturnType(field);
      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);

      // 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, return_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", return_type, [&]() {
          writer += "{{field_name}}({{field_type}}(), j)";
        });
      }

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

            if (vectortype.base_type == BASE_TYPE_STRUCT ||
                vectortype.base_type == BASE_TYPE_UNION) {
              params = "obj: " + field_type + ", j: Int";
            }

            GenerateFun(writer, field_name, params, return_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}}){{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) {
        // 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 = namer_.Method(field, "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 ((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()); }

      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"; });
                    });
      }

      // 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 = namer_.LegacyKotlinMethod("mutate", field, "");
        auto size = NumToString(InlineSize(underlying_type));
        auto params = namer_.Field(field) + ": " + 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(" + namer_.Field(field) + ") 1 else 0).toByte()"
                : namer_.Field(field);

        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 (IsString(key_field->value.type)) {
              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";
            }
          });
    }
  }

  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 "";
    }
  }

  static std::string CastToSigned(const FieldDef &field) {
    return CastToSigned(field.value.type);
  }

  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 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 "";
    }
  }

  void GenerateCompanionObject(CodeWriter &code,
                               const std::function<void()> &callback) const {
    code += "companion object {";
    code.IncrementIdentLevel();
    callback();
    code.DecrementIdentLevel();
    code += "}";
  }

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

    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);
    }
  }

  void GenerateGetRootAsAccessors(const std::string &struct_name,
                                  CodeWriter &writer,
                                  IDLOptions options) const {
    // 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
    GenerateJvmStaticAnnotation(writer, options.gen_jvmstatic);
    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) {...}
    GenerateJvmStaticAnnotation(writer, options.gen_jvmstatic);
    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 += "}";
  }

  void GenerateStaticConstructor(const StructDef &struct_def, CodeWriter &code,
                                 const IDLOptions options) const {
    // create a struct constructor function
    auto params = StructConstructorParams(struct_def);
    GenerateFun(
        code, namer_.LegacyJavaMethod2("create", struct_def, ""), params, "Int",
        [&]() {
          GenStructBody(struct_def, code, "");
          code += "return builder.offset()";
        },
        options.gen_jvmstatic);
  }

  std::string StructConstructorParams(const StructDef &struct_def,
                                      const std::string &prefix = "") const {
    // 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 + (namer_.Variable(field) + "_"));
      } else {
        out << ", " << prefix << namer_.Variable(field) << ": "
            << GenTypeBasic(field.value.type.base_type);
      }
    }
    return out.str();
  }

  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 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 GenerateFun(CodeWriter &writer, const std::string &name,
                          const std::string &params,
                          const std::string &returnType,
                          const std::function<void()> &body,
                          bool gen_jvmstatic = false) {
    // 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);
    GenerateJvmStaticAnnotation(writer, gen_jvmstatic);
    writer += "fun {{name}}({{params}}) {{return_type}} {";
    writer.IncrementIdentLevel();
    body();
    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,
                                 bool gen_jvmstatic = false) {
    // 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);
    GenerateJvmStaticAnnotation(writer, gen_jvmstatic);
    writer += "fun {{name}}({{params}}){{return_type_p}} = \\";
    body();
  }

  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";
    }
  }

  // Prepend @JvmStatic to methods in companion object.
  static void GenerateJvmStaticAnnotation(CodeWriter &code,
                                          bool gen_jvmstatic) {
    if (gen_jvmstatic) { code += "@JvmStatic"; }
  }

  const IdlNamer namer_;
};
}  // 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();
}
}  // namespace flatbuffers
