//===-- 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 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<EnumExtensibilityKind> EnumExtensibility;
  std::optional<bool> FlagEnum;
  std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
};

typedef std::vector<Tag> TagsSeq;
} // 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("EnumExtensibility", T.EnumExtensibility);
    IO.mapOptional("FlagEnum", T.FlagEnum);
    IO.mapOptional("EnumKind", T.EnumConvenienceKind);
  }
};
} // 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 ? *ReturnNullability
                                               : 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);
  }

  void convertContext(std::optional<ContextID> ParentContextID, const Class &C,
                      ContextKind Kind, VersionTuple SwiftVersion) {
    // Write the class.
    ObjCContextInfo 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.addObjCContext(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;
      convertAvailability(Property.Availability, PI, Property.Name);
      PI.setSwiftPrivate(Property.SwiftPrivate);
      PI.SwiftName = std::string(Property.SwiftName);
      if (Property.Nullability)
        PI.setNullabilityAudited(*Property.Nullability);
      if (Property.SwiftImportAsAccessors)
        PI.setSwiftImportAsAccessors(*Property.SwiftImportAsAccessors);
      PI.setType(std::string(Property.Type));

      // 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.
    ObjCContextInfo CI;
    convertCommonEntity(TheNamespace, CI, TheNamespace.Name);

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

    convertTopLevelItems(Context(CtxID, ContextKind::Namespace),
                         TheNamespace.Items, 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;
      convertAvailability(Global.Availability, GVI, Global.Name);
      GVI.setSwiftPrivate(Global.SwiftPrivate);
      GVI.SwiftName = std::string(Global.SwiftName);
      if (Global.Nullability)
        GVI.setNullabilityAudited(*Global.Nullability);
      GVI.setType(std::string(Global.Type));
      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;
      convertAvailability(Function.Availability, GFI, Function.Name);
      GFI.setSwiftPrivate(Function.SwiftPrivate);
      GFI.SwiftName = std::string(Function.SwiftName);
      convertParams(Function.Params, GFI);
      convertNullability(Function.Nullability, Function.NullabilityOfRet, GFI,
                         Function.Name);
      GFI.ResultType = std::string(Function.ResultType);
      GFI.setRetainCountConvention(Function.RetainCountConvention);
      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;
      }

      TagInfo TI;
      convertCommonType(Tag, TI, Tag.Name);

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

      if (Tag.SwiftImportAs)
        TI.SwiftImportAs = Tag.SwiftImportAs;
      if (Tag.SwiftRetainOp)
        TI.SwiftRetainOp = Tag.SwiftRetainOp;
      if (Tag.SwiftReleaseOp)
        TI.SwiftReleaseOp = Tag.SwiftReleaseOp;

      if (Tag.EnumConvenienceKind) {
        if (Tag.EnumExtensibility) {
          emitError(
              llvm::Twine("cannot mix EnumKind and EnumExtensibility (for ") +
              Tag.Name + ")");
          continue;
        }
        if (Tag.FlagEnum) {
          emitError(llvm::Twine("cannot mix EnumKind and FlagEnum (for ") +
                    Tag.Name + ")");
          continue;
        }
        switch (*Tag.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 = Tag.EnumExtensibility;
        TI.setFlagEnum(Tag.FlagEnum);
      }

      Writer.addTag(Ctx, Tag.Name, TI, 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);
}
