diff --git a/src/idl_gen_swift.cpp b/src/idl_gen_swift.cpp
new file mode 100644
index 0000000..c377e9f
--- /dev/null
+++ b/src/idl_gen_swift.cpp
@@ -0,0 +1,1484 @@
+/*
+ * 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"
+
+namespace flatbuffers {
+
+namespace swift {
+
+inline std::string GenIndirect(const std::string &reading) {
+  return "{{ACCESS}}.indirect(" + reading + ")";
+}
+
+inline std::string GenArrayMainBody(const std::string &optional) {
+  return "{{ACCESS_TYPE}} func {{VALUENAME}}(at index: Int32) -> "
+         "{{VALUETYPE}}" +
+         optional + " { ";
+}
+
+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") {
+    namespace_depth = 0;
+    code_.SetPadding("    ");
+    static const char *const keywords[] = {
+      "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",
+      nullptr,
+    };
+    for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
+  }
+
+  bool generate() {
+    code_.Clear();
+    code_.SetValue("ACCESS", "_accessor");
+    code_.SetValue("TABLEOFFSET", "VTOFFSET");
+    code_ += "// " + std::string(FlatBuffersGeneratedWarning());
+    code_ += "// swiftlint:disable all\n";
+    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);
+        if (parser_.opts.generate_object_based_api) {
+          GenObjectAPI(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) {
+        GenStructWriter(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";
+  }
+
+  // Generates the create function for swift
+  void GenStructWriter(const StructDef &struct_def) {
+    auto is_private_access = struct_def.attributes.Lookup("private");
+    code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public");
+    code_.SetValue("STRUCTNAME", NameWrappedInNameSpace(struct_def));
+    code_.SetValue("SHORT_STRUCTNAME", Name(struct_def));
+    code_ += "extension {{STRUCTNAME}} {";
+    Indent();
+    code_ += "@discardableResult";
+    code_ +=
+        "{{ACCESS_TYPE}} static func create{{SHORT_STRUCTNAME}}(builder: inout "
+        "FlatBufferBuilder, \\";
+    std::string func_header = "";
+    GenerateStructArgs(struct_def, &func_header, "", "");
+    code_ += func_header.substr(0, func_header.size() - 2) + "\\";
+    code_ += ") -> Offset<UOffset> {";
+    Indent();
+    code_ +=
+        "builder.createStructOf(size: {{STRUCTNAME}}.size, alignment: "
+        "{{STRUCTNAME}}.alignment)";
+    GenerateStructBody(struct_def, "");
+    code_ += "return builder.endStruct()";
+    Outdent();
+    code_ += "}\n";
+    Outdent();
+    code_ += "}\n";
+  }
+
+  void GenerateStructBody(const StructDef &struct_def,
+                          const std::string &nameprefix, int offset = 0) {
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      auto name = nameprefix + Name(field);
+      const auto &field_type = field.value.type;
+      auto type = GenTypeBasic(field_type, false);
+      if (IsStruct(field.value.type)) {
+        GenerateStructBody(*field_type.struct_def, (nameprefix + field.name),
+                           static_cast<int>(field.value.offset));
+      } else {
+        auto off = NumToString(offset + field.value.offset);
+        code_ += "builder.reverseAdd(v: " + name +
+                 (field_type.enum_def ? ".rawValue" : "") +
+                 ", postion: " + off + ")";
+      }
+    }
+  }
+
+  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) {
+      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 {
+        auto name = Name(field);
+        auto type = GenType(field.value.type);
+        if (!is_obj_api) {
+          code += nameprefix + name + ": " + type;
+          if (!IsEnum(field.value.type)) {
+            code += " = ";
+            auto is_bool = IsBool(field.value.type.base_type);
+            auto constant =
+                is_bool ? ("0" == field.value.constant ? "false" : "true")
+                        : field.value.constant;
+            code += constant;
+          }
+          code += ", ";
+          continue;
+        }
+        code +=
+            nameprefix + name + ": " + obj_api_named + object_name + "." + name;
+        code += ", ";
+      }
+    }
+  }
+
+  void GenObjectHeader(const StructDef &struct_def) {
+    GenComment(struct_def.doc_comment);
+    code_.SetValue("SHORT_STRUCTNAME", Name(struct_def));
+    code_.SetValue("STRUCTNAME", NameWrappedInNameSpace(struct_def));
+    code_.SetValue("PROTOCOL",
+                   struct_def.fixed ? "Readable" : "FlatBufferObject");
+    code_.SetValue("OBJECTTYPE", struct_def.fixed ? "Struct" : "Table");
+    code_ += "{{ACCESS_TYPE}} struct {{STRUCTNAME}}: {{PROTOCOL}}\\";
+    if (!struct_def.fixed && parser_.opts.generate_object_based_api)
+      code_ += ", ObjectAPI\\";
+    code_ += " {\n";
+    Indent();
+    code_ += ValidateFunc();
+    code_ +=
+        "{{ACCESS_TYPE}} var __buffer: ByteBuffer! { return {{ACCESS}}.bb }";
+    code_ += "private var {{ACCESS}}: {{OBJECTTYPE}}\n";
+    if (struct_def.fixed) {
+      code_.SetValue("BYTESIZE", NumToString(struct_def.bytesize));
+      code_.SetValue("MINALIGN", NumToString(struct_def.minalign));
+      code_ += "{{ACCESS_TYPE}} static var size = {{BYTESIZE}}";
+      code_ += "{{ACCESS_TYPE}} static var alignment = {{MINALIGN}}";
+    } else {
+      if (parser_.file_identifier_.length()) {
+        code_.SetValue("FILENAME", parser_.file_identifier_);
+        code_ +=
+            "{{ACCESS_TYPE}} static func finish(_ fbb: inout "
+            "FlatBufferBuilder, end: "
+            "Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, "
+            "fileId: "
+            "\"{{FILENAME}}\", 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_ += "";
+  }
+
+  // Generates the reader for swift
+  void GenTable(const StructDef &struct_def) {
+    auto is_private_access = struct_def.attributes.Lookup("private");
+    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);
+    Outdent();
+    code_ += "}\n";
+  }
+
+  // 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", Name(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 GenerateObjectAPIExtensionHeader() {
+    code_ += "\n";
+    code_ += "{{ACCESS_TYPE}} mutating func unpack() -> " +
+             ObjectAPIName("{{STRUCTNAME}}") + " {";
+    Indent();
+    code_ += "return " + ObjectAPIName("{{STRUCTNAME}}") + "(&self)";
+    Outdent();
+    code_ += "}";
+    code_ +=
+        "{{ACCESS_TYPE}} static func pack(_ builder: inout FlatBufferBuilder, "
+        "obj: "
+        "inout " +
+        ObjectAPIName("{{STRUCTNAME}}") + "?) -> Offset<UOffset> {";
+    Indent();
+    code_ += "guard var obj = obj else { return Offset<UOffset>() }";
+    code_ += "return pack(&builder, obj: &obj)";
+    Outdent();
+    code_ += "}";
+    code_ += "";
+    code_ +=
+        "{{ACCESS_TYPE}} static func pack(_ builder: inout FlatBufferBuilder, "
+        "obj: "
+        "inout " +
+        ObjectAPIName("{{STRUCTNAME}}") + ") -> Offset<UOffset> {";
+    Indent();
+  }
+
+  void GenerateObjectAPIStructExtension(const StructDef &struct_def) {
+    GenerateObjectAPIExtensionHeader();
+    std::string code;
+    GenerateStructArgs(struct_def, &code, "", "", "obj", true);
+    code_ += "return create{{SHORT_STRUCTNAME}}(builder: &builder, \\";
+    code_ += code.substr(0, code.size() - 2) + "\\";
+    code_ += ")";
+    Outdent();
+    code_ += "}";
+  }
+
+  void GenTableReader(const StructDef &struct_def) {
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      GenTableReaderFields(field);
+    }
+  }
+
+  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;
+    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.required)
+        require_fields.push_back(NumToString(field.value.offset));
+
+      GenTableWriterFields(field, &create_func_body, &create_func_header,
+                           should_generate_create);
+    }
+    code_ +=
+        "{{ACCESS_TYPE}} static func end{{SHORT_STRUCTNAME}}(_ fbb: inout "
+        "FlatBufferBuilder, "
+        "start: "
+        "UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(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<UOffset> {";
+      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("VALUENAME", NameWrappedInNameSpace(struct_def));
+      code_.SetValue("SHORT_VALUENAME", Name(struct_def));
+      code_.SetValue("VOFFSET", NumToString(key_field->value.offset));
+
+      code_ +=
+          "{{ACCESS_TYPE}} static func "
+          "sortVectorOf{{SHORT_VALUENAME}}(offsets:[Offset<UOffset>], "
+          "_ fbb: inout FlatBufferBuilder) -> Offset<UOffset> {";
+      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);
+    }
+  }
+
+  void GenTableWriterFields(const FieldDef &field,
+                            std::vector<std::string> *create_body,
+                            std::vector<std::string> *create_header,
+                            bool &contains_structs) {
+    std::string builder_string = ", _ fbb: inout FlatBufferBuilder) { ";
+    auto &create_func_body = *create_body;
+    auto &create_func_header = *create_header;
+    auto name = Name(field);
+    auto type = GenType(field.value.type);
+    bool opt_scalar = field.optional && IsScalar(field.value.type.base_type);
+    auto nullable_type = opt_scalar ? type + "?" : type;
+    code_.SetValue("VALUENAME", name);
+    code_.SetValue("VALUETYPE", nullable_type);
+    code_.SetValue("OFFSET", name);
+    code_.SetValue("CONSTANT", field.value.constant);
+    std::string check_if_vector =
+        (IsVector(field.value.type) ||
+         IsArray(field.value.type))
+            ? "VectorOf("
+            : "(";
+    auto body = "add" + check_if_vector + name + ": ";
+    code_ += "{{ACCESS_TYPE}} static func " + body + "\\";
+
+    create_func_body.push_back("{{STRUCTNAME}}." + body + name + ", &fbb)");
+
+    if (IsScalar(field.value.type.base_type) &&
+        !IsBool(field.value.type.base_type)) {
+      std::string is_enum = IsEnum(field.value.type) ? ".rawValue" : "";
+      std::string optional_enum =
+          IsEnum(field.value.type) ? ("?" + is_enum) : "";
+      code_ +=
+          "{{VALUETYPE}}" + builder_string + "fbb.add(element: {{VALUENAME}}\\";
+
+      code_ += field.optional ? (optional_enum + "\\")
+                              : (is_enum + ", def: {{CONSTANT}}\\");
+
+      code_ += ", at: {{TABLEOFFSET}}.{{OFFSET}}.p) }";
+
+      auto default_value =
+          IsEnum(field.value.type)
+              ? (field.optional ? "nil" : GenEnumDefaultValue(field))
+              : field.value.constant;
+      create_func_header.push_back("" + name + ": " + nullable_type + " = " +
+                                   (field.optional ? "nil" : default_value));
+      return;
+    }
+
+    if (IsBool(field.value.type.base_type)) {
+      std::string default_value =
+          "0" == field.value.constant ? "false" : "true";
+
+      code_.SetValue("CONSTANT", default_value);
+      code_.SetValue("VALUETYPE", field.optional ? "Bool?" : "Bool");
+      code_ += "{{VALUETYPE}}" + builder_string +
+               "fbb.add(element: {{VALUENAME}},\\";
+      code_ += field.optional ? "\\" : " def: {{CONSTANT}},";
+      code_ += " at: {{TABLEOFFSET}}.{{OFFSET}}.p) }";
+      create_func_header.push_back(name + ": " + nullable_type + " = " +
+                                   (field.optional ? "nil" : default_value));
+      return;
+    }
+
+    if (IsStruct(field.value.type)) {
+      contains_structs = false;
+      auto struct_type = "Offset<UOffset>?";
+      auto camel_case_name = "structOf" + MakeCamel(name, true);
+      auto reader_type =
+          "fbb.add(structOffset: {{TABLEOFFSET}}.{{OFFSET}}.p) }";
+      auto create_struct = "guard {{VALUENAME}} != nil else { return }; ";
+      code_ += struct_type + builder_string + create_struct + reader_type;
+      return;
+    }
+
+    auto offset_type = IsString(field.value.type)
+                           ? "Offset<String>"
+                           : "Offset<UOffset>";
+    auto camel_case_name =
+        (IsVector(field.value.type) ||
+                 IsArray(field.value.type)
+             ? "vectorOf"
+             : "offsetOf") +
+        MakeCamel(name, true);
+    create_func_header.push_back(camel_case_name + " " + name + ": " +
+                                 offset_type + " = Offset()");
+    auto reader_type =
+        IsStruct(field.value.type) && field.value.type.struct_def->fixed
+            ? "structOffset: {{TABLEOFFSET}}.{{OFFSET}}.p) }"
+            : "offset: {{VALUENAME}}, at: {{TABLEOFFSET}}.{{OFFSET}}.p) }";
+    code_ += offset_type + builder_string + "fbb.add(" + reader_type;
+
+    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))) {
+      auto field_name = NameWrappedInNameSpace(*vectortype.struct_def);
+      code_ += "public static func startVectorOf" + MakeCamel(name, true) +
+               "(_ size: Int, in builder: inout "
+               "FlatBufferBuilder) {";
+      Indent();
+      code_ += "builder.startVectorOfStructs(count: size, size: " + field_name +
+               ".size, "
+               "alignment: " +
+               field_name + ".alignment)";
+      Outdent();
+      code_ += "}";
+    }
+  }
+
+  void GenTableReaderFields(const FieldDef &field) {
+    auto offset = NumToString(field.value.offset);
+    auto name = Name(field);
+    auto type = GenType(field.value.type);
+    code_.SetValue("VALUENAME", name);
+    code_.SetValue("VALUETYPE", type);
+    code_.SetValue("OFFSET", name);
+    code_.SetValue("CONSTANT", field.value.constant);
+    bool opt_scalar = field.optional && IsScalar(field.value.type.base_type);
+    std::string def_Val = opt_scalar ? "nil" : "{{CONSTANT}}";
+    std::string optional = opt_scalar ? "?" : "";
+    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 =
+          "0" == field.value.constant ? "false" : "true";
+      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)) {
+      auto default_value = field.optional ? "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;
+    }
+
+    std::string is_required = field.required ? "!" : "?";
+    auto required_reader = field.required ? "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 +
+               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:
+        code_.SetValue("VALUETYPE", GenType(field.value.type));
+        code_.SetValue("CONSTANT", "nil");
+        code_ += GenReaderMainBody(is_required) + GenOffset() +
+                 required_reader + "{{ACCESS}}.string(at: o) }";
+        code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}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, const_string);
+        break;
+      case BASE_TYPE_UNION:
+        code_.SetValue("CONSTANT", "nil");
+        code_ +=
+            "{{ACCESS_TYPE}} func {{VALUENAME}}<T: FlatBufferObject>(type: "
+            "T.Type) -> T" +
+            is_required + " { " + GenOffset() + required_reader +
+            "{{ACCESS}}.union(o) }";
+        break;
+      default: FLATBUFFERS_ASSERT(0);
+    }
+  }
+
+  void GenTableReaderVectorFields(const FieldDef &field,
+                                  const std::string &const_string) {
+    auto vectortype = field.value.type.VectorType();
+    code_.SetValue("SIZE", NumToString(InlineSize(vectortype)));
+    code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}Count: Int32 { " + GenOffset() +
+             const_string + "{{ACCESS}}.vector(count: o) }";
+    code_.SetValue("CONSTANT", IsScalar(vectortype.base_type) == true
+                                   ? field.value.constant
+                                   : "nil");
+    auto nullable = IsScalar(vectortype.base_type) == true ? "" : "?";
+    nullable = IsEnum(vectortype) == true ? "?" : nullable;
+    if (vectortype.base_type != BASE_TYPE_UNION) {
+      code_ += GenArrayMainBody(nullable) + GenOffset() + "\\";
+    } else {
+      code_ +=
+          "{{ACCESS_TYPE}} func {{VALUENAME}}<T: FlatBufferObject>(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", "Byte");
+    }
+    if (!IsEnum(vectortype))
+      code_ +=
+          const_string + (IsBool(vectortype.base_type) ? "0 != " : "") + "\\";
+
+    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 {{VALUENAME}}: [{{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_ += 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}})");
+      auto &sd = *field.value.type.struct_def;
+      auto &fields = sd.fields.vec;
+      for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
+        auto &key_field = **kit;
+        if (key_field.key) {
+          GenByKeyFunctions(key_field);
+          break;
+        }
+      }
+    }
+  }
+
+  void GenByKeyFunctions(const FieldDef &key_field) {
+    code_.SetValue("TYPE", GenType(key_field.value.type));
+    code_ +=
+        "{{ACCESS_TYPE}} func {{VALUENAME}}By(key: {{TYPE}}) -> {{VALUETYPE}}? "
+        "{ \\";
+    code_ += GenOffset() +
+             "return o == 0 ? nil : {{VALUETYPE}}.lookupByKey(vector: "
+             "{{ACCESS}}.vector(at: o), key: key, fbb: {{ACCESS}}.bb) }";
+  }
+
+  // Generates the reader for swift
+  void GenStructReader(const StructDef &struct_def) {
+    auto is_private_access = struct_def.attributes.Lookup("private");
+    code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public");
+
+    GenObjectHeader(struct_def);
+    for (auto it = struct_def.fields.vec.begin();
+         it != struct_def.fields.vec.end(); ++it) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      auto offset = NumToString(field.value.offset);
+      auto name = Name(field);
+      auto type = GenType(field.value.type);
+      code_.SetValue("VALUENAME", name);
+      code_.SetValue("VALUETYPE", type);
+      code_.SetValue("OFFSET", offset);
+      GenComment(field.doc_comment);
+      if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type)) {
+        code_ +=
+            GenReaderMainBody() + "return " + GenReader("VALUETYPE") + " }";
+        if (parser_.opts.mutable_buffer) code_ += GenMutate("{{OFFSET}}", "");
+      } 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));
+        code_ += GenReaderMainBody() + "return " +
+                 GenConstructor("{{ACCESS}}.postion + {{OFFSET}}");
+      }
+    }
+    if (parser_.opts.generate_object_based_api)
+      GenerateObjectAPIStructExtension(struct_def);
+    Outdent();
+    code_ += "}\n";
+  }
+
+  void GenEnum(const EnumDef &enum_def) {
+    if (enum_def.generated) return;
+    auto is_private_access = enum_def.attributes.Lookup("private");
+    code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public");
+    code_.SetValue("ENUM_NAME", NameWrappedInNameSpace(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 { ";
+    Indent();
+    code_ += "{{ACCESS_TYPE}} typealias T = {{BASE_TYPE}}";
+    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;
+      auto name = Name(ev);
+      code_.SetValue("KEY", name);
+      code_.SetValue("VALUE", enum_def.ToString(ev));
+      GenComment(ev.doc_comment);
+      code_ += "case {{KEY}} = {{VALUE}}";
+    }
+    code_ += "\n";
+    AddMinOrMaxEnumValue(Name(*enum_def.MaxValue()), "max");
+    AddMinOrMaxEnumValue(Name(*enum_def.MinValue()), "min");
+    Outdent();
+    code_ += "}\n";
+    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: NativeTable?";
+      code_ += "{{ACCESS_TYPE}} init(_ v: NativeTable?, type: {{ENUM_NAME}}) {";
+      Indent();
+      code_ += "self.type = type";
+      code_ += "self.value = v";
+      Outdent();
+      code_ += "}";
+      code_ +=
+          "{{ACCESS_TYPE}} func pack(builder: inout FlatBufferBuilder) -> "
+          "Offset<UOffset> {";
+      Indent();
+      BuildUnionEnumSwitchCaseWritter(enum_def);
+      Outdent();
+      code_ += "}";
+      Outdent();
+      code_ += "}";
+    }
+  }
+
+  void GenObjectAPI(const StructDef &struct_def) {
+    code_ += "{{ACCESS_TYPE}} class " + ObjectAPIName("{{STRUCTNAME}}") +
+             ": NativeTable {\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) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      BuildObjectAPIConstructorBody(field, struct_def.fixed, buffer_constructor,
+                                    base_constructor);
+    }
+    code_ += "";
+    BuildObjectAPIConstructor(
+        buffer_constructor,
+        "_ _t: inout " + NameWrappedInNameSpace(struct_def));
+    BuildObjectAPIConstructor(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();
+    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) {
+      auto &field = **it;
+      if (field.deprecated) continue;
+      auto name = Name(field);
+      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 + name + ": ";
+      switch (field.value.type.base_type) {
+        case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
+        case BASE_TYPE_VECTOR: {
+          GenerateVectorObjectAPITableExtension(field, name, type);
+          unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + name +
+                                builder);
+          break;
+        }
+        case BASE_TYPE_UNION: {
+          code_ += "let __" + name + " = obj." + name +
+                   "?.pack(builder: &builder) ?? Offset()";
+          unpack_body.push_back("if let o = obj." + name + "?.type {");
+          unpack_body.push_back("  {{STRUCTNAME}}.add(" + name + "Type: o" +
+                                builder);
+          unpack_body.push_back("  {{STRUCTNAME}}." + body + "__" + name +
+                                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
+            // UnsafeMutableRawPointer 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." + name + ".map { " +
+                NameWrappedInNameSpace(*field.value.type.struct_def) +
+                ".create" + Name(*field.value.type.struct_def) +
+                "(builder: &builder, " + code + ") }" + builder);
+          } else {
+            code_ += "let __" + name + " = " + type +
+                     ".pack(&builder, obj: &obj." + name + ")";
+            unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + name +
+                                  builder);
+          }
+          break;
+        }
+        case BASE_TYPE_STRING: {
+          unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + name +
+                                builder);
+          if (field.required) {
+            code_ +=
+                "let __" + name + " = builder.create(string: obj." + name + ")";
+          } else {
+            BuildingOptionalObjects(name, "String",
+                                    "builder.create(string: s)");
+          }
+          break;
+        }
+        case BASE_TYPE_UTYPE: break;
+        default:
+          unpack_body.push_back("{{STRUCTNAME}}." + body + "obj." + name +
+                                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,
+                                             const std::string &name,
+                                             const std::string &type) {
+    auto vectortype = field.value.type.VectorType();
+    switch (vectortype.base_type) {
+      case BASE_TYPE_UNION: {
+        code_ += "var __" + name + "__: [Offset<UOffset>] = []";
+        code_ += "for i in obj." + name + " {";
+        Indent();
+        code_ += "guard let off = i?.pack(builder: &builder) else { continue }";
+        code_ += "__" + name + "__.append(off)";
+        Outdent();
+        code_ += "}";
+        code_ += "let __" + name + " = builder.createVector(ofOffsets: __" +
+                 name + "__)";
+        code_ += "let __" + name + "Type = builder.createVector(obj." + name +
+                 ".compactMap { $0?.type })";
+        break;
+      }
+      case BASE_TYPE_UTYPE: break;
+      case BASE_TYPE_STRUCT: {
+        if (field.value.type.struct_def &&
+            !field.value.type.struct_def->fixed) {
+          code_ += "var __" + name + "__: [Offset<UOffset>] = []";
+          code_ += "for var i in obj." + name + " {";
+          Indent();
+          code_ +=
+              "__" + name + "__.append(" + type + ".pack(&builder, obj: &i))";
+          Outdent();
+          code_ += "}";
+          code_ += "let __" + name + " = builder.createVector(ofOffsets: __" +
+                   name + "__)";
+        } else {
+          code_ += "{{STRUCTNAME}}.startVectorOf" + MakeCamel(name, true) +
+                   "(obj." + name + ".count, in: &builder)";
+          std::string code;
+          GenerateStructArgs(*field.value.type.struct_def, &code, "", "", "_o",
+                             true);
+          code = code.substr(0, code.size() - 2);
+          code_ += "for i in obj." + name + " {";
+          Indent();
+          code_ += "guard let _o = i else { continue }";
+          code_ += NameWrappedInNameSpace(*field.value.type.struct_def) +
+                   ".create" + Name(*field.value.type.struct_def) +
+                   "(builder: &builder, " + code + ")";
+          Outdent();
+          code_ += "}";
+          code_ += "let __" + name +
+                   " = builder.endVectorOfStructs(count: obj." + name +
+                   ".count)";
+        }
+        break;
+      }
+      case BASE_TYPE_STRING: {
+        code_ += "let __" + name + " = builder.createVector(ofStrings: obj." +
+                 name + ".compactMap({ $0 }) )";
+        break;
+      }
+      default: {
+        code_ += "let __" + name + " = builder.createVector(obj." + name + ")";
+        break;
+      }
+    }
+  }
+
+  void BuildingOptionalObjects(const std::string &name,
+                               const std::string &object_type,
+                               const std::string &body_front) {
+    code_ += "let __" + name + ": Offset<" + object_type + ">";
+    code_ += "if let s = obj." + name + " {";
+    Indent();
+    code_ += "__" + name + " = " + body_front;
+    Outdent();
+    code_ += "} else {";
+    Indent();
+    code_ += "__" + name + " = Offset<" + object_type + ">()";
+    Outdent();
+    code_ += "}";
+    code_ += "";
+  }
+
+  void BuildObjectAPIConstructor(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) {
+    auto name = Name(field);
+    auto type = GenType(field.value.type);
+    code_.SetValue("VALUENAME", name);
+    code_.SetValue("VALUETYPE", type);
+    std::string is_required = field.required ? "" : "?";
+
+    switch (field.value.type.base_type) {
+      case BASE_TYPE_STRUCT: {
+        type = GenType(field.value.type, true);
+        code_.SetValue("VALUETYPE", type);
+        buffer_constructor.push_back("var __" + name + " = _t." + name);
+        auto optional =
+            (field.value.type.struct_def && field.value.type.struct_def->fixed);
+        std::string question_mark =
+            (field.required || (optional && is_fixed) ? "" : "?");
+
+        code_ +=
+            "{{ACCESS_TYPE}} var {{VALUENAME}}: {{VALUETYPE}}" + question_mark;
+        buffer_constructor.push_back("" + name + " = __" + name +
+                                     (field.required ? "!" : question_mark) +
+                                     ".unpack()");
+        base_constructor.push_back("" + name + " = " + type + "()");
+        break;
+      }
+      case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
+      case BASE_TYPE_VECTOR: {
+        BuildObjectAPIConstructorBodyVectors(field, name, buffer_constructor,
+                                             base_constructor, "    ");
+        break;
+      }
+      case BASE_TYPE_STRING: {
+        code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: String" + is_required;
+        buffer_constructor.push_back(name + " = _t." + name);
+        if (field.required) base_constructor.push_back(name + " = \"\"");
+        break;
+      }
+      case BASE_TYPE_UTYPE: break;
+      case BASE_TYPE_UNION: {
+        BuildUnionEnumSwitchCase(*field.value.type.enum_def, name,
+                                 buffer_constructor);
+        break;
+      }
+      default: {
+        buffer_constructor.push_back(name + " = _t." + name);
+        std::string nullable = field.optional ? "?" : "";
+        if (IsScalar(field.value.type.base_type) &&
+            !IsBool(field.value.type.base_type) && !IsEnum(field.value.type)) {
+          code_ +=
+              "{{ACCESS_TYPE}} var {{VALUENAME}}: {{VALUETYPE}}" + nullable;
+          if (!field.optional)
+            base_constructor.push_back(name + " = " + field.value.constant);
+          break;
+        }
+
+        if (IsEnum(field.value.type)) {
+          auto default_value = IsEnum(field.value.type)
+                                   ? GenEnumDefaultValue(field)
+                                   : field.value.constant;
+          code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: {{VALUETYPE}}";
+          base_constructor.push_back(name + " = " + default_value);
+          break;
+        }
+
+        if (IsBool(field.value.type.base_type)) {
+          code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: Bool" + nullable;
+          std::string default_value =
+              "0" == field.value.constant ? "false" : "true";
+          if (!field.optional)
+            base_constructor.push_back(name + " = " + default_value);
+        }
+      }
+    }
+  }
+
+  void BuildObjectAPIConstructorBodyVectors(
+      const FieldDef &field, const std::string &name,
+      std::vector<std::string> &buffer_constructor,
+      std::vector<std::string> &base_constructor,
+      const std::string &indentation) {
+    auto vectortype = field.value.type.VectorType();
+
+    if (vectortype.base_type != BASE_TYPE_UTYPE) {
+      buffer_constructor.push_back(name + " = []");
+      buffer_constructor.push_back("for index in 0..<_t." + name + "Count {");
+      base_constructor.push_back(name + " = []");
+    }
+
+    switch (vectortype.base_type) {
+      case BASE_TYPE_STRUCT: {
+        code_.SetValue("VALUETYPE", GenType(vectortype, true));
+        code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: [{{VALUETYPE}}?]";
+        buffer_constructor.push_back(indentation + "var __v_ = _t." + name +
+                                     "(at: index)");
+        buffer_constructor.push_back(indentation + name +
+                                     ".append(__v_?.unpack())");
+        break;
+      }
+      case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
+      case BASE_TYPE_VECTOR: {
+        break;
+      }
+      case BASE_TYPE_UNION: {
+        BuildUnionEnumSwitchCase(*field.value.type.enum_def, name,
+                                 buffer_constructor, indentation, true);
+        break;
+      }
+      case BASE_TYPE_UTYPE: break;
+      default: {
+        code_.SetValue("VALUETYPE", (IsString(vectortype)
+                                         ? "String?"
+                                         : GenType(vectortype)));
+        code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: [{{VALUETYPE}}]";
+
+        if (IsEnum(vectortype) && vectortype.base_type != BASE_TYPE_UNION) {
+          auto default_value = IsEnum(field.value.type)
+                                   ? GenEnumDefaultValue(field)
+                                   : field.value.constant;
+          buffer_constructor.push_back(indentation + name + ".append(_t." +
+                                       name + "(at: index)!)");
+          break;
+        }
+        buffer_constructor.push_back(indentation + name + ".append(_t." + name +
+                                     "(at: index))");
+        break;
+      }
+    }
+    if (vectortype.base_type != BASE_TYPE_UTYPE)
+      buffer_constructor.push_back("}");
+  }
+
+  void BuildUnionEnumSwitchCaseWritter(const EnumDef &ev) {
+    auto field_name = Name(ev);
+    code_.SetValue("VALUETYPE", field_name);
+    code_ += "switch type {";
+    for (auto it = ev.Vals().begin(); it < ev.Vals().end(); ++it) {
+      auto field = **it;
+      auto ev_name = Name(field);
+      auto type = GenType(field.union_type);
+
+      if (field.union_type.base_type == BASE_TYPE_NONE ||
+          IsString(field.union_type)) {
+        continue;
+      }
+      code_ += "case ." + ev_name + ":";
+      Indent();
+      code_ += "var __obj = value as? " + GenType(field.union_type, true);
+      code_ += "return " + type + ".pack(&builder, obj: &__obj)";
+      Outdent();
+    }
+    code_ += "default: return Offset()";
+    code_ += "}";
+  }
+
+  void BuildUnionEnumSwitchCase(const EnumDef &ev, const std::string &name,
+                                std::vector<std::string> &buffer_constructor,
+                                const std::string &indentation = "",
+                                const bool is_vector = false) {
+    auto field_name = NameWrappedInNameSpace(ev);
+    code_.SetValue("VALUETYPE", field_name);
+    code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: \\";
+    code_ += is_vector ? "[{{VALUETYPE}}Union?]" : "{{VALUETYPE}}Union?";
+
+    auto vector_reader = is_vector ? "(at: index" : "";
+    buffer_constructor.push_back(indentation + "switch _t." + name + "Type" +
+                                 vector_reader + (is_vector ? ")" : "") + " {");
+
+    for (auto it = ev.Vals().begin(); it < ev.Vals().end(); ++it) {
+      auto field = **it;
+      auto ev_name = Name(field);
+      if (field.union_type.base_type == BASE_TYPE_NONE ||
+          IsString(field.union_type)) {
+        continue;
+      }
+      buffer_constructor.push_back(indentation + "case ." + ev_name + ":");
+      buffer_constructor.push_back(
+          indentation + "    var _v = _t." + name + (is_vector ? "" : "(") +
+          vector_reader + (is_vector ? ", " : "") +
+          "type: " + GenType(field.union_type) + ".self)");
+      auto constructor =
+          field_name + "Union(_v?.unpack(), type: ." + ev_name + ")";
+      buffer_constructor.push_back(
+          indentation + "    " + name +
+          (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) {
+    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) {
+    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) -> {{VALUENAME}}? {";
+    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 {{VALUENAME}}(fbb, o: tableOffset)";
+    Outdent();
+    code_ += "}";
+    Outdent();
+    code_ += "}";
+    code_ += "return nil";
+    Outdent();
+    code_ += "}";
+  }
+
+  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 {{VALUENAME}}: {{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({{VALUENAME}}: "
+           "{{VALUETYPE}}) -> Bool {" +
+           get_offset + " return {{ACCESS}}.mutate({{VALUENAME}}" +
+           (isRaw ? ".rawValue" : "") + ", index: " + offset + ") }";
+  }
+
+  std::string GenMutateArray() {
+    return "{{ACCESS_TYPE}} func mutate({{VALUENAME}}: {{VALUETYPE}}, at "
+           "index: "
+           "Int32) -> Bool { " +
+           GenOffset() +
+           "return {{ACCESS}}.directMutate({{VALUENAME}}, index: "
+           "{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }";
+  }
+
+  std::string GenEnumDefaultValue(const FieldDef &field) {
+    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);
+    std::string name;
+    if (enum_val) {
+      name = Name(*enum_val);
+    } else {
+      const auto &ev = **enum_def.Vals().begin();
+      name = Name(ev);
+    }
+    std::transform(name.begin(), name.end(), name.begin(), CharToLower);
+    return "." + name;
+  }
+
+  std::string GenEnumConstructor(const std::string &at) {
+    return "{{VALUETYPE}}(rawValue: " + GenReader("BASEVALUE", at) + ") ";
+  }
+
+  std::string ValidateFunc() {
+    return "static func validateVersion() { FlatBuffersVersion_1_12_0() }";
+  }
+
+  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: {
+        auto &struct_ = *type.struct_def;
+        if (should_consider_suffix) {
+          return WrapInNameSpace(struct_.defined_namespace,
+                                 ObjectAPIName(Name(struct_)));
+        }
+        return WrapInNameSpace(struct_.defined_namespace, Name(struct_));
+      }
+      case BASE_TYPE_UNION:
+      default: return "FlatBufferObject";
+    }
+  }
+
+  std::string GenTypeBasic(const Type &type) const {
+    return GenTypeBasic(type, true);
+  }
+
+  std::string ObjectAPIName(const std::string &name) const {
+    return parser_.opts.object_prefix + name + parser_.opts.object_suffix;
+  }
+
+  void Indent() { code_.IncrementIdentLevel(); }
+
+  void Outdent() { code_.DecrementIdentLevel(); }
+
+  std::string NameWrappedInNameSpace(const EnumDef &enum_def) const {
+    return WrapInNameSpace(enum_def.defined_namespace, Name(enum_def));
+  }
+
+  std::string NameWrappedInNameSpace(const StructDef &struct_def) const {
+    return WrapInNameSpace(struct_def.defined_namespace, Name(struct_def));
+  }
+
+  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 NameWrappedInNameSpace(*type.enum_def);
+      if (type.base_type == BASE_TYPE_BOOL) return "Bool";
+    }
+    return swift_type[static_cast<int>(type.base_type)];
+  }
+
+  std::string EscapeKeyword(const std::string &name) const {
+    return keywords_.find(name) == keywords_.end() ? name : name + "_";
+  }
+
+  std::string Name(const EnumVal &ev) const {
+    auto name = ev.name;
+    if (isupper(name.front())) {
+      std::transform(name.begin(), name.end(), name.begin(), CharToLower);
+    }
+    return EscapeKeyword(MakeCamel(name, false));
+  }
+
+  std::string Name(const Definition &def) const {
+    return EscapeKeyword(MakeCamel(def.name, false));
+  }
+};
+}  // 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
