/*
 * 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"

namespace flatbuffers {

namespace kotlin {

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

// 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 ConvertCase(name + "_", Case::kLowerCamel);
    }
  }

  return ConvertCase(name, Case::kLowerCamel);
}

class KotlinGenerator : public BaseGenerator {
 public:
  KotlinGenerator(const Parser &parser, const std::string &path,
                  const std::string &file_name)
      : BaseGenerator(parser, path, file_name, "", ".", "kt"),
        cur_name_space_(nullptr) {}

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

    cur_name_space_ = parser_.current_namespace_;
    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
         ++it) {
      CodeWriter enumWriter(ident_pad);
      auto &enum_def = **it;
      if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace;
      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;
      if (!parser_.opts.one_file)
        cur_name_space_ = struct_def.defined_namespace;
      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;
    auto filename = NamespaceDir(ns) + defname + ".kt";
    return SaveFile(filename.c_str(), code, false);
  }

  const Namespace *CurrentNameSpace() const FLATBUFFERS_OVERRIDE {
    return cur_name_space_;
  }

  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 " + 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 += "]";
            },
            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 + ".get" +
               ConvertCase(GenTypeBasic(type.base_type), Case::kUpperCamel);
    }
  }

  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" +
                 ConvertCase(GenTypeBasic(type.base_type), Case::kUpperCamel);
      }
    }
    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.
  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 += ConvertCase(field.name, Case::kUpperCamel) + ": \\";
        writer += GenTypeBasic(field.value.type.base_type) + "\\";
      }
    }
  }

  // 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 + ConvertCase(Esc(field.name),
                                                            Case::kLowerCamel));
        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", Esc(struct_def.name));
    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",
                  Esc(struct_def.name), [&]() {
                    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 verson check method.
          // Force compile time error if not using the same version
          // runtime.
          GenerateFunOneLine(
              writer, "validateVersion", "", "",
              [&]() { writer += "Constants.FLATBUFFERS_2_0_0()"; },
              options.gen_jvmstatic);

          GenerateGetRootAsAccessors(Esc(struct_def.name), 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: " << 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(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(),
                Esc(struct_def.name) + "?", 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 = "finishSizePrefixed" + Esc(struct_def.name) + "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 = "finish" + Esc(struct_def.name) + "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 = "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.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 =
        "create" + ConvertCase(Esc(field.name), Case::kUpperCamel) + "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,
        "start" + ConvertCase(Esc(field.name) + "Vector", Case::kUpperCamel),
        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 =
        ConvertCase(Esc(field.name), Case::kLowerCamel) + ": " + field_type;

    GenerateFunOneLine(
        writer, "add" + ConvertCase(Esc(field.name), Case::kUpperCamel),
        "builder: FlatBufferBuilder, " + secondArg, "",
        [&]() {
          auto method = GenMethod(field.value.type);
          writer.SetValue("field_name",
                          ConvertCase(Esc(field.name), Case::kLowerCamel));
          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}})";
        },
        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, "start" + Esc(struct_def.name), "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 = "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 << ", " << ConvertCase(Esc(field.name), Case::kLowerCamel);
        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(
                      "camel_field_name",
                      ConvertCase(Esc(field.name), Case::kUpperCamel));
                  writer.SetValue("field_name", ConvertCase(Esc(field.name),
                                                            Case::kLowerCamel));

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

                  writer += "add{{camel_field_name}}(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 = ConvertCase(Esc(struct_def.name), Case::kLowerCamel);
    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 = ConvertCase(Esc(field.name), Case::kLowerCamel);
      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 =
                  ConvertCase(Esc(field.name), Case::kLowerCamel) + "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 = "mutate" + ConvertCase(Esc(field.name), Case::kUpperCamel);
        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 (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);
    }
  }

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

  static void GenerateStaticConstructor(const StructDef &struct_def,
                                        CodeWriter &code,
                                        const IDLOptions options) {
    // 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()";
        },
        options.gen_jvmstatic);
  }

  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 << ConvertCase(Esc(field.name), Case::kLowerCamel)
            << ": " << 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"; }
  }

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