/*
 * 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 "idl_gen_swift.h"

#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=*/"_",
          /*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
          /*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 + ")";
}

}  // 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", "VT");
    code_ += "// " + std::string(FlatBuffersGeneratedWarning());
    code_ += "// swiftlint:disable all";
    code_ += "// swiftformat:disable all\n";

    if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) {
      code_.SetValue("IMPLEMENTONLY",
                     parser_.opts.swift_implementation_only ? "internal " : "");
      code_ += "#if canImport(Common)";
      code_ += "{{IMPLEMENTONLY}}import Common";
      code_ += "#endif";
      code_ += "";
      code_ += "{{IMPLEMENTONLY}}import FlatBuffers\n";
    }

    if (parser_.advanced_features_ == reflection::AdvancedArrayFeatures) {
      code_ += "#if compiler(>=6.2)";
    }

    GenerateCode();

    if (parser_.advanced_features_ == reflection::AdvancedArrayFeatures) {
      code_ += "#endif";
    }

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

  void GenerateCode() {
    // 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);
        }
      }
    }
  }

  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));
    GenOSVersionChecks();
    code_ +=
        "{{ACCESS_TYPE}} struct {{STRUCTNAME}}: NativeStruct, "
        "FlatbuffersVectorInitializable, 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);
      code_.SetValue("FIELDVAR", field_var);
      const auto type = GenType(field.value.type);
      if (IsEnum(field.value.type)) {
        code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false));
      }
      code_.SetValue("VALUETYPE", type);
      GenComment(field.doc_comment);

      if (IsArray(field.value.type)) {
        std::string valueType = IsEnum(field.value.type.VectorType())
                                    ? "{{BASEVALUE}}"
                                    : "{{VALUETYPE}}";
        const auto fixed_length =
            NumToString(field.value.type.VectorType().fixed_length);
        code_.SetValue("FIXEDLENGTH", fixed_length);

        std::string vector_base_type;
        if (IsStruct(field.value.type.VectorType())) {
          vector_base_type = type + "()";
        } else if (IsBool(field.value.type.VectorType().base_type)) {
          vector_base_type = "false";
        } else if (IsFloat(field.value.type.VectorType().base_type)) {
          vector_base_type = "0.0";
        } else {
          vector_base_type = SwiftConstant(field);
        }
        code_ += "private var _{{FIELDVAR}}: InlineArray<{{FIXEDLENGTH}}, " +
                 valueType + ">";

        main_constructor.push_back("_" + field_var + " = " + field_var);
        base_constructor.push_back(
            "_" + field_var + " = InlineArray(repeating: " + vector_base_type +
            ")");

        if (field.padding) {
          GenPadding(field, &padding_id);
        }
        constructor += field_var + ": " + "InlineArray<" + fixed_length + ", ";
        if (IsEnum(field.value.type.VectorType())) {
          constructor +=
              GenTypeBasic(field.value.type.VectorType(), false) + ">";
        } else {
          constructor += type + ">";
        }
      } else {
        const auto accessing_value = IsEnum(field.value.type) ? ".value" : "";
        const auto base_value =
            IsStruct(field.value.type) ? (type + "()") : SwiftConstant(field);

        std::string valueType =
            IsEnum(field.value.type) ? "{{BASEVALUE}}" : "{{VALUETYPE}}";
        code_ += "private var _{{FIELDVAR}}: " + valueType;

        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_ += "";
    code_ += "{{ACCESS_TYPE}} init(_ bb: ByteBuffer, o: Int32) {";
    Indent();
    code_ += "self = bb.read(def: Self.self, position: Int(o))";
    Outdent();
    code_ += "}\n";

    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 (IsArray(field.value.type)) {
        const auto fixed_length =
            NumToString(field.value.type.VectorType().fixed_length);
        code_.SetValue("FIXEDLENGTH", fixed_length);
        if (IsEnum(field.value.type.VectorType())) {
          code_ +=
              "{{ACCESS_TYPE}} var {{FIELDVAR}}: InlineArray<{{FIXEDLENGTH}}, "
              "{{VALUETYPE}}> { InlineArray { {{VALUETYPE}}(rawValue: "
              "_{{FIELDVAR}}[$0])! } }";
        } else {
          code_ +=
              "{{ACCESS_TYPE}} var {{FIELDVAR}}: InlineArray<{{FIXEDLENGTH}}, "
              "{{VALUETYPE}}> { _{{FIELDVAR}} }";
        }
      } else 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 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 (IsArray(field.value.type)) {
        code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
        code_.SetValue("SIZE",
                       NumToString(InlineSize(field.value.type.VectorType())));
        code_.SetValue("MUTABLE", IsStruct(field.value.type.VectorType())
                                      ? Mutable()
                                      : "");
        const auto fixed_length =
            NumToString(field.value.type.VectorType().fixed_length);
        code_.SetValue("FIXEDLENGTH", fixed_length);

        code_ +=
            "{{ACCESS_TYPE}} var {{FIELDVAR}}: "
            "FlatbufferVector<{{VALUETYPE}}{{MUTABLE}}> "
            "{ return {{ACCESS}}.vector(at: {{OFFSET_VALUE}}, count: "
            "{{FIXEDLENGTH}}, size: {{SIZE}}) "
            "}";
      } else 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}}.position + {{OFFSET}}");
      } else if (IsVector(field.value.type.base_type)) {
        code_.SetValue("VALUETYPE", GenType(field.value.type) + Mutable());
        code_ += GenReaderMainBody() + "return " +
                 GenConstructor("{{ACCESS}}.position + {{OFFSET}}");
      }

      if (parser_.opts.mutable_buffer) {
        if (!IsStruct(field.value.type) && !IsArray(field.value.type)) {
          code_ += GenMutate("{{OFFSET}}", "", IsEnum(field.value.type));
        } else if (IsArray(field.value.type) &&
                   !IsStruct(field.value.type.VectorType())) {
          code_.SetValue("IS_RAW", IsEnum(field.value.type.VectorType())
                                       ? ".rawValue"
                                       : "");
          code_ +=
              "@discardableResult {{ACCESS_TYPE}} func mutate({{FIELDVAR}}: "
              "{{VALUETYPE}}, at index: Int32) -> Bool { "
              "return {{ACCESS}}.mutate({{FIELDVAR}}{{IS_RAW}}, index: "
              "{{OFFSET_VALUE}} + (index * {{SIZE}})) }";
        }
      }
    }

    if (parser_.opts.generate_object_based_api) {
      GenerateObjectAPIExtensionHeader(namer_.NamespacedType(struct_def),
                                       struct_def.fixed);
      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 struct {{TABLEOFFSET}} {";
      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_ += "static let {{OFFSET_NAME}}: VOffset = {{OFFSET_VALUE}}";
      }
      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("PROTOCOL", struct_def.fixed ? "FlatBufferStruct"
                                                : "FlatBufferVerifiableTable");
    code_.SetValue("MUTABLE", struct_def.fixed ? Mutable() : "");

    GenOSVersionChecks();
    code_ +=
        "{{ACCESS_TYPE}} struct {{STRUCTNAME}}{{MUTABLE}}: "
        "{{PROTOCOL}}, FlatbuffersVectorInitializable\\";
    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_ += "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\\";
      if (create_func_header.empty() == false) code_ += ",";
      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), Table.offset(Int32($0.o), vOffset: "
               "{{VOFFSET}}, fbb: &fbb), fbb: &fbb) < 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}}) }";

      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}}) }";
      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}}) }";
      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}}) }"
            : "offset: {{FIELDVAR}}, at: {{TABLEOFFSET}}.{{OFFSET}}) "
              "}";
    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_ += GenOffset() +
               "return o == 0 ? {{CONSTANT}} : " + 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}}.position");
      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}}.position"));
        break;

      case BASE_TYPE_STRING: {
        const auto sc = SwiftConstant(field);
        std::string default_string;
        flatbuffers::EscapeString(sc.c_str(), sc.length(), &default_string,
                                  true, false);
        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}}) }";
        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) {
    const auto vectortype = field.value.type.VectorType();
    code_.SetValue("SIZE", NumToString(InlineSize(vectortype)));

    if (vectortype.base_type == BASE_TYPE_STRING) {
      code_.SetValue("VALUETYPE", "String?");
    }

    if (vectortype.base_type != BASE_TYPE_UNION) {
      code_ +=
          "{{ACCESS_TYPE}} var {{FIELDVAR}}: "
          "FlatbufferVector<{{VALUETYPE}}> "
          "{ return {{ACCESS}}.vector(at: {{TABLEOFFSET}}.{{OFFSET}}, "
          "byteSize: {{SIZE}}) }";
    }

    if (IsScalar(vectortype.base_type) && !IsEnum(vectortype) &&
        !IsBool(field.value.type.base_type)) {
      if (parser_.opts.mutable_buffer) code_ += GenMutateArray();
      GenUnsafeBufferPointer(field);
      return;
    }

    if (vectortype.base_type == BASE_TYPE_STRUCT &&
        field.value.type.struct_def->fixed) {
      code_.SetValue("FIELDVAR", namer_.Method("mutable", field));
      code_ +=
          "{{ACCESS_TYPE}} var {{FIELDVAR}}: "
          "FlatbufferVector<{{VALUETYPE}}_Mutable> "
          "{ return {{ACCESS}}.vector(at: {{TABLEOFFSET}}.{{OFFSET}}, "
          "byteSize: {{SIZE}}) }";
      GenUnsafeBufferPointer(field);
      return;
    }

    if (vectortype.base_type == BASE_TYPE_UNION) {
      code_ +=
          "{{ACCESS_TYPE}} var {{FIELDVAR}}: UnionFlatbufferVector "
          "{ return {{ACCESS}}.unionVector(at: "
          "{{TABLEOFFSET}}.{{OFFSET}}, "
          "byteSize: {{SIZE}}) }";
      code_ +=
          "{{ACCESS_TYPE}} func {{FIELDVAR}}<T: FlatbuffersInitializable>(at "
          "index: "
          "Int32, type: T.Type) -> T? { " +
          GenOffset() + "return o == 0 ? nil : \\";
      code_ +=
          "{{ACCESS}}.directUnion({{ACCESS}}.vector(at: o) + "
          "index * {{SIZE}}) }";
      return;
    }

    if (vectortype.base_type == BASE_TYPE_STRUCT &&
        !field.value.type.struct_def->fixed) {
      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 GenUnsafeBufferPointer(const FieldDef& field) {
    code_.SetValue("functionName",
                   namer_.Variable("withUnsafePointerTo", field));
    code_ +=
        "{{ACCESS_TYPE}} func {{functionName}}<T>(_ body: "
        "(UnsafeRawBufferPointer, Int) throws -> T) rethrows -> T? { return "
        "try "
        "{{ACCESS}}.withUnsafePointerToSlice(at: "
        "{{TABLEOFFSET}}.{{OFFSET}}, "
        "body: body) }";
  }

  std::vector<std::string> GenerateCodingKeys(const StructDef& struct_def) {
    std::vector<std::string> coding_keys;
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      const auto& field = **it;
      if (field.deprecated) continue;
      coding_keys.push_back("case " + namer_.Variable(field) + " = \"" +
                            field.name + "\"");
    }
    return coding_keys;
  }

  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_ +=
          "try container.encode({{FIELDVAR}}Type, forKey: .charactersType)";
      code_ +=
          "var contentEncoder = container.nestedUnkeyedContainer(forKey: "
          ".{{FIELDVAR}})";
      code_ += "let _{{FIELDVAR}} = {{FIELDVAR}}Type";
      code_ +=
          "for index in _{{FIELDVAR}}.startIndex..<_{{FIELDVAR}}.endIndex {";
      Indent();
      code_ += "switch _{{FIELDVAR}}[index] {";
      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: Int32(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;

      code_.SetValue("FIELDVAR", namer_.Variable(field));
      code_.SetValue("CONSTANT", SwiftConstant(field));
      bool should_indent = true;
      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 (IsArray(type)) {
        code_ +=
            "var {{FIELDVAR}}Container = "
            "container.nestedUnkeyedContainer(forKey: .{{FIELDVAR}})";
        code_ +=
            "for index in {{FIELDVAR}}.startIndex..<{{FIELDVAR}}.endIndex {";
        Indent();
        code_ += "try {{FIELDVAR}}Container.encode({{FIELDVAR}}[index])";
        Outdent();
        code_ += "}";
      } else {
        code_ +=
            "try container.encodeIfPresent({{FIELDVAR}}, forKey: "
            ".{{FIELDVAR}})";
      }
      if (should_indent) Outdent();

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

  void GenerateJSONEncodingAPIs(const StructDef& struct_def) {
    GenOSVersionChecks();
    code_ += "extension {{STRUCTNAME}}: Encodable {";
    Indent();
    auto coding_keys = GenerateCodingKeys(struct_def);

    if (coding_keys.empty() == false) {
      code_ += "enum CodingKeys: String, CodingKey {";
      Indent();
      for (auto it = coding_keys.begin(); it != coding_keys.end(); ++it) {
        const auto& field = *it;
        code_ += field;
      }
      Outdent();
      code_ += "}";

      code_ += "";
    }

    code_ += "{{ACCESS_TYPE}} func encode(to encoder: Encoder) throws {";

    if (coding_keys.empty() == false) {
      Indent();
      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}}, 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, "
        "unionField: {{TABLEOFFSET}}.{{OFFSET}}, 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}}, FlatbuffersVectorInitializable, {{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,
                                        const bool is_fixed_struct) {
    //    code_.SetValue("MUTATING", is_fixed_struct ? "" : " mutating");
    code_ += "";
    code_ += "{{ACCESS_TYPE}} func unpack() -> " + type_name + " {";
    Indent();
    code_ += "return " + type_name + (is_fixed_struct ? "(self)" : "(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: borrowing {{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 (IsArray(field.value.type)) {
        code_.SetValue(
            "RAW_VALUE",
            IsStruct(field.value.type.VectorType())
                ? ".unpack()"
                : (IsEnum(field.value.type.VectorType()) ? ".rawValue" : ""));
        code_ += "let _v{{FIELDVAR}} = _t.{{FIELDVAR}}";
        code_ +=
            "_{{FIELDVAR}} = InlineArray { _v{{FIELDVAR}}[$0]{{RAW_VALUE}} }";
        continue;
      } else if (IsStruct(field.value.type)) {
        code_ += "let _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) {
    GenOSVersionChecks();
    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: borrowing " + 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),
                                     struct_def.fixed);
    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 val in obj." + field + " {";
          Indent();
          code_ += "builder.create(struct: val)";
          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(
              "" + field_var + " = _t." + 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;
          if (field.IsDefault()) {
            const auto sc = SwiftConstant(field);
            flatbuffers::EscapeString(sc.c_str(), sc.length(), &default_value,
                                      true, false);
          } else {
            default_value = "\"\"";
          }
          base_constructor.push_back(field_var + " = " + default_value);
          break;
        }
        if (field.IsDefault() && !field.IsRequired()) {
          const auto sc = SwiftConstant(field);
          std::string value;
          flatbuffers::EscapeString(sc.c_str(), sc.length(), &value,
                                    true, false);
          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 + " = []");
      base_constructor.push_back(field_var + " = []");
    }

    switch (vectortype.base_type) {
      case BASE_TYPE_STRUCT: {
        code_.SetValue("VALUETYPE", GenType(vectortype, true));
        code_.SetValue("OPTIONAL", !vectortype.struct_def->fixed ? "?" : "");
        code_ +=
            "{{ACCESS_TYPE}} var {{FIELDVAR}}: [{{VALUETYPE}}{{OPTIONAL}}]";
        if (!vectortype.struct_def->fixed) {
          buffer_constructor.push_back("for val in _t." + field_field + "{");
          buffer_constructor.push_back(indentation + field_var +
                                       ".append(val.unpack())");
          buffer_constructor.push_back("}");
        } else {
          buffer_constructor.push_back(field_var + ".append(contentsOf: _t." +
                                       field_field + ")");
        }
        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}}]";

        buffer_constructor.push_back(field_var + ".append(contentsOf: _t." +
                                     field_field + ")");
        break;
      }
    }
  }

  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 ? "[index]" : "";
    if (is_vector) {
      buffer_constructor.push_back("let _" + field + "Type = _t." + field +
                                   "Type");
      buffer_constructor.push_back("for index in _" + field +
                                   "Type.startIndex..<_" + field +
                                   "Type.endIndex {");
    }

    buffer_constructor.push_back(indentation + "switch _t." + field + "Type" +
                                 vector_reader + " {");

    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 + ":");
      const auto constructor =
          ns_type + "Union(_v?.unpack(), type: ." + variant + ")";
      if (is_vector) {
        buffer_constructor.push_back(indentation + "  let _v = _t." + field +
                                     "(at: Int32(index), type: " + type +
                                     ".self)");
        buffer_constructor.push_back(indentation + "  " + field + ".append(" +
                                     constructor + ")");
      } else {
        buffer_constructor.push_back(indentation + "  let _v = _t." + field +
                                     "(" + "type: " + type + ".self)");
        buffer_constructor.push_back(indentation + "  " + field + " = " +
                                     constructor);
      }
    }
    buffer_constructor.push_back(indentation + "default: break");
    buffer_constructor.push_back(indentation + "}");
    if (is_vector) {
      buffer_constructor.push_back("}");
    }
  }

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

  void GenOSVersionChecks() {
    if (parser_.advanced_features_ == reflection::AdvancedArrayFeatures) {
      code_ += "@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)";
    }
  }

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

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

  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

static 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 {

class SwiftCodeGenerator : public CodeGenerator {
 public:
  Status GenerateCode(const Parser& parser, const std::string& path,
                      const std::string& filename) override {
    if (!GenerateSwift(parser, path, filename)) {
      return Status::ERROR;
    }
    return Status::OK;
  }

  Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
    return Status::NOT_IMPLEMENTED;
  }

  Status GenerateGrpcCode(const Parser& parser, const std::string& path,
                          const std::string& filename) override {
    if (!GenerateSwiftGRPC(parser, path, filename)) {
      return Status::ERROR;
    }
    return Status::OK;
  }

  Status GenerateMakeRule(const Parser& parser, const std::string& path,
                          const std::string& filename,
                          std::string& output) override {
    (void)parser;
    (void)path;
    (void)filename;
    (void)output;
    return Status::NOT_IMPLEMENTED;
  }

  Status GenerateRootFile(const Parser& parser,
                          const std::string& path) override {
    (void)parser;
    (void)path;
    return Status::NOT_IMPLEMENTED;
  }

  bool IsSchemaOnly() const override { return true; }

  bool SupportsBfbsGeneration() const override { return false; }

  bool SupportsRootFileGeneration() const override { return false; }

  IDLOptions::Language Language() const override { return IDLOptions::kSwift; }

  std::string LanguageName() const override { return "Swift"; }
};
}  // namespace

std::unique_ptr<CodeGenerator> NewSwiftCodeGenerator() {
  return std::unique_ptr<SwiftCodeGenerator>(new SwiftCodeGenerator());
}

}  // namespace flatbuffers
