//===-- APINotesYAMLCompiler.cpp - API Notes YAML Format Reader -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// The types defined locally are designed to represent the YAML state, which
// adds an additional bit of state: e.g. a tri-state boolean attribute (yes, no,
// not applied) becomes a tri-state boolean + present.  As a result, while these
// enumerations appear to be redefining constants from the attributes table
// data, they are distinct.
//

#include "clang/APINotes/APINotesYAMLCompiler.h"
#include "clang/APINotes/APINotesWriter.h"
#include "clang/APINotes/Types.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/YAMLTraits.h"
#include <optional>
#include <vector>

using namespace clang;
using namespace api_notes;

namespace {
enum class APIAvailability {
  Available = 0,
  None,
  NonSwift,
};
} // namespace

namespace llvm {
namespace yaml {
template <> struct ScalarEnumerationTraits<APIAvailability> {
  static void enumeration(IO &IO, APIAvailability &AA) {
    IO.enumCase(AA, "none", APIAvailability::None);
    IO.enumCase(AA, "nonswift", APIAvailability::NonSwift);
    IO.enumCase(AA, "available", APIAvailability::Available);
  }
};
} // namespace yaml
} // namespace llvm

namespace {
enum class MethodKind {
  Class,
  Instance,
};
} // namespace

namespace llvm {
namespace yaml {
template <> struct ScalarEnumerationTraits<MethodKind> {
  static void enumeration(IO &IO, MethodKind &MK) {
    IO.enumCase(MK, "Class", MethodKind::Class);
    IO.enumCase(MK, "Instance", MethodKind::Instance);
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct Param {
  unsigned Position;
  std::optional<bool> NoEscape = false;
  std::optional<NullabilityKind> Nullability;
  std::optional<RetainCountConventionKind> RetainCountConvention;
  StringRef Type;
};

typedef std::vector<Param> ParamsSeq;
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Param)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(NullabilityKind)

namespace llvm {
namespace yaml {
template <> struct ScalarEnumerationTraits<NullabilityKind> {
  static void enumeration(IO &IO, NullabilityKind &NK) {
    IO.enumCase(NK, "Nonnull", NullabilityKind::NonNull);
    IO.enumCase(NK, "Optional", NullabilityKind::Nullable);
    IO.enumCase(NK, "Unspecified", NullabilityKind::Unspecified);
    IO.enumCase(NK, "NullableResult", NullabilityKind::NullableResult);
    // TODO: Mapping this to it's own value would allow for better cross
    // checking. Also the default should be Unknown.
    IO.enumCase(NK, "Scalar", NullabilityKind::Unspecified);

    // Aliases for compatibility with existing APINotes.
    IO.enumCase(NK, "N", NullabilityKind::NonNull);
    IO.enumCase(NK, "O", NullabilityKind::Nullable);
    IO.enumCase(NK, "U", NullabilityKind::Unspecified);
    IO.enumCase(NK, "S", NullabilityKind::Unspecified);
  }
};

template <> struct ScalarEnumerationTraits<RetainCountConventionKind> {
  static void enumeration(IO &IO, RetainCountConventionKind &RCCK) {
    IO.enumCase(RCCK, "none", RetainCountConventionKind::None);
    IO.enumCase(RCCK, "CFReturnsRetained",
                RetainCountConventionKind::CFReturnsRetained);
    IO.enumCase(RCCK, "CFReturnsNotRetained",
                RetainCountConventionKind::CFReturnsNotRetained);
    IO.enumCase(RCCK, "NSReturnsRetained",
                RetainCountConventionKind::NSReturnsRetained);
    IO.enumCase(RCCK, "NSReturnsNotRetained",
                RetainCountConventionKind::NSReturnsNotRetained);
  }
};

template <> struct MappingTraits<Param> {
  static void mapping(IO &IO, Param &P) {
    IO.mapRequired("Position", P.Position);
    IO.mapOptional("Nullability", P.Nullability, std::nullopt);
    IO.mapOptional("RetainCountConvention", P.RetainCountConvention);
    IO.mapOptional("NoEscape", P.NoEscape);
    IO.mapOptional("Type", P.Type, StringRef(""));
  }
};
} // namespace yaml
} // namespace llvm

namespace {
typedef std::vector<NullabilityKind> NullabilitySeq;

struct AvailabilityItem {
  APIAvailability Mode = APIAvailability::Available;
  StringRef Msg;
};

/// Old attribute deprecated in favor of SwiftName.
enum class FactoryAsInitKind {
  /// Infer based on name and type (the default).
  Infer,
  /// Treat as a class method.
  AsClassMethod,
  /// Treat as an initializer.
  AsInitializer,
};

struct Method {
  StringRef Selector;
  MethodKind Kind;
  ParamsSeq Params;
  NullabilitySeq Nullability;
  std::optional<NullabilityKind> NullabilityOfRet;
  std::optional<RetainCountConventionKind> RetainCountConvention;
  AvailabilityItem Availability;
  std::optional<bool> SwiftPrivate;
  StringRef SwiftName;
  FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;
  bool DesignatedInit = false;
  bool Required = false;
  StringRef ResultType;
};

typedef std::vector<Method> MethodsSeq;
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Method)

namespace llvm {
namespace yaml {
template <> struct ScalarEnumerationTraits<FactoryAsInitKind> {
  static void enumeration(IO &IO, FactoryAsInitKind &FIK) {
    IO.enumCase(FIK, "A", FactoryAsInitKind::Infer);
    IO.enumCase(FIK, "C", FactoryAsInitKind::AsClassMethod);
    IO.enumCase(FIK, "I", FactoryAsInitKind::AsInitializer);
  }
};

template <> struct MappingTraits<Method> {
  static void mapping(IO &IO, Method &M) {
    IO.mapRequired("Selector", M.Selector);
    IO.mapRequired("MethodKind", M.Kind);
    IO.mapOptional("Parameters", M.Params);
    IO.mapOptional("Nullability", M.Nullability);
    IO.mapOptional("NullabilityOfRet", M.NullabilityOfRet, std::nullopt);
    IO.mapOptional("RetainCountConvention", M.RetainCountConvention);
    IO.mapOptional("Availability", M.Availability.Mode,
                   APIAvailability::Available);
    IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));
    IO.mapOptional("SwiftPrivate", M.SwiftPrivate);
    IO.mapOptional("SwiftName", M.SwiftName, StringRef(""));
    IO.mapOptional("FactoryAsInit", M.FactoryAsInit, FactoryAsInitKind::Infer);
    IO.mapOptional("DesignatedInit", M.DesignatedInit, false);
    IO.mapOptional("Required", M.Required, false);
    IO.mapOptional("ResultType", M.ResultType, StringRef(""));
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct Property {
  StringRef Name;
  std::optional<MethodKind> Kind;
  std::optional<NullabilityKind> Nullability;
  AvailabilityItem Availability;
  std::optional<bool> SwiftPrivate;
  StringRef SwiftName;
  std::optional<bool> SwiftImportAsAccessors;
  StringRef Type;
};

typedef std::vector<Property> PropertiesSeq;
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Property)

namespace llvm {
namespace yaml {
template <> struct MappingTraits<Property> {
  static void mapping(IO &IO, Property &P) {
    IO.mapRequired("Name", P.Name);
    IO.mapOptional("PropertyKind", P.Kind);
    IO.mapOptional("Nullability", P.Nullability, std::nullopt);
    IO.mapOptional("Availability", P.Availability.Mode,
                   APIAvailability::Available);
    IO.mapOptional("AvailabilityMsg", P.Availability.Msg, StringRef(""));
    IO.mapOptional("SwiftPrivate", P.SwiftPrivate);
    IO.mapOptional("SwiftName", P.SwiftName, StringRef(""));
    IO.mapOptional("SwiftImportAsAccessors", P.SwiftImportAsAccessors);
    IO.mapOptional("Type", P.Type, StringRef(""));
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct Class {
  StringRef Name;
  bool AuditedForNullability = false;
  AvailabilityItem Availability;
  std::optional<bool> SwiftPrivate;
  StringRef SwiftName;
  std::optional<StringRef> SwiftBridge;
  std::optional<StringRef> NSErrorDomain;
  std::optional<bool> SwiftImportAsNonGeneric;
  std::optional<bool> SwiftObjCMembers;
  MethodsSeq Methods;
  PropertiesSeq Properties;
};

typedef std::vector<Class> ClassesSeq;
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Class)

namespace llvm {
namespace yaml {
template <> struct MappingTraits<Class> {
  static void mapping(IO &IO, Class &C) {
    IO.mapRequired("Name", C.Name);
    IO.mapOptional("AuditedForNullability", C.AuditedForNullability, false);
    IO.mapOptional("Availability", C.Availability.Mode,
                   APIAvailability::Available);
    IO.mapOptional("AvailabilityMsg", C.Availability.Msg, StringRef(""));
    IO.mapOptional("SwiftPrivate", C.SwiftPrivate);
    IO.mapOptional("SwiftName", C.SwiftName, StringRef(""));
    IO.mapOptional("SwiftBridge", C.SwiftBridge);
    IO.mapOptional("NSErrorDomain", C.NSErrorDomain);
    IO.mapOptional("SwiftImportAsNonGeneric", C.SwiftImportAsNonGeneric);
    IO.mapOptional("SwiftObjCMembers", C.SwiftObjCMembers);
    IO.mapOptional("Methods", C.Methods);
    IO.mapOptional("Properties", C.Properties);
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct Function {
  StringRef Name;
  ParamsSeq Params;
  NullabilitySeq Nullability;
  std::optional<NullabilityKind> NullabilityOfRet;
  std::optional<api_notes::RetainCountConventionKind> RetainCountConvention;
  AvailabilityItem Availability;
  std::optional<bool> SwiftPrivate;
  StringRef SwiftName;
  StringRef Type;
  StringRef ResultType;
};

typedef std::vector<Function> FunctionsSeq;
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Function)

namespace llvm {
namespace yaml {
template <> struct MappingTraits<Function> {
  static void mapping(IO &IO, Function &F) {
    IO.mapRequired("Name", F.Name);
    IO.mapOptional("Parameters", F.Params);
    IO.mapOptional("Nullability", F.Nullability);
    IO.mapOptional("NullabilityOfRet", F.NullabilityOfRet, std::nullopt);
    IO.mapOptional("RetainCountConvention", F.RetainCountConvention);
    IO.mapOptional("Availability", F.Availability.Mode,
                   APIAvailability::Available);
    IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef(""));
    IO.mapOptional("SwiftPrivate", F.SwiftPrivate);
    IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));
    IO.mapOptional("ResultType", F.ResultType, StringRef(""));
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct GlobalVariable {
  StringRef Name;
  std::optional<NullabilityKind> Nullability;
  AvailabilityItem Availability;
  std::optional<bool> SwiftPrivate;
  StringRef SwiftName;
  StringRef Type;
};

typedef std::vector<GlobalVariable> GlobalVariablesSeq;
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)

namespace llvm {
namespace yaml {
template <> struct MappingTraits<GlobalVariable> {
  static void mapping(IO &IO, GlobalVariable &GV) {
    IO.mapRequired("Name", GV.Name);
    IO.mapOptional("Nullability", GV.Nullability, std::nullopt);
    IO.mapOptional("Availability", GV.Availability.Mode,
                   APIAvailability::Available);
    IO.mapOptional("AvailabilityMsg", GV.Availability.Msg, StringRef(""));
    IO.mapOptional("SwiftPrivate", GV.SwiftPrivate);
    IO.mapOptional("SwiftName", GV.SwiftName, StringRef(""));
    IO.mapOptional("Type", GV.Type, StringRef(""));
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct EnumConstant {
  StringRef Name;
  AvailabilityItem Availability;
  std::optional<bool> SwiftPrivate;
  StringRef SwiftName;
};

typedef std::vector<EnumConstant> EnumConstantsSeq;
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)

namespace llvm {
namespace yaml {
template <> struct MappingTraits<EnumConstant> {
  static void mapping(IO &IO, EnumConstant &EC) {
    IO.mapRequired("Name", EC.Name);
    IO.mapOptional("Availability", EC.Availability.Mode,
                   APIAvailability::Available);
    IO.mapOptional("AvailabilityMsg", EC.Availability.Msg, StringRef(""));
    IO.mapOptional("SwiftPrivate", EC.SwiftPrivate);
    IO.mapOptional("SwiftName", EC.SwiftName, StringRef(""));
  }
};
} // namespace yaml
} // namespace llvm

namespace {
/// Syntactic sugar for EnumExtensibility and FlagEnum
enum class EnumConvenienceAliasKind {
  /// EnumExtensibility: none, FlagEnum: false
  None,
  /// EnumExtensibility: open, FlagEnum: false
  CFEnum,
  /// EnumExtensibility: open, FlagEnum: true
  CFOptions,
  /// EnumExtensibility: closed, FlagEnum: false
  CFClosedEnum
};
} // namespace

namespace llvm {
namespace yaml {
template <> struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
  static void enumeration(IO &IO, EnumConvenienceAliasKind &ECAK) {
    IO.enumCase(ECAK, "none", EnumConvenienceAliasKind::None);
    IO.enumCase(ECAK, "CFEnum", EnumConvenienceAliasKind::CFEnum);
    IO.enumCase(ECAK, "NSEnum", EnumConvenienceAliasKind::CFEnum);
    IO.enumCase(ECAK, "CFOptions", EnumConvenienceAliasKind::CFOptions);
    IO.enumCase(ECAK, "NSOptions", EnumConvenienceAliasKind::CFOptions);
    IO.enumCase(ECAK, "CFClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
    IO.enumCase(ECAK, "NSClosedEnum", EnumConvenienceAliasKind::CFClosedEnum);
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct Field {
  StringRef Name;
  std::optional<NullabilityKind> Nullability;
  AvailabilityItem Availability;
  std::optional<bool> SwiftPrivate;
  StringRef SwiftName;
  StringRef Type;
};

typedef std::vector<Field> FieldsSeq;
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Field)

namespace llvm {
namespace yaml {
template <> struct MappingTraits<Field> {
  static void mapping(IO &IO, Field &F) {
    IO.mapRequired("Name", F.Name);
    IO.mapOptional("Nullability", F.Nullability, std::nullopt);
    IO.mapOptional("Availability", F.Availability.Mode,
                   APIAvailability::Available);
    IO.mapOptional("AvailabilityMsg", F.Availability.Msg, StringRef(""));
    IO.mapOptional("SwiftPrivate", F.SwiftPrivate);
    IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));
    IO.mapOptional("Type", F.Type, StringRef(""));
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct Tag;
typedef std::vector<Tag> TagsSeq;

struct Tag {
  StringRef Name;
  AvailabilityItem Availability;
  StringRef SwiftName;
  std::optional<bool> SwiftPrivate;
  std::optional<StringRef> SwiftBridge;
  std::optional<StringRef> NSErrorDomain;
  std::optional<std::string> SwiftImportAs;
  std::optional<std::string> SwiftRetainOp;
  std::optional<std::string> SwiftReleaseOp;
  std::optional<std::string> SwiftConformance;
  std::optional<EnumExtensibilityKind> EnumExtensibility;
  std::optional<bool> FlagEnum;
  std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
  std::optional<bool> SwiftCopyable;
  FunctionsSeq Methods;
  FieldsSeq Fields;

  /// Tags that are declared within the current tag. Only the tags that have
  /// corresponding API Notes will be listed.
  TagsSeq Tags;
};
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)

namespace llvm {
namespace yaml {
template <> struct ScalarEnumerationTraits<EnumExtensibilityKind> {
  static void enumeration(IO &IO, EnumExtensibilityKind &EEK) {
    IO.enumCase(EEK, "none", EnumExtensibilityKind::None);
    IO.enumCase(EEK, "open", EnumExtensibilityKind::Open);
    IO.enumCase(EEK, "closed", EnumExtensibilityKind::Closed);
  }
};

template <> struct MappingTraits<Tag> {
  static void mapping(IO &IO, Tag &T) {
    IO.mapRequired("Name", T.Name);
    IO.mapOptional("Availability", T.Availability.Mode,
                   APIAvailability::Available);
    IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
    IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
    IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
    IO.mapOptional("SwiftBridge", T.SwiftBridge);
    IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
    IO.mapOptional("SwiftImportAs", T.SwiftImportAs);
    IO.mapOptional("SwiftReleaseOp", T.SwiftReleaseOp);
    IO.mapOptional("SwiftRetainOp", T.SwiftRetainOp);
    IO.mapOptional("SwiftConformsTo", T.SwiftConformance);
    IO.mapOptional("EnumExtensibility", T.EnumExtensibility);
    IO.mapOptional("FlagEnum", T.FlagEnum);
    IO.mapOptional("EnumKind", T.EnumConvenienceKind);
    IO.mapOptional("SwiftCopyable", T.SwiftCopyable);
    IO.mapOptional("Methods", T.Methods);
    IO.mapOptional("Fields", T.Fields);
    IO.mapOptional("Tags", T.Tags);
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct Typedef {
  StringRef Name;
  AvailabilityItem Availability;
  StringRef SwiftName;
  std::optional<bool> SwiftPrivate;
  std::optional<StringRef> SwiftBridge;
  std::optional<StringRef> NSErrorDomain;
  std::optional<SwiftNewTypeKind> SwiftType;
};

typedef std::vector<Typedef> TypedefsSeq;
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)

namespace llvm {
namespace yaml {
template <> struct ScalarEnumerationTraits<SwiftNewTypeKind> {
  static void enumeration(IO &IO, SwiftNewTypeKind &SWK) {
    IO.enumCase(SWK, "none", SwiftNewTypeKind::None);
    IO.enumCase(SWK, "struct", SwiftNewTypeKind::Struct);
    IO.enumCase(SWK, "enum", SwiftNewTypeKind::Enum);
  }
};

template <> struct MappingTraits<Typedef> {
  static void mapping(IO &IO, Typedef &T) {
    IO.mapRequired("Name", T.Name);
    IO.mapOptional("Availability", T.Availability.Mode,
                   APIAvailability::Available);
    IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
    IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
    IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
    IO.mapOptional("SwiftBridge", T.SwiftBridge);
    IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
    IO.mapOptional("SwiftWrapper", T.SwiftType);
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct Namespace;
typedef std::vector<Namespace> NamespacesSeq;

struct TopLevelItems {
  ClassesSeq Classes;
  ClassesSeq Protocols;
  FunctionsSeq Functions;
  GlobalVariablesSeq Globals;
  EnumConstantsSeq EnumConstants;
  TagsSeq Tags;
  TypedefsSeq Typedefs;
  NamespacesSeq Namespaces;
};
} // namespace

namespace llvm {
namespace yaml {
static void mapTopLevelItems(IO &IO, TopLevelItems &TLI) {
  IO.mapOptional("Classes", TLI.Classes);
  IO.mapOptional("Protocols", TLI.Protocols);
  IO.mapOptional("Functions", TLI.Functions);
  IO.mapOptional("Globals", TLI.Globals);
  IO.mapOptional("Enumerators", TLI.EnumConstants);
  IO.mapOptional("Tags", TLI.Tags);
  IO.mapOptional("Typedefs", TLI.Typedefs);
  IO.mapOptional("Namespaces", TLI.Namespaces);
}
} // namespace yaml
} // namespace llvm

namespace {
struct Namespace {
  StringRef Name;
  AvailabilityItem Availability;
  StringRef SwiftName;
  std::optional<bool> SwiftPrivate;
  TopLevelItems Items;
};
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Namespace)

namespace llvm {
namespace yaml {
template <> struct MappingTraits<Namespace> {
  static void mapping(IO &IO, Namespace &T) {
    IO.mapRequired("Name", T.Name);
    IO.mapOptional("Availability", T.Availability.Mode,
                   APIAvailability::Available);
    IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
    IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
    IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
    mapTopLevelItems(IO, T.Items);
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct Versioned {
  VersionTuple Version;
  TopLevelItems Items;
};

typedef std::vector<Versioned> VersionedSeq;
} // namespace

LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)

namespace llvm {
namespace yaml {
template <> struct MappingTraits<Versioned> {
  static void mapping(IO &IO, Versioned &V) {
    IO.mapRequired("Version", V.Version);
    mapTopLevelItems(IO, V.Items);
  }
};
} // namespace yaml
} // namespace llvm

namespace {
struct Module {
  StringRef Name;
  AvailabilityItem Availability;
  TopLevelItems TopLevel;
  VersionedSeq SwiftVersions;

  std::optional<bool> SwiftInferImportAsMember;

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  LLVM_DUMP_METHOD void dump() /*const*/;
#endif
};
} // namespace

namespace llvm {
namespace yaml {
template <> struct MappingTraits<Module> {
  static void mapping(IO &IO, Module &M) {
    IO.mapRequired("Name", M.Name);
    IO.mapOptional("Availability", M.Availability.Mode,
                   APIAvailability::Available);
    IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef(""));
    IO.mapOptional("SwiftInferImportAsMember", M.SwiftInferImportAsMember);
    mapTopLevelItems(IO, M.TopLevel);
    IO.mapOptional("SwiftVersions", M.SwiftVersions);
  }
};
} // namespace yaml
} // namespace llvm

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void Module::dump() {
  llvm::yaml::Output OS(llvm::errs());
  OS << *this;
}
#endif

namespace {
bool parseAPINotes(StringRef YI, Module &M, llvm::SourceMgr::DiagHandlerTy Diag,
                   void *DiagContext) {
  llvm::yaml::Input IS(YI, nullptr, Diag, DiagContext);
  IS >> M;
  return static_cast<bool>(IS.error());
}
} // namespace

bool clang::api_notes::parseAndDumpAPINotes(StringRef YI,
                                            llvm::raw_ostream &OS) {
  Module M;
  if (parseAPINotes(YI, M, nullptr, nullptr))
    return true;

  llvm::yaml::Output YOS(OS);
  YOS << M;

  return false;
}

namespace {
using namespace api_notes;

class YAMLConverter {
  const Module &M;
  APINotesWriter Writer;
  llvm::raw_ostream &OS;
  llvm::SourceMgr::DiagHandlerTy DiagHandler;
  void *DiagHandlerCtxt;
  bool ErrorOccured;

  /// Emit a diagnostic
  bool emitError(llvm::Twine Message) {
    DiagHandler(
        llvm::SMDiagnostic("", llvm::SourceMgr::DK_Error, Message.str()),
        DiagHandlerCtxt);
    ErrorOccured = true;
    return true;
  }

public:
  YAMLConverter(const Module &TheModule, const FileEntry *SourceFile,
                llvm::raw_ostream &OS,
                llvm::SourceMgr::DiagHandlerTy DiagHandler,
                void *DiagHandlerCtxt)
      : M(TheModule), Writer(TheModule.Name, SourceFile), OS(OS),
        DiagHandler(DiagHandler), DiagHandlerCtxt(DiagHandlerCtxt),
        ErrorOccured(false) {}

  void convertAvailability(const AvailabilityItem &Availability,
                           CommonEntityInfo &CEI, llvm::StringRef APIName) {
    // Populate the unavailability information.
    CEI.Unavailable = (Availability.Mode == APIAvailability::None);
    CEI.UnavailableInSwift = (Availability.Mode == APIAvailability::NonSwift);
    if (CEI.Unavailable || CEI.UnavailableInSwift) {
      CEI.UnavailableMsg = std::string(Availability.Msg);
    } else {
      if (!Availability.Msg.empty())
        emitError(llvm::Twine("availability message for available API '") +
                  APIName + "' will not be used");
    }
  }

  void convertParams(const ParamsSeq &Params, FunctionInfo &OutInfo) {
    for (const auto &P : Params) {
      ParamInfo PI;
      if (P.Nullability)
        PI.setNullabilityAudited(*P.Nullability);
      PI.setNoEscape(P.NoEscape);
      PI.setType(std::string(P.Type));
      PI.setRetainCountConvention(P.RetainCountConvention);
      if (OutInfo.Params.size() <= P.Position)
        OutInfo.Params.resize(P.Position + 1);
      OutInfo.Params[P.Position] |= PI;
    }
  }

  void convertNullability(const NullabilitySeq &Nullability,
                          std::optional<NullabilityKind> ReturnNullability,
                          FunctionInfo &OutInfo, llvm::StringRef APIName) {
    if (Nullability.size() > FunctionInfo::getMaxNullabilityIndex()) {
      emitError(llvm::Twine("nullability info for '") + APIName +
                "' does not fit");
      return;
    }

    bool audited = false;
    unsigned int idx = 1;
    for (const auto &N : Nullability)
      OutInfo.addTypeInfo(idx++, N);
    audited = Nullability.size() > 0 || ReturnNullability;
    if (audited)
      OutInfo.addTypeInfo(0,
                          ReturnNullability.value_or(NullabilityKind::NonNull));
    if (!audited)
      return;
    OutInfo.NullabilityAudited = audited;
    OutInfo.NumAdjustedNullable = idx;
  }

  /// Convert the common parts of an entity from YAML.
  template <typename T>
  void convertCommonEntity(const T &Common, CommonEntityInfo &Info,
                           StringRef APIName) {
    convertAvailability(Common.Availability, Info, APIName);
    Info.setSwiftPrivate(Common.SwiftPrivate);
    Info.SwiftName = std::string(Common.SwiftName);
  }

  /// Convert the common parts of a type entity from YAML.
  template <typename T>
  void convertCommonType(const T &Common, CommonTypeInfo &Info,
                         StringRef APIName) {
    convertCommonEntity(Common, Info, APIName);
    if (Common.SwiftBridge)
      Info.setSwiftBridge(std::string(*Common.SwiftBridge));
    Info.setNSErrorDomain(Common.NSErrorDomain);
  }

  // Translate from Method into ObjCMethodInfo and write it out.
  void convertMethod(const Method &M, ContextID ClassID, StringRef ClassName,
                     VersionTuple SwiftVersion) {
    ObjCMethodInfo MI;
    convertCommonEntity(M, MI, M.Selector);

    // Check if the selector ends with ':' to determine if it takes arguments.
    bool takesArguments = M.Selector.ends_with(":");

    // Split the selector into pieces.
    llvm::SmallVector<StringRef, 4> Args;
    M.Selector.split(Args, ":", /*MaxSplit*/ -1, /*KeepEmpty*/ false);
    if (!takesArguments && Args.size() > 1) {
      emitError("selector '" + M.Selector + "' is missing a ':' at the end");
      return;
    }

    // Construct ObjCSelectorRef.
    api_notes::ObjCSelectorRef Selector;
    Selector.NumArgs = !takesArguments ? 0 : Args.size();
    Selector.Identifiers = Args;

    // Translate the initializer info.
    MI.DesignatedInit = M.DesignatedInit;
    MI.RequiredInit = M.Required;
    if (M.FactoryAsInit != FactoryAsInitKind::Infer)
      emitError("'FactoryAsInit' is no longer valid; use 'SwiftName' instead");

    MI.ResultType = std::string(M.ResultType);

    // Translate parameter information.
    convertParams(M.Params, MI);

    // Translate nullability info.
    convertNullability(M.Nullability, M.NullabilityOfRet, MI, M.Selector);

    MI.setRetainCountConvention(M.RetainCountConvention);

    // Write it.
    Writer.addObjCMethod(ClassID, Selector, M.Kind == MethodKind::Instance, MI,
                         SwiftVersion);
  }

  template <typename T>
  void convertVariable(const T &Entity, VariableInfo &VI) {
    convertAvailability(Entity.Availability, VI, Entity.Name);
    VI.setSwiftPrivate(Entity.SwiftPrivate);
    VI.SwiftName = std::string(Entity.SwiftName);
    if (Entity.Nullability)
      VI.setNullabilityAudited(*Entity.Nullability);
    VI.setType(std::string(Entity.Type));
  }

  void convertContext(std::optional<ContextID> ParentContextID, const Class &C,
                      ContextKind Kind, VersionTuple SwiftVersion) {
    // Write the class.
    ContextInfo CI;
    convertCommonType(C, CI, C.Name);

    if (C.AuditedForNullability)
      CI.setDefaultNullability(NullabilityKind::NonNull);
    if (C.SwiftImportAsNonGeneric)
      CI.setSwiftImportAsNonGeneric(*C.SwiftImportAsNonGeneric);
    if (C.SwiftObjCMembers)
      CI.setSwiftObjCMembers(*C.SwiftObjCMembers);

    ContextID CtxID =
        Writer.addContext(ParentContextID, C.Name, Kind, CI, SwiftVersion);

    // Write all methods.
    llvm::StringMap<std::pair<bool, bool>> KnownMethods;
    for (const auto &method : C.Methods) {
      // Check for duplicate method definitions.
      bool IsInstanceMethod = method.Kind == MethodKind::Instance;
      bool &Known = IsInstanceMethod ? KnownMethods[method.Selector].first
                                     : KnownMethods[method.Selector].second;
      if (Known) {
        emitError(llvm::Twine("duplicate definition of method '") +
                  (IsInstanceMethod ? "-" : "+") + "[" + C.Name + " " +
                  method.Selector + "]'");
        continue;
      }
      Known = true;

      convertMethod(method, CtxID, C.Name, SwiftVersion);
    }

    // Write all properties.
    llvm::StringSet<> KnownInstanceProperties;
    llvm::StringSet<> KnownClassProperties;
    for (const auto &Property : C.Properties) {
      // Check for duplicate property definitions.
      if ((!Property.Kind || *Property.Kind == MethodKind::Instance) &&
          !KnownInstanceProperties.insert(Property.Name).second) {
        emitError(llvm::Twine("duplicate definition of instance property '") +
                  C.Name + "." + Property.Name + "'");
        continue;
      }

      if ((!Property.Kind || *Property.Kind == MethodKind::Class) &&
          !KnownClassProperties.insert(Property.Name).second) {
        emitError(llvm::Twine("duplicate definition of class property '") +
                  C.Name + "." + Property.Name + "'");
        continue;
      }

      // Translate from Property into ObjCPropertyInfo.
      ObjCPropertyInfo PI;
      convertVariable(Property, PI);
      if (Property.SwiftImportAsAccessors)
        PI.setSwiftImportAsAccessors(*Property.SwiftImportAsAccessors);

      // Add both instance and class properties with this name.
      if (Property.Kind) {
        Writer.addObjCProperty(CtxID, Property.Name,
                               *Property.Kind == MethodKind::Instance, PI,
                               SwiftVersion);
      } else {
        Writer.addObjCProperty(CtxID, Property.Name, true, PI, SwiftVersion);
        Writer.addObjCProperty(CtxID, Property.Name, false, PI, SwiftVersion);
      }
    }
  }

  void convertNamespaceContext(std::optional<ContextID> ParentContextID,
                               const Namespace &TheNamespace,
                               VersionTuple SwiftVersion) {
    // Write the namespace.
    ContextInfo CI;
    convertCommonEntity(TheNamespace, CI, TheNamespace.Name);

    ContextID CtxID =
        Writer.addContext(ParentContextID, TheNamespace.Name,
                          ContextKind::Namespace, CI, SwiftVersion);

    convertTopLevelItems(Context(CtxID, ContextKind::Namespace),
                         TheNamespace.Items, SwiftVersion);
  }

  void convertFunction(const Function &Function, FunctionInfo &FI) {
    convertAvailability(Function.Availability, FI, Function.Name);
    FI.setSwiftPrivate(Function.SwiftPrivate);
    FI.SwiftName = std::string(Function.SwiftName);
    convertParams(Function.Params, FI);
    convertNullability(Function.Nullability, Function.NullabilityOfRet, FI,
                       Function.Name);
    FI.ResultType = std::string(Function.ResultType);
    FI.setRetainCountConvention(Function.RetainCountConvention);
  }

  void convertTagContext(std::optional<Context> ParentContext, const Tag &T,
                         VersionTuple SwiftVersion) {
    TagInfo TI;
    std::optional<ContextID> ParentContextID =
        ParentContext ? std::optional<ContextID>(ParentContext->id)
                      : std::nullopt;
    convertCommonType(T, TI, T.Name);

    if ((T.SwiftRetainOp || T.SwiftReleaseOp) && !T.SwiftImportAs) {
      emitError(llvm::Twine("should declare SwiftImportAs to use "
                            "SwiftRetainOp and SwiftReleaseOp (for ") +
                T.Name + ")");
      return;
    }
    if (T.SwiftReleaseOp.has_value() != T.SwiftRetainOp.has_value()) {
      emitError(llvm::Twine("should declare both SwiftReleaseOp and "
                            "SwiftRetainOp (for ") +
                T.Name + ")");
      return;
    }

    if (T.SwiftImportAs)
      TI.SwiftImportAs = T.SwiftImportAs;
    if (T.SwiftRetainOp)
      TI.SwiftRetainOp = T.SwiftRetainOp;
    if (T.SwiftReleaseOp)
      TI.SwiftReleaseOp = T.SwiftReleaseOp;
    if (T.SwiftConformance)
      TI.SwiftConformance = T.SwiftConformance;

    if (T.SwiftCopyable)
      TI.setSwiftCopyable(T.SwiftCopyable);

    if (T.EnumConvenienceKind) {
      if (T.EnumExtensibility) {
        emitError(
            llvm::Twine("cannot mix EnumKind and EnumExtensibility (for ") +
            T.Name + ")");
        return;
      }
      if (T.FlagEnum) {
        emitError(llvm::Twine("cannot mix EnumKind and FlagEnum (for ") +
                  T.Name + ")");
        return;
      }
      switch (*T.EnumConvenienceKind) {
      case EnumConvenienceAliasKind::None:
        TI.EnumExtensibility = EnumExtensibilityKind::None;
        TI.setFlagEnum(false);
        break;
      case EnumConvenienceAliasKind::CFEnum:
        TI.EnumExtensibility = EnumExtensibilityKind::Open;
        TI.setFlagEnum(false);
        break;
      case EnumConvenienceAliasKind::CFOptions:
        TI.EnumExtensibility = EnumExtensibilityKind::Open;
        TI.setFlagEnum(true);
        break;
      case EnumConvenienceAliasKind::CFClosedEnum:
        TI.EnumExtensibility = EnumExtensibilityKind::Closed;
        TI.setFlagEnum(false);
        break;
      }
    } else {
      TI.EnumExtensibility = T.EnumExtensibility;
      TI.setFlagEnum(T.FlagEnum);
    }

    Writer.addTag(ParentContext, T.Name, TI, SwiftVersion);

    ContextInfo CI;
    auto TagCtxID = Writer.addContext(ParentContextID, T.Name, ContextKind::Tag,
                                      CI, SwiftVersion);
    Context TagCtx(TagCtxID, ContextKind::Tag);

    for (const auto &Field : T.Fields) {
      FieldInfo FI;
      convertVariable(Field, FI);
      Writer.addField(TagCtxID, Field.Name, FI, SwiftVersion);
    }

    for (const auto &CXXMethod : T.Methods) {
      CXXMethodInfo MI;
      convertFunction(CXXMethod, MI);
      Writer.addCXXMethod(TagCtxID, CXXMethod.Name, MI, SwiftVersion);
    }

    // Convert nested tags.
    for (const auto &Tag : T.Tags)
      convertTagContext(TagCtx, Tag, SwiftVersion);
  }

  void convertTopLevelItems(std::optional<Context> Ctx,
                            const TopLevelItems &TLItems,
                            VersionTuple SwiftVersion) {
    std::optional<ContextID> CtxID =
        Ctx ? std::optional(Ctx->id) : std::nullopt;

    // Write all classes.
    llvm::StringSet<> KnownClasses;
    for (const auto &Class : TLItems.Classes) {
      // Check for duplicate class definitions.
      if (!KnownClasses.insert(Class.Name).second) {
        emitError(llvm::Twine("multiple definitions of class '") + Class.Name +
                  "'");
        continue;
      }

      convertContext(CtxID, Class, ContextKind::ObjCClass, SwiftVersion);
    }

    // Write all protocols.
    llvm::StringSet<> KnownProtocols;
    for (const auto &Protocol : TLItems.Protocols) {
      // Check for duplicate protocol definitions.
      if (!KnownProtocols.insert(Protocol.Name).second) {
        emitError(llvm::Twine("multiple definitions of protocol '") +
                  Protocol.Name + "'");
        continue;
      }

      convertContext(CtxID, Protocol, ContextKind::ObjCProtocol, SwiftVersion);
    }

    // Write all namespaces.
    llvm::StringSet<> KnownNamespaces;
    for (const auto &Namespace : TLItems.Namespaces) {
      // Check for duplicate namespace definitions.
      if (!KnownNamespaces.insert(Namespace.Name).second) {
        emitError(llvm::Twine("multiple definitions of namespace '") +
                  Namespace.Name + "'");
        continue;
      }

      convertNamespaceContext(CtxID, Namespace, SwiftVersion);
    }

    // Write all global variables.
    llvm::StringSet<> KnownGlobals;
    for (const auto &Global : TLItems.Globals) {
      // Check for duplicate global variables.
      if (!KnownGlobals.insert(Global.Name).second) {
        emitError(llvm::Twine("multiple definitions of global variable '") +
                  Global.Name + "'");
        continue;
      }

      GlobalVariableInfo GVI;
      convertVariable(Global, GVI);
      Writer.addGlobalVariable(Ctx, Global.Name, GVI, SwiftVersion);
    }

    // Write all global functions.
    llvm::StringSet<> KnownFunctions;
    for (const auto &Function : TLItems.Functions) {
      // Check for duplicate global functions.
      if (!KnownFunctions.insert(Function.Name).second) {
        emitError(llvm::Twine("multiple definitions of global function '") +
                  Function.Name + "'");
        continue;
      }

      GlobalFunctionInfo GFI;
      convertFunction(Function, GFI);
      Writer.addGlobalFunction(Ctx, Function.Name, GFI, SwiftVersion);
    }

    // Write all enumerators.
    llvm::StringSet<> KnownEnumConstants;
    for (const auto &EnumConstant : TLItems.EnumConstants) {
      // Check for duplicate enumerators
      if (!KnownEnumConstants.insert(EnumConstant.Name).second) {
        emitError(llvm::Twine("multiple definitions of enumerator '") +
                  EnumConstant.Name + "'");
        continue;
      }

      EnumConstantInfo ECI;
      convertAvailability(EnumConstant.Availability, ECI, EnumConstant.Name);
      ECI.setSwiftPrivate(EnumConstant.SwiftPrivate);
      ECI.SwiftName = std::string(EnumConstant.SwiftName);
      Writer.addEnumConstant(EnumConstant.Name, ECI, SwiftVersion);
    }

    // Write all tags.
    llvm::StringSet<> KnownTags;
    for (const auto &Tag : TLItems.Tags) {
      // Check for duplicate tag definitions.
      if (!KnownTags.insert(Tag.Name).second) {
        emitError(llvm::Twine("multiple definitions of tag '") + Tag.Name +
                  "'");
        continue;
      }

      convertTagContext(Ctx, Tag, SwiftVersion);
    }

    // Write all typedefs.
    llvm::StringSet<> KnownTypedefs;
    for (const auto &Typedef : TLItems.Typedefs) {
      // Check for duplicate typedef definitions.
      if (!KnownTypedefs.insert(Typedef.Name).second) {
        emitError(llvm::Twine("multiple definitions of typedef '") +
                  Typedef.Name + "'");
        continue;
      }

      TypedefInfo TInfo;
      convertCommonType(Typedef, TInfo, Typedef.Name);
      TInfo.SwiftWrapper = Typedef.SwiftType;

      Writer.addTypedef(Ctx, Typedef.Name, TInfo, SwiftVersion);
    }
  }

  bool convertModule() {
    // Write the top-level items.
    convertTopLevelItems(/* context */ std::nullopt, M.TopLevel,
                         VersionTuple());

    // Convert the versioned information.
    for (const auto &Versioned : M.SwiftVersions)
      convertTopLevelItems(/* context */ std::nullopt, Versioned.Items,
                           Versioned.Version);

    if (!ErrorOccured)
      Writer.writeToStream(OS);

    return ErrorOccured;
  }
};
} // namespace

static bool compile(const Module &M, const FileEntry *SourceFile,
                    llvm::raw_ostream &OS,
                    llvm::SourceMgr::DiagHandlerTy DiagHandler,
                    void *DiagHandlerCtxt) {
  YAMLConverter C(M, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
  return C.convertModule();
}

/// Simple diagnostic handler that prints diagnostics to standard error.
static void printDiagnostic(const llvm::SMDiagnostic &Diag, void *Context) {
  Diag.print(nullptr, llvm::errs());
}

bool api_notes::compileAPINotes(StringRef YAMLInput,
                                const FileEntry *SourceFile,
                                llvm::raw_ostream &OS,
                                llvm::SourceMgr::DiagHandlerTy DiagHandler,
                                void *DiagHandlerCtxt) {
  Module TheModule;

  if (!DiagHandler)
    DiagHandler = &printDiagnostic;

  if (parseAPINotes(YAMLInput, TheModule, DiagHandler, DiagHandlerCtxt))
    return true;

  return compile(TheModule, SourceFile, OS, DiagHandler, DiagHandlerCtxt);
}
