/*
 * Copyright 2020 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.
 */

#include <cctype>
#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 swift {

namespace {

static Namer::Config SwiftDefaultConfig() {
  return { /*types=*/Case::kKeep,
           /*constants=*/Case::kLowerCamel,
           /*methods=*/Case::kLowerCamel,
           /*functions=*/Case::kLowerCamel,
           /*fields=*/Case::kLowerCamel,
           /*variables=*/Case::kLowerCamel,
           /*variants=*/Case::kLowerCamel,
           /*enum_variant_seperator=*/".",
           /*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase,
           /*namespaces=*/Case::kKeep,
           /*namespace_seperator=*/"_",
           /*object_prefix=*/"",
           /*object_suffix=*/"T",
           /*keyword_prefix=*/"",
           /*keyword_suffix=*/"_",
           /*filenames=*/Case::kKeep,
           /*directories=*/Case::kKeep,
           /*output_path=*/"",
           /*filename_suffix=*/"_generated",
           /*filename_extension=*/".swift" };
}

static std::set<std::string> SwiftKeywords() {
  return {
    "associatedtype",
    "class",
    "deinit",
    "enum",
    "extension",
    "fileprivate",
    "func",
    "import",
    "init",
    "inout",
    "internal",
    "let",
    "open",
    "operator",
    "private",
    "protocol",
    "public",
    "rethrows",
    "static",
    "struct",
    "subscript",
    "typealias",
    "var",
    "break",
    "case",
    "continue",
    "default",
    "defer",
    "do",
    "else",
    "fallthrough",
    "for",
    "guard",
    "if",
    "in",
    "repeat",
    "return",
    "switch",
    "where",
    "while",
    "Any",
    "catch",
    "false",
    "is",
    "nil",
    "super",
    "self",
    "Self",
    "throw",
    "throws",
    "true",
    "try",
    "associativity",
    "convenience",
    "dynamic",
    "didSet",
    "final",
    "get",
    "infix",
    "indirect",
    "lazy",
    "left",
    "mutating",
    "none",
    "nonmutating",
    "optional",
    "override",
    "postfix",
    "precedence",
    "prefix",
    "Protocol",
    "required",
    "right",
    "set",
    "Type",
    "unowned",
    "weak",
    "willSet",
    "Void",
  };
}

static std::string GenIndirect(const std::string &reading) {
  return "{{ACCESS}}.indirect(" + reading + ")";
}

static std::string GenArrayMainBody(const std::string &optional) {
  return "{{ACCESS_TYPE}} func {{FIELDMETHOD}}(at index: Int32) -> "
         "{{VALUETYPE}}" +
         optional + " { ";
}

} // namespace

class SwiftGenerator : public BaseGenerator {
 private:
  CodeWriter code_;
  std::unordered_set<std::string> keywords_;
  int namespace_depth;

 public:
  SwiftGenerator(const Parser &parser, const std::string &path,
                 const std::string &file_name)
      : BaseGenerator(parser, path, file_name, "", "_", "swift"),
        namer_(WithFlagOptions(SwiftDefaultConfig(), parser.opts, path),
               SwiftKeywords()) {
    namespace_depth = 0;
    code_.SetPadding("  ");
  }

  bool generate() {
    code_.Clear();
    code_.SetValue("ACCESS", "_accessor");
    code_.SetValue("TABLEOFFSET", "VTOFFSET");
    code_ += "// " + std::string(FlatBuffersGeneratedWarning());
    code_ += "// swiftlint:disable all";
    code_ += "// swiftformat:disable all\n";
    if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) {
      if (parser_.opts.swift_implementation_only)
        code_ += "@_implementationOnly \\";

      code_ += "import FlatBuffers\n";
    }

    // Generate code for all the enum declarations.
    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
         ++it) {
      const auto &enum_def = **it;
      if (!enum_def.generated) { GenEnum(enum_def); }
    }

    for (auto it = parser_.structs_.vec.begin();
         it != parser_.structs_.vec.end(); ++it) {
      const auto &struct_def = **it;
      if (struct_def.fixed && !struct_def.generated) {
        GenStructReader(struct_def);
        GenMutableStructReader(struct_def);
      }
    }

    for (auto it = parser_.structs_.vec.begin();
         it != parser_.structs_.vec.end(); ++it) {
      const auto &struct_def = **it;
      if (!struct_def.fixed && !struct_def.generated) {
        GenTable(struct_def);
        if (parser_.opts.generate_object_based_api) {
          GenObjectAPI(struct_def);
        }
      }
    }

    const auto filename = GeneratedFileName(path_, file_name_, parser_.opts);
    const auto final_code = code_.ToString();
    return SaveFile(filename.c_str(), final_code, false);
  }

  void mark(const std::string &str) {
    code_.SetValue("MARKVALUE", str);
    code_ += "\n// MARK: - {{MARKVALUE}}\n";
  }

  // MARK: - Generating structs

  // Generates the reader for swift
  void GenStructReader(const StructDef &struct_def) {
    const bool is_private_access =
        parser_.opts.swift_implementation_only ||
        struct_def.attributes.Lookup("private") != nullptr;
    code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public");
    GenComment(struct_def.doc_comment);
    code_.SetValue("STRUCTNAME", namer_.NamespacedType(struct_def));
    code_ +=
        "{{ACCESS_TYPE}} struct {{STRUCTNAME}}: NativeStruct, Verifiable, "
        "FlatbuffersInitializable\\";
    if (parser_.opts.generate_object_based_api) code_ += ", NativeObject\\";
    code_ += " {";
    code_ += "";
    Indent();
    code_ += ValidateFunc();
    code_ += "";
    int padding_id = 0;
    std::string constructor = "";
    std::vector<std::string> base_constructor;
    std::vector<std::string> main_constructor;

    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;

      if (!constructor.empty()) constructor += ", ";

      const auto field_var = namer_.Variable(field);
      const auto type = GenType(field.value.type);
      code_.SetValue("FIELDVAR", field_var);
      if (IsEnum(field.value.type)) {
        code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false));
      }
      code_.SetValue("VALUETYPE", type);
      GenComment(field.doc_comment);
      std::string valueType =
          IsEnum(field.value.type) ? "{{BASEVALUE}}" : "{{VALUETYPE}}";
      code_ += "private var _{{FIELDVAR}}: " + valueType;
      const auto accessing_value = IsEnum(field.value.type) ? ".value" : "";
      const auto base_value =
          IsStruct(field.value.type) ? (type + "()")
          : SwiftConstant(field);

      main_constructor.push_back("_" + field_var + " = " + field_var +
                                 accessing_value);
      base_constructor.push_back("_" + field_var + " = " + base_value);

      if (field.padding) { GenPadding(field, &padding_id); }
      constructor += field_var + ": " + type;
    }
    code_ += "";
    BuildStructConstructor(struct_def);
    BuildObjectConstructor(main_constructor, constructor);
    BuildObjectConstructor(base_constructor, "");

    if (parser_.opts.generate_object_based_api)
      GenerateObjectAPIStructConstructor(struct_def);

    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;
      code_.SetValue("FIELDVAR", namer_.Variable(field));
      code_.SetValue("VALUETYPE", GenType(field.value.type));
      GenComment(field.doc_comment);
      if (!IsEnum(field.value.type)) {
        code_ += GenReaderMainBody() + "_{{FIELDVAR}} }";
      } else if (IsEnum(field.value.type)) {
        code_ +=
            GenReaderMainBody() + "{{VALUETYPE}}(rawValue: _{{FIELDVAR}})! }";
      }
    }
    code_ += "";
    code_ +=
        "{{ACCESS_TYPE}} static func verify<T>(_ verifier: inout Verifier, at "
        "position: "
        "Int, of type: T.Type) throws where T: Verifiable {";
    Indent();
    code_ +=
        "try verifier.inBuffer(position: position, of: {{STRUCTNAME}}.self)";
    Outdent();
    code_ += "}";
    Outdent();
    code_ += "}\n";
    if (parser_.opts.gen_json_coders) GenerateJSONEncodingAPIs(struct_def);
  }

  void BuildStructConstructor(const StructDef &struct_def) {
    code_ += "{{ACCESS_TYPE}} init(_ bb: ByteBuffer, o: Int32) {";
    Indent();
    code_ += "let {{ACCESS}} = Struct(bb: bb, position: o)";
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;
      const auto type = field.value.type;
      code_.SetValue("FIELDVAR", namer_.Variable(field));
      code_.SetValue("VALUETYPE", GenType(type));
      code_.SetValue("OFFSET", NumToString(field.value.offset));
      if (IsScalar(type.base_type)) {
        if (IsEnum(type))
          code_.SetValue("VALUETYPE", GenTypeBasic(field.value.type, false));
        code_ +=
            "_{{FIELDVAR}} = {{ACCESS}}.readBuffer(of: {{VALUETYPE}}.self, "
            "at: {{OFFSET}})";
      } else {
        code_ +=
            "_{{FIELDVAR}} = {{VALUETYPE}}({{ACCESS}}.bb, o: "
            "{{ACCESS}}.postion + {{OFFSET}})";
      }
    }
    Outdent();
    code_ += "}\n";
  }

  void GenMutableStructReader(const StructDef &struct_def) {
    GenObjectHeader(struct_def);

    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;
      const auto offset = NumToString(field.value.offset);
      const auto type = GenType(field.value.type);
      code_.SetValue("FIELDVAR", namer_.Variable(field));
      if (IsEnum(field.value.type)) {
        code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false));
      }
      code_.SetValue("VALUETYPE", type);
      code_.SetValue("OFFSET", offset);
      if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type)) {
        code_ +=
            GenReaderMainBody() + "return " + GenReader("VALUETYPE") + " }";
      } else if (IsEnum(field.value.type)) {
        code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false));
        code_ += GenReaderMainBody() + "return " +
                 GenEnumConstructor("{{OFFSET}}") + "?? " +
                 GenEnumDefaultValue(field) + " }";
      } else if (IsStruct(field.value.type)) {
        code_.SetValue("VALUETYPE", GenType(field.value.type) + Mutable());
        code_ += GenReaderMainBody() + "return " +
                 GenConstructor("{{ACCESS}}.postion + {{OFFSET}}");
      }
      if (parser_.opts.mutable_buffer && !IsStruct(field.value.type))
        code_ += GenMutate("{{OFFSET}}", "", IsEnum(field.value.type));
    }

    if (parser_.opts.generate_object_based_api) {
      GenerateObjectAPIExtensionHeader(namer_.NamespacedType(struct_def));
      code_ += "return builder.create(struct: obj)";
      Outdent();
      code_ += "}";
    }
    Outdent();
    code_ += "}\n";
  }

  void GenerateStructArgs(const StructDef &struct_def, std::string *code_ptr,
                          const std::string &nameprefix,
                          const std::string &object_name,
                          const std::string &obj_api_named = "",
                          bool is_obj_api = false) {
    auto &code = *code_ptr;
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;
      const auto &field_type = field.value.type;
      if (IsStruct(field.value.type)) {
        GenerateStructArgs(
            *field_type.struct_def, code_ptr, (nameprefix + field.name),
            (object_name + "." + field.name), obj_api_named, is_obj_api);
      } else {
        const auto field_var = namer_.Variable(field);
        const auto field_field = namer_.Field(field);
        const auto type = GenType(field.value.type);
        if (!is_obj_api) {
          code += nameprefix + field_var + ": " + type;
          if (!IsEnum(field.value.type)) {
            code += " = ";
            code += SwiftConstant(field);
          }
          code += ", ";
          continue;
        }
        code += nameprefix + field_var + ": " + obj_api_named + object_name +
                "." + field_field;
        code += ", ";
      }
    }
  }

  // MARK: - Table Generator

  // Generates the reader for swift
  void GenTable(const StructDef &struct_def) {
    const bool is_private_access =
        parser_.opts.swift_implementation_only ||
        struct_def.attributes.Lookup("private") != nullptr;
    code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public");
    GenObjectHeader(struct_def);
    GenTableAccessors(struct_def);
    GenTableReader(struct_def);
    GenTableWriter(struct_def);
    if (parser_.opts.generate_object_based_api)
      GenerateObjectAPITableExtension(struct_def);
    code_ += "";
    GenerateVerifier(struct_def);
    Outdent();
    code_ += "}\n";
    if (parser_.opts.gen_json_coders) GenerateJSONEncodingAPIs(struct_def);
  }

  // Generates the reader for swift
  void GenTableAccessors(const StructDef &struct_def) {
    // Generate field id constants.
    if (struct_def.fields.vec.size() > 0) {
      code_ += "private enum {{TABLEOFFSET}}: VOffset {";
      Indent();
      for (auto it = struct_def.fields.vec.begin();
           it != struct_def.fields.vec.end(); ++it) {
        const auto &field = **it;
        if (field.deprecated) { continue; }
        code_.SetValue("OFFSET_NAME", namer_.Variable(field));
        code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
        code_ += "case {{OFFSET_NAME}} = {{OFFSET_VALUE}}";
      }
      code_ += "var v: Int32 { Int32(self.rawValue) }";
      code_ += "var p: VOffset { self.rawValue }";
      Outdent();
      code_ += "}";
      code_ += "";
    }
  }

  void GenObjectHeader(const StructDef &struct_def) {
    GenComment(struct_def.doc_comment);

    code_.SetValue("SHORT_STRUCTNAME", namer_.Type(struct_def));
    code_.SetValue("STRUCTNAME", namer_.NamespacedType(struct_def));
    code_.SetValue("OBJECTTYPE", struct_def.fixed ? "Struct" : "Table");
    code_.SetValue("MUTABLE", struct_def.fixed ? Mutable() : "");
    code_ +=
        "{{ACCESS_TYPE}} struct {{STRUCTNAME}}{{MUTABLE}}: FlatBufferObject\\";
    if (!struct_def.fixed) code_ += ", Verifiable\\";
    if (!struct_def.fixed && parser_.opts.generate_object_based_api)
      code_ += ", ObjectAPIPacker\\";
    code_ += " {\n";
    Indent();
    code_ += ValidateFunc();
    code_ +=
        "{{ACCESS_TYPE}} var __buffer: ByteBuffer! { return {{ACCESS}}.bb }";
    code_ += "private var {{ACCESS}}: {{OBJECTTYPE}}\n";
    if (!struct_def.fixed) {
      if (parser_.file_identifier_.length()) {
        code_.SetValue("FILENAME", parser_.file_identifier_);
        code_ += "{{ACCESS_TYPE}} static var id: String { \"{{FILENAME}}\" } ";
        code_ +=
            "{{ACCESS_TYPE}} static func finish(_ fbb: inout "
            "FlatBufferBuilder, end: "
            "Offset, prefix: Bool = false) { fbb.finish(offset: end, "
            "fileId: "
            "{{STRUCTNAME}}.id, addPrefix: prefix) }";
      }
      code_ +=
          "{{ACCESS_TYPE}} static func getRootAs{{SHORT_STRUCTNAME}}(bb: "
          "ByteBuffer) -> "
          "{{STRUCTNAME}} { return {{STRUCTNAME}}(Table(bb: bb, position: "
          "Int32(bb.read(def: UOffset.self, position: bb.reader)) + "
          "Int32(bb.reader))) }\n";
      code_ += "private init(_ t: Table) { {{ACCESS}} = t }";
    }
    code_ +=
        "{{ACCESS_TYPE}} init(_ bb: ByteBuffer, o: Int32) { {{ACCESS}} = "
        "{{OBJECTTYPE}}(bb: "
        "bb, position: o) }";
    code_ += "";
  }

  void GenTableWriter(const StructDef &struct_def) {
    flatbuffers::FieldDef *key_field = nullptr;
    std::vector<std::string> require_fields;
    std::vector<std::string> create_func_body;
    std::vector<std::string> create_func_header;
    const auto should_generate_create = struct_def.fields.vec.size() != 0;

    code_.SetValue("NUMBEROFFIELDS", NumToString(struct_def.fields.vec.size()));
    code_ +=
        "{{ACCESS_TYPE}} static func start{{SHORT_STRUCTNAME}}(_ fbb: inout "
        "FlatBufferBuilder) -> "
        "UOffset { fbb.startTable(with: {{NUMBEROFFIELDS}}) }";

    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto &field = **it;
      if (field.deprecated) continue;
      if (field.key) key_field = &field;
      if (field.IsRequired())
        require_fields.push_back(NumToString(field.value.offset));

      GenTableWriterFields(field, &create_func_body, &create_func_header);
    }
    code_ +=
        "{{ACCESS_TYPE}} static func end{{SHORT_STRUCTNAME}}(_ fbb: inout "
        "FlatBufferBuilder, "
        "start: "
        "UOffset) -> Offset { let end = Offset(offset: "
        "fbb.endTable(at: start))\\";
    if (require_fields.capacity() != 0) {
      std::string fields = "";
      for (auto it = require_fields.begin(); it != require_fields.end(); ++it)
        fields += *it + ", ";
      code_.SetValue("FIELDS", fields.substr(0, fields.size() - 2));
      code_ += "; fbb.require(table: end, fields: [{{FIELDS}}])\\";
    }
    code_ += "; return end }";

    if (should_generate_create) {
      code_ += "{{ACCESS_TYPE}} static func create{{SHORT_STRUCTNAME}}(";
      Indent();
      code_ += "_ fbb: inout FlatBufferBuilder,";
      for (auto it = create_func_header.begin(); it < create_func_header.end();
           ++it) {
        code_ += *it + "\\";
        if (it < create_func_header.end() - 1) code_ += ",";
      }
      code_ += "";
      Outdent();
      code_ += ") -> Offset {";
      Indent();
      code_ += "let __start = {{STRUCTNAME}}.start{{SHORT_STRUCTNAME}}(&fbb)";
      for (auto it = create_func_body.begin(); it < create_func_body.end();
           ++it) {
        code_ += *it;
      }
      code_ +=
          "return {{STRUCTNAME}}.end{{SHORT_STRUCTNAME}}(&fbb, start: __start)";
      Outdent();
      code_ += "}";
    }

    std::string spacing = "";

    if (key_field != nullptr && !struct_def.fixed && struct_def.has_key) {
      code_.SetValue("VOFFSET", NumToString(key_field->value.offset));

      code_ += "{{ACCESS_TYPE}} static func " +
               namer_.Method("sort_vector_of", struct_def) +
               "(offsets:[Offset], "
               "_ fbb: inout FlatBufferBuilder) -> Offset {";
      Indent();
      code_ += spacing + "var off = offsets";
      code_ +=
          spacing +
          "off.sort { Table.compare(Table.offset(Int32($1.o), vOffset: "
          "{{VOFFSET}}, fbb: fbb.buffer), Table.offset(Int32($0.o), vOffset: "
          "{{VOFFSET}}, fbb: fbb.buffer), fbb: fbb.buffer) < 0 } ";
      code_ += spacing + "return fbb.createVector(ofOffsets: off)";
      Outdent();
      code_ += "}";
      GenLookup(*key_field, namer_.NamespacedType(struct_def));
    }
  }

  void GenTableWriterFields(const FieldDef &field,
                            std::vector<std::string> *create_body,
                            std::vector<std::string> *create_header) {
    std::string builder_string = ", _ fbb: inout FlatBufferBuilder) { ";
    auto &create_func_body = *create_body;
    auto &create_func_header = *create_header;
    const auto field_field = namer_.Field(field);
    const auto field_var = namer_.Variable(field);
    const auto type = GenType(field.value.type);
    const auto opt_scalar =
        field.IsOptional() && IsScalar(field.value.type.base_type);
    const auto nullable_type = opt_scalar ? type + "?" : type;
    code_.SetValue("FIELDVAR", namer_.Variable(field));
    code_.SetValue("VALUETYPE", nullable_type);
    code_.SetValue("OFFSET", namer_.Field(field));
    code_.SetValue("CONSTANT", SwiftConstant(field));
    std::string check_if_vector =
        (IsVector(field.value.type) || IsArray(field.value.type)) ? "VectorOf("
                                                                  : "(";
    const auto body = "add" + check_if_vector + field_field + ": ";
    code_ += "{{ACCESS_TYPE}} static func " + body + "\\";

    create_func_body.push_back("{{STRUCTNAME}}." + body + field_field +
                               ", &fbb)");

    if (IsScalar(field.value.type.base_type) &&
        !IsBool(field.value.type.base_type)) {
      const std::string is_enum = IsEnum(field.value.type) ? ".rawValue" : "";
      const std::string optional_enum =
          IsEnum(field.value.type) ? ("?" + is_enum) : "";
      code_ +=
          "{{VALUETYPE}}" + builder_string + "fbb.add(element: {{FIELDVAR}}\\";

      code_ += field.IsOptional() ? (optional_enum + "\\")
                                  : (is_enum + ", def: {{CONSTANT}}\\");

      code_ += ", at: {{TABLEOFFSET}}.{{OFFSET}}.p) }";

      const auto default_value =
          IsEnum(field.value.type)
              ? (field.IsOptional() ? "nil" : GenEnumDefaultValue(field))
              : SwiftConstant(field);
      create_func_header.push_back(
          "" + field_field + ": " + nullable_type + " = " +
          (field.IsOptional() ? "nil" : default_value));
      return;
    }

    if (IsBool(field.value.type.base_type)) {
      std::string default_value = SwiftConstant(field);

      code_.SetValue("CONSTANT", default_value);
      code_.SetValue("VALUETYPE", field.IsOptional() ? "Bool?" : "Bool");
      code_ +=
          "{{VALUETYPE}}" + builder_string + "fbb.add(element: {{FIELDVAR}},\\";
      code_ += field.IsOptional() ? "\\" : " def: {{CONSTANT}},";
      code_ += " at: {{TABLEOFFSET}}.{{OFFSET}}.p) }";
      create_func_header.push_back(
          field_var + ": " + nullable_type + " = " +
          (field.IsOptional() ? "nil" : default_value));
      return;
    }

    if (IsStruct(field.value.type)) {
      const auto create_struct =
          "guard let {{FIELDVAR}} = {{FIELDVAR}} else { return };"
          " fbb.create(struct: {{FIELDVAR}}, position: "
          "{{TABLEOFFSET}}.{{OFFSET}}.p) }";
      code_ += type + "?" + builder_string + create_struct;
      /// Optional hard coded since structs are always optional
      create_func_header.push_back(field_var + ": " + type +
                                   (field.IsOptional() ? "? = nil" : ""));
      return;
    }

    const auto arg_label =
        namer_.Variable(field) +
        (IsVector(field.value.type) || IsArray(field.value.type)
             ? "VectorOffset"
             : "Offset");
    create_func_header.push_back(arg_label + " " + field_var + ": " + "Offset" +
                                 (field.IsRequired() ? "" : " = Offset()"));
    const auto reader_type =
        IsStruct(field.value.type) && field.value.type.struct_def->fixed
            ? "structOffset: {{TABLEOFFSET}}.{{OFFSET}}.p) }"
            : "offset: {{FIELDVAR}}, at: {{TABLEOFFSET}}.{{OFFSET}}.p) }";
    code_ += "Offset" + builder_string + "fbb.add(" + reader_type;

    const auto vectortype = field.value.type.VectorType();

    if ((vectortype.base_type == BASE_TYPE_STRUCT &&
         field.value.type.struct_def->fixed) &&
        (IsVector(field.value.type) || IsArray(field.value.type))) {
      const auto field_name = namer_.NamespacedType(*vectortype.struct_def);
      code_ += "{{ACCESS_TYPE}} static func " +
               namer_.Method("start_vector_of", field_var) +
               "(_ size: Int, in builder: inout "
               "FlatBufferBuilder) {";
      Indent();
      code_ += "builder.startVector(size * MemoryLayout<" + field_name +
               ">.size, elementSize: MemoryLayout<" + field_name +
               ">.alignment)";
      Outdent();
      code_ += "}";
    }
  }

  void GenTableReader(const StructDef &struct_def) {
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;
      GenTableReaderFields(field);
    }
  }

  void GenTableReaderFields(const FieldDef &field) {
    const auto offset = NumToString(field.value.offset);
    const auto field_field = namer_.Field(field);
    const auto type = GenType(field.value.type);
    code_.SetValue("FIELDVAR", namer_.Variable(field));
    code_.SetValue("FIELDMETHOD", namer_.Method(field));
    code_.SetValue("VALUETYPE", type);
    code_.SetValue("OFFSET", namer_.Constant(field.name));
    code_.SetValue("CONSTANT", SwiftConstant(field));
    bool opt_scalar =
        field.IsOptional() && IsScalar(field.value.type.base_type);
    std::string def_Val = opt_scalar ? "nil" : "{{CONSTANT}}";
    std::string optional = opt_scalar ? "?" : "";
    const auto const_string = "return o == 0 ? " + def_Val + " : ";
    GenComment(field.doc_comment);
    if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type) &&
        !IsBool(field.value.type.base_type)) {
      code_ += GenReaderMainBody(optional) + GenOffset() + const_string +
               GenReader("VALUETYPE", "o") + " }";
      if (parser_.opts.mutable_buffer) code_ += GenMutate("o", GenOffset());
      return;
    }

    if (IsBool(field.value.type.base_type)) {
      std::string default_value =
          field.IsOptional() ? "nil"
                             : SwiftConstant(field);
      code_.SetValue("CONSTANT", default_value);
      code_.SetValue("VALUETYPE", "Bool");
      code_ += GenReaderMainBody(optional) + "\\";
      code_.SetValue("VALUETYPE", "Byte");
      code_ += GenOffset() + "return o == 0 ? {{CONSTANT}} : 0 != " +
               GenReader("VALUETYPE", "o") + " }";
      if (parser_.opts.mutable_buffer) code_ += GenMutate("o", GenOffset());
      return;
    }

    if (IsEnum(field.value.type)) {
      const auto default_value =
          field.IsOptional() ? "nil" : GenEnumDefaultValue(field);
      code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false));
      code_ += GenReaderMainBody(optional) + "\\";
      code_ += GenOffset() + "return o == 0 ? " + default_value + " : " +
               GenEnumConstructor("o") + "?? " + default_value + " }";
      if (parser_.opts.mutable_buffer && !IsUnion(field.value.type))
        code_ += GenMutate("o", GenOffset(), true);
      return;
    }

    const std::string is_required = field.IsRequired() ? "!" : "?";
    const auto required_reader = field.IsRequired() ? "return " : const_string;

    if (IsStruct(field.value.type) && field.value.type.struct_def->fixed) {
      code_.SetValue("VALUETYPE", GenType(field.value.type));
      code_.SetValue("CONSTANT", "nil");
      code_ += GenReaderMainBody(is_required) + GenOffset() + required_reader +
               "{{ACCESS}}.readBuffer(of: {{VALUETYPE}}.self, at: o) }";
      code_.SetValue("FIELDVAR", namer_.Variable("mutable", field_field));
      code_.SetValue("VALUETYPE", GenType(field.value.type) + Mutable());
      code_.SetValue("CONSTANT", "nil");
      code_ += GenReaderMainBody(is_required) + GenOffset() + required_reader +
               GenConstructor("o + {{ACCESS}}.postion");
      return;
    }
    switch (field.value.type.base_type) {
      case BASE_TYPE_STRUCT:
        code_.SetValue("VALUETYPE", GenType(field.value.type));
        code_.SetValue("CONSTANT", "nil");
        code_ += GenReaderMainBody(is_required) + GenOffset() +
                 required_reader +
                 GenConstructor(GenIndirect("o + {{ACCESS}}.postion"));
        break;

      case BASE_TYPE_STRING: {
        const auto default_string = "\"" + SwiftConstant(field) + "\"";
        code_.SetValue("VALUETYPE", GenType(field.value.type));
        code_.SetValue("CONSTANT", field.IsDefault() ? default_string : "nil");
        code_ += GenReaderMainBody(is_required) + GenOffset() +
                 required_reader + "{{ACCESS}}.string(at: o) }";
        code_ += "{{ACCESS_TYPE}} var {{FIELDVAR}}SegmentArray: [UInt8]" +
                 is_required +
                 " { return "
                 "{{ACCESS}}.getVector(at: {{TABLEOFFSET}}.{{OFFSET}}.v) }";
        break;
      }
      case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();  // fall thru
      case BASE_TYPE_VECTOR: GenTableReaderVectorFields(field); break;
      case BASE_TYPE_UNION:
        code_.SetValue("CONSTANT", "nil");
        code_ +=
            "{{ACCESS_TYPE}} func {{FIELDVAR}}<T: "
            "FlatbuffersInitializable>(type: "
            "T.Type) -> T" +
            is_required + " { " + GenOffset() + required_reader +
            "{{ACCESS}}.union(o) }";
        break;
      default: FLATBUFFERS_ASSERT(0);
    }
  }

  void GenTableReaderVectorFields(const FieldDef &field) {
    std::string const_string = "return o == 0 ? {{CONSTANT}} : ";
    const auto vectortype = field.value.type.VectorType();
    code_.SetValue("SIZE", NumToString(InlineSize(vectortype)));
    code_.SetValue("HAS_FIELDVAR", namer_.Variable("has", field));
    code_ += "{{ACCESS_TYPE}} var {{HAS_FIELDVAR}}: Bool { " + GenOffset() +
             "return o == 0 ? false : true }";
    code_ += "{{ACCESS_TYPE}} var {{FIELDVAR}}Count: Int32 { " + GenOffset() +
             "return o == 0 ? 0 : {{ACCESS}}.vector(count: o) }";
    code_.SetValue("CONSTANT", IsScalar(vectortype.base_type) ? "0" : "nil");
    const auto nullable =
        IsScalar(vectortype.base_type) && !IsEnum(vectortype) ? "" : "?";

    if (vectortype.base_type != BASE_TYPE_UNION) {
      code_ += GenArrayMainBody(nullable) + GenOffset() + "\\";
    } else {
      code_ +=
          "{{ACCESS_TYPE}} func {{FIELDVAR}}<T: FlatbuffersInitializable>(at "
          "index: "
          "Int32, type: T.Type) -> T? { " +
          GenOffset() + "\\";
    }

    if (IsBool(vectortype.base_type)) {
      code_.SetValue("CONSTANT", field.value.offset == 0 ? "false" : "true");
      code_.SetValue("VALUETYPE", "Bool");
    }

    if (!IsEnum(vectortype)) code_ += const_string + "\\";

    if (IsScalar(vectortype.base_type) && !IsEnum(vectortype) &&
        !IsBool(field.value.type.base_type)) {
      code_ +=
          "{{ACCESS}}.directRead(of: {{VALUETYPE}}.self, offset: "
          "{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }";
      code_ +=
          "{{ACCESS_TYPE}} var {{FIELDVAR}}: [{{VALUETYPE}}] { return "
          "{{ACCESS}}.getVector(at: {{TABLEOFFSET}}.{{OFFSET}}.v) ?? [] }";
      if (parser_.opts.mutable_buffer) code_ += GenMutateArray();
      return;
    }

    if (vectortype.base_type == BASE_TYPE_STRUCT &&
        field.value.type.struct_def->fixed) {
      code_ +=
          "{{ACCESS}}.directRead(of: {{VALUETYPE}}.self, offset: "
          "{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }";
      code_.SetValue("FIELDMETHOD", namer_.Method("mutable", field));
      code_.SetValue("VALUETYPE", GenType(field.value.type) + Mutable());
      code_ += GenArrayMainBody(nullable) + GenOffset() + const_string +
               GenConstructor("{{ACCESS}}.vector(at: o) + index * {{SIZE}}");

      return;
    }

    if (IsString(vectortype)) {
      code_ +=
          "{{ACCESS}}.directString(at: {{ACCESS}}.vector(at: o) + "
          "index * {{SIZE}}) }";
      return;
    }

    if (IsEnum(vectortype)) {
      code_.SetValue("BASEVALUE", GenTypeBasic(vectortype, false));
      code_ += "return o == 0 ? {{VALUETYPE}}" + GenEnumDefaultValue(field) +
               " : {{VALUETYPE}}(rawValue: {{ACCESS}}.directRead(of: "
               "{{BASEVALUE}}.self, offset: {{ACCESS}}.vector(at: o) + "
               "index * {{SIZE}})) }";
      return;
    }
    if (vectortype.base_type == BASE_TYPE_UNION) {
      code_ +=
          "{{ACCESS}}.directUnion({{ACCESS}}.vector(at: o) + "
          "index * {{SIZE}}) }";
      return;
    }

    if (vectortype.base_type == BASE_TYPE_STRUCT &&
        !field.value.type.struct_def->fixed) {
      code_ += GenConstructor(
          "{{ACCESS}}.indirect({{ACCESS}}.vector(at: o) + index * "
          "{{SIZE}})");
      const auto &sd = *field.value.type.struct_def;
      const auto &fields = sd.fields.vec;
      for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
        const auto &key_field = **kit;
        if (key_field.key) {
          GenByKeyFunctions(key_field);
          break;
        }
      }
    }
  }

  void GenerateCodingKeys(const StructDef &struct_def) {
    code_ += "enum CodingKeys: String, CodingKey {";
    Indent();
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;

      code_.SetValue("RAWVALUENAME", field.name);
      code_.SetValue("FIELDVAR", namer_.Variable(field));
      code_ += "case {{FIELDVAR}} = \"{{RAWVALUENAME}}\"";
    }
    Outdent();
    code_ += "}";
  }

  void GenerateEncoderUnionBody(const FieldDef &field) {
    EnumDef &union_def = *field.value.type.enum_def;
    const auto is_vector = field.value.type.base_type == BASE_TYPE_VECTOR ||
                           field.value.type.base_type == BASE_TYPE_ARRAY;
    if (field.value.type.base_type == BASE_TYPE_UTYPE ||
        (is_vector &&
         field.value.type.VectorType().base_type == BASE_TYPE_UTYPE))
      return;
    if (is_vector) {
      code_ +=
          "var enumsEncoder = container.nestedUnkeyedContainer(forKey: "
          ".{{FIELDVAR}}Type)";
      code_ +=
          "var contentEncoder = container.nestedUnkeyedContainer(forKey: "
          ".{{FIELDVAR}})";
      code_ += "for index in 0..<{{FIELDVAR}}Count {";
      Indent();
      code_ += "guard let type = {{FIELDVAR}}Type(at: index) else { continue }";
      code_ += "try enumsEncoder.encode(type)";
      code_ += "switch type {";
      for (auto it = union_def.Vals().begin(); it != union_def.Vals().end();
           ++it) {
        const auto &ev = **it;
        const auto type = GenType(ev.union_type);
        code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
        code_.SetValue("VALUETYPE", type);
        if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; }
        code_ += "case .{{KEY}}:";
        Indent();
        code_ += "let _v = {{FIELDVAR}}(at: index, type: {{VALUETYPE}}.self)";
        code_ += "try contentEncoder.encode(_v)";
        Outdent();
      }
      code_ += "default: break;";
      code_ += "}";
      Outdent();
      code_ += "}";
      return;
    }

    code_ += "switch {{FIELDVAR}}Type {";
    for (auto it = union_def.Vals().begin(); it != union_def.Vals().end();
         ++it) {
      const auto &ev = **it;
      const auto type = GenType(ev.union_type);
      code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
      code_.SetValue("VALUETYPE", type);
      if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; }
      code_ += "case .{{KEY}}:";
      Indent();
      code_ += "let _v = {{FIELDVAR}}(type: {{VALUETYPE}}.self)";
      code_ += "try container.encodeIfPresent(_v, forKey: .{{FIELDVAR}})";
      Outdent();
    }
    code_ += "default: break;";
    code_ += "}";
  }

  void GenerateEncoderBody(const StructDef &struct_def) {
    code_ += "var container = encoder.container(keyedBy: CodingKeys.self)";
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;
      const auto type = field.value.type;

      const auto is_non_union_vector =
          (field.value.type.base_type == BASE_TYPE_ARRAY ||
           field.value.type.base_type == BASE_TYPE_VECTOR) &&
          field.value.type.VectorType().base_type != BASE_TYPE_UTYPE;

      code_.SetValue("FIELDVAR", namer_.Variable(field));
      code_.SetValue("CONSTANT", SwiftConstant(field));
      bool should_indent = true;
      if (is_non_union_vector) {
        code_ += "if {{FIELDVAR}}Count > 0 {";
      } else if (IsEnum(type) && !field.IsOptional()) {
        code_.SetValue("CONSTANT", GenEnumDefaultValue(field));
        code_ += "if {{FIELDVAR}} != {{CONSTANT}} {";
      } else if (IsFloat(type.base_type) && StringIsFlatbufferNan(field.value.constant)) {
	code_ += "if !{{FIELDVAR}}.isNaN {";
      } else if (IsScalar(type.base_type) && !IsEnum(type) &&
                 !IsBool(type.base_type) && !field.IsOptional()) {
        code_ += "if {{FIELDVAR}} != {{CONSTANT}} {";
      } else if (IsBool(type.base_type) && !field.IsOptional()) {
        code_.SetValue("CONSTANT", SwiftConstant(field));
        code_ += "if {{FIELDVAR}} != {{CONSTANT}} {";
      } else {
        should_indent = false;
      }
      if (should_indent) Indent();

      if (IsUnion(type) && !IsEnum(type)) {
        GenerateEncoderUnionBody(field);
      } else if (is_non_union_vector &&
                 (!IsScalar(type.VectorType().base_type) ||
                  IsEnum(type.VectorType()))) {
        code_ +=
            "var contentEncoder = container.nestedUnkeyedContainer(forKey: "
            ".{{FIELDVAR}})";
        code_ += "for index in 0..<{{FIELDVAR}}Count {";
        Indent();
        code_ += "guard let type = {{FIELDVAR}}(at: index) else { continue }";
        code_ += "try contentEncoder.encode(type)";
        Outdent();
        code_ += "}";
      } else {
        code_ +=
            "try container.encodeIfPresent({{FIELDVAR}}, forKey: "
            ".{{FIELDVAR}})";
      }
      if (should_indent) Outdent();

      if (is_non_union_vector ||
          (IsScalar(type.base_type) && !field.IsOptional())) {
        code_ += "}";
      }
    }
  }

  void GenerateJSONEncodingAPIs(const StructDef &struct_def) {
    code_ += "extension {{STRUCTNAME}}: Encodable {";
    Indent();
    code_ += "";
    if (struct_def.fields.vec.empty() == false) GenerateCodingKeys(struct_def);

    code_ += "{{ACCESS_TYPE}} func encode(to encoder: Encoder) throws {";
    Indent();
    if (struct_def.fields.vec.empty() == false) GenerateEncoderBody(struct_def);
    Outdent();
    code_ += "}";
    Outdent();
    code_ += "}";
    code_ += "";
  }

  void GenerateVerifier(const StructDef &struct_def) {
    code_ +=
        "{{ACCESS_TYPE}} static func verify<T>(_ verifier: inout Verifier, at "
        "position: "
        "Int, of type: T.Type) throws where T: Verifiable {";
    Indent();
    code_ += "var _v = try verifier.visitTable(at: position)";
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;
      const auto offset = NumToString(field.value.offset);

      code_.SetValue("FIELDVAR", namer_.Variable(field));
      code_.SetValue("VALUETYPE", GenerateVerifierType(field));
      code_.SetValue("OFFSET", namer_.Field(field));
      code_.SetValue("ISREQUIRED", field.IsRequired() ? "true" : "false");

      if (IsUnion(field.value.type)) {
        GenerateUnionTypeVerifier(field);
        continue;
      }

      code_ +=
          "try _v.visit(field: {{TABLEOFFSET}}.{{OFFSET}}.p, fieldName: "
          "\"{{FIELDVAR}}\", required: {{ISREQUIRED}}, type: "
          "{{VALUETYPE}}.self)";
    }
    code_ += "_v.finish()";
    Outdent();
    code_ += "}";
  }

  void GenerateUnionTypeVerifier(const FieldDef &field) {
    const auto is_vector =
        IsVector(field.value.type) || IsArray(field.value.type);
    if (field.value.type.base_type == BASE_TYPE_UTYPE ||
        (is_vector &&
         field.value.type.VectorType().base_type == BASE_TYPE_UTYPE))
      return;
    EnumDef &union_def = *field.value.type.enum_def;
    code_.SetValue("VALUETYPE", namer_.NamespacedType(union_def));
    code_.SetValue("FUNCTION_NAME", is_vector ? "visitUnionVector" : "visit");
    code_ +=
        "try _v.{{FUNCTION_NAME}}(unionKey: {{TABLEOFFSET}}.{{OFFSET}}Type.p, "
        "unionField: {{TABLEOFFSET}}.{{OFFSET}}.p, unionKeyName: "
        "\"{{FIELDVAR}}Type\", fieldName: \"{{FIELDVAR}}\", required: "
        "{{ISREQUIRED}}, completion: { (verifier, key: {{VALUETYPE}}, pos) in";
    Indent();
    code_ += "switch key {";
    for (auto it = union_def.Vals().begin(); it != union_def.Vals().end();
         ++it) {
      const auto &ev = **it;
      const auto type = GenType(ev.union_type);
      code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
      code_.SetValue("VALUETYPE", type);
      code_ += "case .{{KEY}}:";
      Indent();
      if (ev.union_type.base_type == BASE_TYPE_NONE) {
        code_ += "break // NOTE - SWIFT doesnt support none";
      } else if (ev.union_type.base_type == BASE_TYPE_STRING) {
        code_ +=
            "try ForwardOffset<String>.verify(&verifier, at: pos, of: "
            "String.self)";
      } else {
        code_.SetValue("MAINTYPE", ev.union_type.struct_def->fixed
                                       ? type
                                       : "ForwardOffset<" + type + ">");
        code_ +=
            "try {{MAINTYPE}}.verify(&verifier, at: pos, of: "
            "{{VALUETYPE}}.self)";
      }
      Outdent();
    }
    code_ += "}";
    Outdent();
    code_ += "})";
  }

  std::string GenerateVerifierType(const FieldDef &field) {
    const auto type = field.value.type;
    const auto is_vector = IsVector(type) || IsArray(type);

    if (is_vector) {
      const auto vector_type = field.value.type.VectorType();
      return "ForwardOffset<Vector<" +
             GenerateNestedVerifierTypes(vector_type) + ", " +
             GenType(vector_type) + ">>";
    }

    return GenerateNestedVerifierTypes(field.value.type);
  }

  std::string GenerateNestedVerifierTypes(const Type &type) {
    const auto string_type = GenType(type);

    if (IsScalar(type.base_type)) { return string_type; }

    if (IsString(type)) { return "ForwardOffset<" + string_type + ">"; }

    if (type.struct_def && type.struct_def->fixed) { return string_type; }

    return "ForwardOffset<" + string_type + ">";
  }

  void GenByKeyFunctions(const FieldDef &key_field) {
    code_.SetValue("TYPE", GenType(key_field.value.type));
    code_ +=
        "{{ACCESS_TYPE}} func {{FIELDVAR}}By(key: {{TYPE}}) -> {{VALUETYPE}}? "
        "{ \\";
    code_ += GenOffset() +
             "return o == 0 ? nil : {{VALUETYPE}}.lookupByKey(vector: "
             "{{ACCESS}}.vector(at: o), key: key, fbb: {{ACCESS}}.bb) }";
  }

  void GenEnum(const EnumDef &enum_def) {
    if (enum_def.generated) return;
    const bool is_private_access = parser_.opts.swift_implementation_only ||
       enum_def.attributes.Lookup("private") != nullptr;
    code_.SetValue("ENUM_TYPE",
                   enum_def.is_union ? "UnionEnum" : "Enum, Verifiable");
    code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public");
    code_.SetValue("ENUM_NAME", namer_.NamespacedType(enum_def));
    code_.SetValue("BASE_TYPE", GenTypeBasic(enum_def.underlying_type, false));
    GenComment(enum_def.doc_comment);
    code_ +=
        "{{ACCESS_TYPE}} enum {{ENUM_NAME}}: {{BASE_TYPE}}, {{ENUM_TYPE}} {";
    Indent();
    code_ += "{{ACCESS_TYPE}} typealias T = {{BASE_TYPE}}";
    if (enum_def.is_union) {
      code_ += "";
      code_ += "{{ACCESS_TYPE}} init?(value: T) {";
      Indent();
      code_ += "self.init(rawValue: value)";
      Outdent();
      code_ += "}\n";
    }
    code_ +=
        "{{ACCESS_TYPE}} static var byteSize: Int { return "
        "MemoryLayout<{{BASE_TYPE}}>.size "
        "}";
    code_ +=
        "{{ACCESS_TYPE}} var value: {{BASE_TYPE}} { return self.rawValue }";
    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
      const auto &ev = **it;
      code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
      code_.SetValue("VALUE", enum_def.ToString(ev));
      GenComment(ev.doc_comment);
      code_ += "case {{KEY}} = {{VALUE}}";
    }
    code_ += "";
    AddMinOrMaxEnumValue(namer_.LegacySwiftVariant(*enum_def.MaxValue()),
                         "max");
    AddMinOrMaxEnumValue(namer_.LegacySwiftVariant(*enum_def.MinValue()),
                         "min");
    Outdent();
    code_ += "}\n";
    if (parser_.opts.gen_json_coders) EnumEncoder(enum_def);
    code_ += "";
    if (parser_.opts.generate_object_based_api && enum_def.is_union) {
      code_ += "{{ACCESS_TYPE}} struct {{ENUM_NAME}}Union {";
      Indent();
      code_ += "{{ACCESS_TYPE}} var type: {{ENUM_NAME}}";
      code_ += "{{ACCESS_TYPE}} var value: NativeObject?";
      code_ +=
          "{{ACCESS_TYPE}} init(_ v: NativeObject?, type: {{ENUM_NAME}}) {";
      Indent();
      code_ += "self.type = type";
      code_ += "self.value = v";
      Outdent();
      code_ += "}";
      code_ +=
          "{{ACCESS_TYPE}} func pack(builder: inout FlatBufferBuilder) -> "
          "Offset {";
      Indent();
      BuildUnionEnumSwitchCaseWritter(enum_def);
      Outdent();
      code_ += "}";
      Outdent();
      code_ += "}";
    }
  }

  void EnumEncoder(const EnumDef &enum_def) {
    code_ += "extension {{ENUM_NAME}}: Encodable {";
    Indent();
    code_ += "{{ACCESS_TYPE}} func encode(to encoder: Encoder) throws {";
    Indent();
    code_ += "var container = encoder.singleValueContainer()";
    code_ += "switch self {";
    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
      const auto &ev = **it;
      code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
      code_.SetValue("RAWKEY", ev.name);
      code_ += "case .{{KEY}}: try container.encode(\"{{RAWKEY}}\")";
    }
    code_ += "}";
    Outdent();
    code_ += "}";
    Outdent();
    code_ += "}";
  }

  // MARK: - Object API

  void GenerateObjectAPIExtensionHeader(std::string type_name) {
    code_ += "\n";
    code_ += "{{ACCESS_TYPE}} mutating func unpack() -> " + type_name + " {";
    Indent();
    code_ += "return " + type_name + "(&self)";
    Outdent();
    code_ += "}";
    code_ +=
        "{{ACCESS_TYPE}} static func pack(_ builder: inout FlatBufferBuilder, "
        "obj: "
        "inout " +
        type_name + "?) -> Offset {";
    Indent();
    code_ += "guard var obj = obj else { return Offset() }";
    code_ += "return pack(&builder, obj: &obj)";
    Outdent();
    code_ += "}";
    code_ += "";
    code_ +=
        "{{ACCESS_TYPE}} static func pack(_ builder: inout FlatBufferBuilder, "
        "obj: "
        "inout " +
        type_name + ") -> Offset {";
    Indent();
  }

  void GenerateObjectAPIStructConstructor(const StructDef &struct_def) {
    code_ +=
        "{{ACCESS_TYPE}} init(_ _t: inout {{STRUCTNAME}}" + Mutable() + ") {";
    Indent();
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;

      const auto type = GenType(field.value.type);
      code_.SetValue("FIELDVAR", namer_.Variable(field));
      if (IsStruct(field.value.type)) {
        code_ += "var _v{{FIELDVAR}} = _t.{{FIELDVAR}}";
        code_ += "_{{FIELDVAR}} = _v{{FIELDVAR}}.unpack()";
        continue;
      }
      std::string is_enum = IsEnum(field.value.type) ? ".value" : "";
      code_ += "_{{FIELDVAR}} = _t.{{FIELDVAR}}" + is_enum;
    }
    Outdent();
    code_ += "}\n";
  }

  void GenObjectAPI(const StructDef &struct_def) {
    code_ += "{{ACCESS_TYPE}} class " +
             namer_.NamespacedObjectType(struct_def) + ": NativeObject {\n";
    std::vector<std::string> buffer_constructor;
    std::vector<std::string> base_constructor;
    Indent();
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;
      BuildObjectAPIConstructorBody(field, struct_def.fixed, buffer_constructor,
                                    base_constructor);
    }
    code_ += "";
    BuildObjectConstructor(buffer_constructor,
                           "_ _t: inout " + namer_.NamespacedType(struct_def));
    BuildObjectConstructor(base_constructor);
    if (!struct_def.fixed)
      code_ +=
          "{{ACCESS_TYPE}} func serialize() -> ByteBuffer { return "
          "serialize(type: "
          "{{STRUCTNAME}}.self) }\n";
    Outdent();
    code_ += "}";
  }

  void GenerateObjectAPITableExtension(const StructDef &struct_def) {
    GenerateObjectAPIExtensionHeader(namer_.NamespacedObjectType(struct_def));
    std::vector<std::string> unpack_body;
    std::string builder = ", &builder)";
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto &field = **it;
      if (field.deprecated) continue;
      const auto field_var = namer_.Variable(field);
      const auto field_field = namer_.Field(field);
      const auto field_method = namer_.Method(field);
      const auto type = GenType(field.value.type);
      std::string check_if_vector =
          (IsVector(field.value.type) || IsArray(field.value.type))
              ? "VectorOf("
              : "(";
      std::string body = "add" + check_if_vector + field_method + ": ";
      switch (field.value.type.base_type) {
        case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
        case BASE_TYPE_VECTOR: {
          GenerateVectorObjectAPITableExtension(field);
          unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + field_var +
                                builder);
          break;
        }
        case BASE_TYPE_UNION: {
          code_ += "let __" + field_var + " = obj." + field_var +
                   "?.pack(builder: &builder) ?? Offset()";
          unpack_body.push_back("if let o = obj." + field_var + "?.type {");
          unpack_body.push_back("  {{STRUCTNAME}}.add(" + field_var +
                                "Type: o" + builder);
          unpack_body.push_back("  {{STRUCTNAME}}." + body + "__" + field_var +
                                builder);
          unpack_body.push_back("}\n");
          break;
        }
        case BASE_TYPE_STRUCT: {
          if (field.value.type.struct_def &&
              field.value.type.struct_def->fixed) {
            // This is a Struct (IsStruct), not a table. We create
            // a native swift object in this case.
            std::string code;
            GenerateStructArgs(*field.value.type.struct_def, &code, "", "",
                               "$0", true);
            code = code.substr(0, code.size() - 2);
            unpack_body.push_back("{{STRUCTNAME}}." + body + "obj." +
                                  field_field + builder);
          } else {
            code_ += "let __" + field_var + " = " + type +
                     ".pack(&builder, obj: &obj." + field_field + ")";
            unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + field_var +
                                  builder);
          }
          break;
        }
        case BASE_TYPE_STRING: {
          unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + field_var +
                                builder);
          if (field.IsRequired()) {
            code_ += "let __" + field_var + " = builder.create(string: obj." +
                     field_field + ")";
          } else {
            BuildingOptionalObjects(field_field, "builder.create(string: s)");
          }
          break;
        }
        case BASE_TYPE_UTYPE: break;
        default:
          unpack_body.push_back("{{STRUCTNAME}}." + body + "obj." +
                                field_field + builder);
      }
    }
    code_ += "let __root = {{STRUCTNAME}}.start{{SHORT_STRUCTNAME}}(&builder)";
    for (auto it = unpack_body.begin(); it < unpack_body.end(); it++)
      code_ += *it;
    code_ +=
        "return {{STRUCTNAME}}.end{{SHORT_STRUCTNAME}}(&builder, start: "
        "__root)";
    Outdent();
    code_ += "}";
  }

  void GenerateVectorObjectAPITableExtension(const FieldDef &field_def) {
    const Type &field_type = field_def.value.type;
    const auto type = GenType(field_type);
    const auto var = namer_.Variable(field_def);
    const auto field = namer_.Field(field_def);

    const auto vectortype = field_type.VectorType();
    switch (vectortype.base_type) {
      case BASE_TYPE_UNION: {
        code_ += "var __" + var + "__: [Offset] = []";
        code_ += "for i in obj." + var + " {";
        Indent();
        code_ += "guard let off = i?.pack(builder: &builder) else { continue }";
        code_ += "__" + var + "__.append(off)";
        Outdent();
        code_ += "}";
        code_ += "let __" + var + " = builder.createVector(ofOffsets: __" +
                 var + "__)";
        code_ += "let __" + var + "Type = builder.createVector(obj." + field +
                 ".compactMap { $0?.type })";
        break;
      }
      case BASE_TYPE_UTYPE: break;
      case BASE_TYPE_STRUCT: {
        if (field_type.struct_def && !field_type.struct_def->fixed) {
          code_ += "var __" + var + "__: [Offset] = []";
          code_ += "for var i in obj." + var + " {";
          Indent();
          code_ +=
              "__" + var + "__.append(" + type + ".pack(&builder, obj: &i))";
          Outdent();
          code_ += "}";
          code_ += "let __" + var + " = builder.createVector(ofOffsets: __" +
                   var + "__)";
        } else {
          code_ += "{{STRUCTNAME}}." + namer_.Method("start_vector_of", var) +
                   "(obj." + field + ".count, in: &builder)";
          std::string code;
          GenerateStructArgs(*field_type.struct_def, &code, "", "", "_o", true);
          code = code.substr(0, code.size() - 2);
          code_ += "for i in obj." + field + " {";
          Indent();
          code_ += "guard let _o = i else { continue }";
          code_ += "builder.create(struct: _o)";
          Outdent();
          code_ += "}";
          code_ += "let __" + var + " = builder.endVector(len: obj." + field +
                   ".count)";
        }
        break;
      }
      case BASE_TYPE_STRING: {
        code_ += "let __" + var + " = builder.createVector(ofStrings: obj." +
                 var + ".compactMap({ $0 }) )";
        break;
      }
      default: {
        code_ += "let __" + var + " = builder.createVector(obj." + field + ")";
        break;
      }
    }
  }

  void BuildingOptionalObjects(const std::string &var,
                               const std::string &body_front) {
    code_ += "let __" + var + ": Offset";
    code_ += "if let s = obj." + var + " {";
    Indent();
    code_ += "__" + var + " = " + body_front;
    Outdent();
    code_ += "} else {";
    Indent();
    code_ += "__" + var + " = Offset()";
    Outdent();
    code_ += "}";
    code_ += "";
  }

  void BuildObjectConstructor(const std::vector<std::string> &body,
                              const std::string &header = "") {
    code_.SetValue("HEADER", header);
    code_ += "{{ACCESS_TYPE}} init({{HEADER}}) {";
    Indent();
    for (auto it = body.begin(); it < body.end(); ++it) code_ += *it;
    Outdent();
    code_ += "}\n";
  }

  void BuildObjectAPIConstructorBody(
      const FieldDef &field, bool is_fixed,
      std::vector<std::string> &buffer_constructor,
      std::vector<std::string> &base_constructor) {
    const auto field_field = namer_.Field(field);
    const auto field_var = namer_.Variable(field);
    const auto type = GenType(field.value.type);
    code_.SetValue("FIELDVAR", field_field);
    code_.SetValue("VALUETYPE", type);
    std::string is_required = field.IsRequired() ? "" : "?";

    switch (field.value.type.base_type) {
      case BASE_TYPE_STRUCT: {
        const auto objtype = GenType(field.value.type, true);
        code_.SetValue("VALUETYPE", objtype);
        const auto optional =
            (field.value.type.struct_def && field.value.type.struct_def->fixed);
        std::string question_mark =
            (field.IsRequired() || (optional && is_fixed) ? "" : "?");

        code_ +=
            "{{ACCESS_TYPE}} var {{FIELDVAR}}: {{VALUETYPE}}" + question_mark;
        base_constructor.push_back("" + field_var + " = " + objtype + "()");

        if (field.value.type.struct_def->fixed) {
          buffer_constructor.push_back("" + field_var + " = _t." + field_field);
        } else {
          buffer_constructor.push_back("var __" + field_var + " = _t." +
                                       field_field);
          buffer_constructor.push_back(
              "" + field_var + " = __" + field_var +
              (field.IsRequired() ? "!" : question_mark) + ".unpack()");
        }
        break;
      }
      case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
      case BASE_TYPE_VECTOR: {
        BuildObjectAPIConstructorBodyVectors(field, buffer_constructor,
                                             base_constructor, "    ");
        break;
      }
      case BASE_TYPE_STRING: {
        code_ += "{{ACCESS_TYPE}} var {{FIELDVAR}}: String" + is_required;
        buffer_constructor.push_back(field_var + " = _t." + field_field);

        if (field.IsRequired()) {
          std::string default_value =
              field.IsDefault() ? SwiftConstant(field) : "";
          base_constructor.push_back(field_var + " = \"" + default_value +
                                     "\"");
          break;
        }
        if (field.IsDefault() && !field.IsRequired()) {
          std::string value = field.IsDefault() ? SwiftConstant(field) : "nil";
          base_constructor.push_back(field_var + " = \"" + value + "\"");
        }
        break;
      }
      case BASE_TYPE_UTYPE: break;
      case BASE_TYPE_UNION: {
        BuildUnionEnumSwitchCase(*field.value.type.enum_def, field_var,
                                 buffer_constructor);
        break;
      }
      default: {
        buffer_constructor.push_back(field_var + " = _t." + field_field);
        std::string nullable = field.IsOptional() ? "?" : "";
        if (IsScalar(field.value.type.base_type) &&
            !IsBool(field.value.type.base_type) && !IsEnum(field.value.type)) {
          code_ += "{{ACCESS_TYPE}} var {{FIELDVAR}}: {{VALUETYPE}}" + nullable;
          if (!field.IsOptional())
            base_constructor.push_back(field_var + " = " +
                                       SwiftConstant(field));
          break;
        }

        if (IsEnum(field.value.type)) {
          const auto default_value = IsEnum(field.value.type)
                                         ? GenEnumDefaultValue(field)
                                         : SwiftConstant(field);
          code_ += "{{ACCESS_TYPE}} var {{FIELDVAR}}: {{VALUETYPE}}";
          base_constructor.push_back(field_var + " = " + default_value);
          break;
        }

        if (IsBool(field.value.type.base_type)) {
          code_ += "{{ACCESS_TYPE}} var {{FIELDVAR}}: Bool" + nullable;
          if (!field.IsOptional())
            base_constructor.push_back(field_var + " = " + SwiftConstant(field));
        }
      }
    }
  }

  void BuildObjectAPIConstructorBodyVectors(
      const FieldDef &field, std::vector<std::string> &buffer_constructor,
      std::vector<std::string> &base_constructor,
      const std::string &indentation) {
    const auto vectortype = field.value.type.VectorType();
    const auto field_var = namer_.Field(field);
    const auto field_field = namer_.Field(field);

    if (vectortype.base_type != BASE_TYPE_UTYPE) {
      buffer_constructor.push_back(field_var + " = []");
      buffer_constructor.push_back("for index in 0..<_t." + field_field +
                                   "Count {");
      base_constructor.push_back(field_var + " = []");
    }

    switch (vectortype.base_type) {
      case BASE_TYPE_STRUCT: {
        code_.SetValue("VALUETYPE", GenType(vectortype, true));
        code_ += "{{ACCESS_TYPE}} var {{FIELDVAR}}: [{{VALUETYPE}}?]";
        if (!vectortype.struct_def->fixed) {
          buffer_constructor.push_back(indentation + "var __v_ = _t." +
                                       field_field + "(at: index)");
          buffer_constructor.push_back(indentation + field_var +
                                       ".append(__v_?.unpack())");
        } else {
          buffer_constructor.push_back(indentation + field_var + ".append(_t." +
                                       field_var + "(at: index))");
        }
        break;
      }
      case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
      case BASE_TYPE_VECTOR: {
        break;
      }
      case BASE_TYPE_UNION: {
        BuildUnionEnumSwitchCase(*field.value.type.enum_def, field_var,
                                 buffer_constructor, indentation, true);
        break;
      }
      case BASE_TYPE_UTYPE: break;
      default: {
        code_.SetValue(
            "VALUETYPE",
            (IsString(vectortype) ? "String?" : GenType(vectortype)));
        code_ += "{{ACCESS_TYPE}} var {{FIELDVAR}}: [{{VALUETYPE}}]";

        if (IsEnum(vectortype) && vectortype.base_type != BASE_TYPE_UNION) {
          const auto default_value = IsEnum(field.value.type)
                                         ? GenEnumDefaultValue(field)
                                         : SwiftConstant(field);
          buffer_constructor.push_back(indentation + field_var + ".append(_t." +
                                       field_field + "(at: index)!)");
          break;
        }
        buffer_constructor.push_back(indentation + field_var + ".append(_t." +
                                     field_field + "(at: index))");
        break;
      }
    }
    if (vectortype.base_type != BASE_TYPE_UTYPE)
      buffer_constructor.push_back("}");
  }

  void BuildUnionEnumSwitchCaseWritter(const EnumDef &ed) {
    code_ += "switch type {";
    for (auto it = ed.Vals().begin(); it < ed.Vals().end(); ++it) {
      const auto ev = **it;
      const auto variant = namer_.LegacySwiftVariant(ev);
      const auto type = GenType(ev.union_type);
      const auto is_struct = IsStruct(ev.union_type) ? type + Mutable() : type;
      if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; }
      code_ += "case ." + variant + ":";
      Indent();
      code_ += "var __obj = value as? " + GenType(ev.union_type, true);
      code_ += "return " + is_struct + ".pack(&builder, obj: &__obj)";
      Outdent();
    }
    code_ += "default: return Offset()";
    code_ += "}";
  }

  void BuildUnionEnumSwitchCase(const EnumDef &ed, const std::string &field,
                                std::vector<std::string> &buffer_constructor,
                                const std::string &indentation = "",
                                const bool is_vector = false) {
    const auto ns_type = namer_.NamespacedType(ed);
    code_.SetValue("VALUETYPE", ns_type);
    code_ += "{{ACCESS_TYPE}} var {{FIELDVAR}}: \\";
    code_ += is_vector ? "[{{VALUETYPE}}Union?]" : "{{VALUETYPE}}Union?";

    const auto vector_reader = is_vector ? "(at: index" : "";
    buffer_constructor.push_back(indentation + "switch _t." + field + "Type" +
                                 vector_reader + (is_vector ? ")" : "") + " {");

    for (auto it = ed.Vals().begin(); it < ed.Vals().end(); ++it) {
      const auto ev = **it;
      const auto variant = namer_.LegacySwiftVariant(ev);
      if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; }
      const auto type = IsStruct(ev.union_type)
                            ? GenType(ev.union_type) + Mutable()
                            : GenType(ev.union_type);
      buffer_constructor.push_back(indentation + "case ." + variant + ":");
      buffer_constructor.push_back(
          indentation + "  var _v = _t." + field + (is_vector ? "" : "(") +
          vector_reader + (is_vector ? ", " : "") + "type: " + type + ".self)");
      const auto constructor =
          ns_type + "Union(_v?.unpack(), type: ." + variant + ")";
      buffer_constructor.push_back(
          indentation + "  " + field +
          (is_vector ? ".append(" + constructor + ")" : " = " + constructor));
    }
    buffer_constructor.push_back(indentation + "default: break");
    buffer_constructor.push_back(indentation + "}");
  }

  void AddMinOrMaxEnumValue(const std::string &str, const std::string &type) {
    const auto current_value = str;
    code_.SetValue(type, current_value);
    code_ += "{{ACCESS_TYPE}} static var " + type +
             ": {{ENUM_NAME}} { return .{{" + type + "}} }";
  }

  void GenLookup(const FieldDef &key_field, const std::string &struct_type) {
    code_.SetValue("STRUCTTYPE", struct_type);
    code_.SetValue("OFFSET", NumToString(key_field.value.offset));
    std::string offset_reader =
        "Table.offset(Int32(fbb.capacity) - tableOffset, vOffset: {{OFFSET}}, "
        "fbb: fbb)";

    code_.SetValue("TYPE", GenType(key_field.value.type));
    code_ +=
        "fileprivate static func lookupByKey(vector: Int32, key: {{TYPE}}, "
        "fbb: "
        "ByteBuffer) -> {{STRUCTTYPE}}? {";
    Indent();
    if (IsString(key_field.value.type))
      code_ += "let key = key.utf8.map { $0 }";
    code_ += "var span = fbb.read(def: Int32.self, position: Int(vector - 4))";
    code_ += "var start: Int32 = 0";
    code_ += "while span != 0 {";
    Indent();
    code_ += "var middle = span / 2";
    code_ +=
        "let tableOffset = Table.indirect(vector + 4 * (start + middle), fbb)";
    if (IsString(key_field.value.type)) {
      code_ += "let comp = Table.compare(" + offset_reader + ", key, fbb: fbb)";
    } else {
      code_ += "let comp = fbb.read(def: {{TYPE}}.self, position: Int(" +
               offset_reader + "))";
    }

    code_ += "if comp > 0 {";
    Indent();
    code_ += "span = middle";
    Outdent();
    code_ += "} else if comp < 0 {";
    Indent();
    code_ += "middle += 1";
    code_ += "start += middle";
    code_ += "span -= middle";
    Outdent();
    code_ += "} else {";
    Indent();
    code_ += "return {{STRUCTTYPE}}(fbb, o: tableOffset)";
    Outdent();
    code_ += "}";
    Outdent();
    code_ += "}";
    code_ += "return nil";
    Outdent();
    code_ += "}";
  }

  inline void GenPadding(const FieldDef &field, int *id) {
    if (field.padding) {
      for (int i = 0; i < 4; i++) {
        if (static_cast<int>(field.padding) & (1 << i)) {
          const auto bits = (1 << i) * 8;
          code_ += "private let padding" + NumToString((*id)++) + "__: UInt" +
                   NumToString(bits) + " = 0";
        }
      }
      FLATBUFFERS_ASSERT(!(field.padding & ~0xF));
    }
  }

  void GenComment(const std::vector<std::string> &dc) {
    if (dc.begin() == dc.end()) {
      // Don't output empty comment blocks with 0 lines of comment content.
      return;
    }
    for (auto it = dc.begin(); it != dc.end(); ++it) { code_ += "/// " + *it; }
  }

  std::string GenOffset() {
    return "let o = {{ACCESS}}.offset({{TABLEOFFSET}}.{{OFFSET}}.v); ";
  }

  std::string GenReaderMainBody(const std::string &optional = "") {
    return "{{ACCESS_TYPE}} var {{FIELDVAR}}: {{VALUETYPE}}" + optional + " { ";
  }

  std::string GenReader(const std::string &type,
                        const std::string &at = "{{OFFSET}}") {
    return "{{ACCESS}}.readBuffer(of: {{" + type + "}}.self, at: " + at + ")";
  }

  std::string GenConstructor(const std::string &offset) {
    return "{{VALUETYPE}}({{ACCESS}}.bb, o: " + offset + ") }";
  }

  std::string GenMutate(const std::string &offset,
                        const std::string &get_offset, bool isRaw = false) {
    return "@discardableResult {{ACCESS_TYPE}} func mutate({{FIELDVAR}}: "
           "{{VALUETYPE}}) -> Bool {" +
           get_offset + " return {{ACCESS}}.mutate({{FIELDVAR}}" +
           (isRaw ? ".rawValue" : "") + ", index: " + offset + ") }";
  }

  std::string GenMutateArray() {
    return "{{ACCESS_TYPE}} func mutate({{FIELDVAR}}: {{VALUETYPE}}, at "
           "index: Int32) -> Bool { " +
           GenOffset() +
           "return {{ACCESS}}.directMutate({{FIELDVAR}}, index: "
           "{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }";
  }

  std::string GenEnumDefaultValue(const FieldDef &field) {
    const auto &value = field.value;
    FLATBUFFERS_ASSERT(value.type.enum_def);
    const auto &enum_def = *value.type.enum_def;
    // Vector of enum defaults are always "[]" which never works.
    const std::string constant = IsVector(value.type) ? "0" : value.constant;
    const auto enum_val = enum_def.FindByValue(constant);
    if (enum_val) {
      return "." + namer_.LegacySwiftVariant(*enum_val);
    } else {
      const auto &ev = **enum_def.Vals().begin();
      return "." + namer_.LegacySwiftVariant(ev);
    }
  }

  std::string SwiftConstant(const FieldDef& field) {
    const auto default_value =
        StringIsFlatbufferNan(field.value.constant) ? ".nan" :
        StringIsFlatbufferPositiveInfinity(field.value.constant) ? ".infinity" :
        StringIsFlatbufferNegativeInfinity(field.value.constant) ? "-.infinity" :
        IsBool(field.value.type.base_type) ? ("0" == field.value.constant ? "false" : "true") :
        field.value.constant;
    return default_value;
 }

  std::string GenEnumConstructor(const std::string &at) {
    return "{{VALUETYPE}}(rawValue: " + GenReader("BASEVALUE", at) + ") ";
  }

  std::string ValidateFunc() {
    return "static func validateVersion() { FlatBuffersVersion_22_11_22() }";
  }

  std::string GenType(const Type &type,
                      const bool should_consider_suffix = false) const {
    return IsScalar(type.base_type) ? GenTypeBasic(type)
           : IsArray(type)          ? GenType(type.VectorType())
                           : GenTypePointer(type, should_consider_suffix);
  }

  std::string GenTypePointer(const Type &type,
                             const bool should_consider_suffix) const {
    switch (type.base_type) {
      case BASE_TYPE_STRING: return "String";
      case BASE_TYPE_VECTOR: return GenType(type.VectorType());
      case BASE_TYPE_STRUCT: {
        const auto &sd = *type.struct_def;
        if (should_consider_suffix && !sd.fixed) {
          return namer_.NamespacedObjectType(sd);
        }
        return namer_.NamespacedType(sd);
      }
      case BASE_TYPE_UNION:
      default: return "FlatbuffersInitializable";
    }
  }

  std::string GenTypeBasic(const Type &type) const {
    return GenTypeBasic(type, true);
  }

  void Indent() { code_.IncrementIdentLevel(); }

  void Outdent() { code_.DecrementIdentLevel(); }

  std::string GenTypeBasic(const Type &type, bool can_override) const {
    // clang-format off
    static const char * const swift_type[] = {
      #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
              CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE, STYPE) \
        #STYPE,
        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
      #undef FLATBUFFERS_TD
    };
    // clang-format on
    if (can_override) {
      if (type.enum_def) return namer_.NamespacedType(*type.enum_def);
      if (type.base_type == BASE_TYPE_BOOL) return "Bool";
    }
    return swift_type[static_cast<int>(type.base_type)];
  }

  std::string Mutable() const { return "_Mutable"; }

  IdlNamer namer_;
};
}  // namespace swift
bool GenerateSwift(const Parser &parser, const std::string &path,
                   const std::string &file_name) {
  swift::SwiftGenerator generator(parser, path, file_name);
  return generator.generate();
}
}  // namespace flatbuffers
