//===- ExtractAPI/Serialization/SymbolGraphSerializer.cpp -------*- 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements the SymbolGraphSerializer.
///
//===----------------------------------------------------------------------===//

#include "clang/ExtractAPI/Serialization/SymbolGraphSerializer.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Version.h"
#include "clang/ExtractAPI/API.h"
#include "clang/ExtractAPI/DeclarationFragments.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/raw_ostream.h"
#include <iterator>
#include <optional>

using namespace clang;
using namespace clang::extractapi;
using namespace llvm;

namespace {

/// Helper function to inject a JSON object \p Obj into another object \p Paren
/// at position \p Key.
void serializeObject(Object &Paren, StringRef Key,
                     std::optional<Object> &&Obj) {
  if (Obj)
    Paren[Key] = std::move(*Obj);
}

/// Helper function to inject a JSON array \p Array into object \p Paren at
/// position \p Key.
void serializeArray(Object &Paren, StringRef Key,
                    std::optional<Array> &&Array) {
  if (Array)
    Paren[Key] = std::move(*Array);
}

/// Helper function to inject a JSON array composed of the values in \p C into
/// object \p Paren at position \p Key.
template <typename ContainerTy>
void serializeArray(Object &Paren, StringRef Key, ContainerTy &&C) {
  Paren[Key] = Array(C);
}

/// Serialize a \c VersionTuple \p V with the Symbol Graph semantic version
/// format.
///
/// A semantic version object contains three numeric fields, representing the
/// \c major, \c minor, and \c patch parts of the version tuple.
/// For example version tuple 1.0.3 is serialized as:
/// \code
///   {
///     "major" : 1,
///     "minor" : 0,
///     "patch" : 3
///   }
/// \endcode
///
/// \returns \c std::nullopt if the version \p V is empty, or an \c Object
/// containing the semantic version representation of \p V.
std::optional<Object> serializeSemanticVersion(const VersionTuple &V) {
  if (V.empty())
    return std::nullopt;

  Object Version;
  Version["major"] = V.getMajor();
  Version["minor"] = V.getMinor().value_or(0);
  Version["patch"] = V.getSubminor().value_or(0);
  return Version;
}

/// Serialize the OS information in the Symbol Graph platform property.
///
/// The OS information in Symbol Graph contains the \c name of the OS, and an
/// optional \c minimumVersion semantic version field.
Object serializeOperatingSystem(const Triple &T) {
  Object OS;
  OS["name"] = T.getOSTypeName(T.getOS());
  serializeObject(OS, "minimumVersion",
                  serializeSemanticVersion(T.getMinimumSupportedOSVersion()));
  return OS;
}

/// Serialize the platform information in the Symbol Graph module section.
///
/// The platform object describes a target platform triple in corresponding
/// three fields: \c architecture, \c vendor, and \c operatingSystem.
Object serializePlatform(const Triple &T) {
  Object Platform;
  Platform["architecture"] = T.getArchName();
  Platform["vendor"] = T.getVendorName();

  if (!T.getEnvironmentName().empty())
    Platform["environment"] = T.getEnvironmentName();

  Platform["operatingSystem"] = serializeOperatingSystem(T);
  return Platform;
}

/// Serialize a source position.
Object serializeSourcePosition(const PresumedLoc &Loc) {
  assert(Loc.isValid() && "invalid source position");

  Object SourcePosition;
  SourcePosition["line"] = Loc.getLine() - 1;
  SourcePosition["character"] = Loc.getColumn() - 1;

  return SourcePosition;
}

/// Serialize a source location in file.
///
/// \param Loc The presumed location to serialize.
/// \param IncludeFileURI If true, include the file path of \p Loc as a URI.
/// Defaults to false.
Object serializeSourceLocation(const PresumedLoc &Loc,
                               bool IncludeFileURI = false) {
  Object SourceLocation;
  serializeObject(SourceLocation, "position", serializeSourcePosition(Loc));

  if (IncludeFileURI) {
    std::string FileURI = "file://";
    // Normalize file path to use forward slashes for the URI.
    FileURI += sys::path::convert_to_slash(Loc.getFilename());
    SourceLocation["uri"] = FileURI;
  }

  return SourceLocation;
}

/// Serialize a source range with begin and end locations.
Object serializeSourceRange(const PresumedLoc &BeginLoc,
                            const PresumedLoc &EndLoc) {
  Object SourceRange;
  serializeObject(SourceRange, "start", serializeSourcePosition(BeginLoc));
  serializeObject(SourceRange, "end", serializeSourcePosition(EndLoc));
  return SourceRange;
}

/// Serialize the availability attributes of a symbol.
///
/// Availability information contains the introduced, deprecated, and obsoleted
/// versions of the symbol as semantic versions, if not default.
/// Availability information also contains flags to indicate if the symbol is
/// unconditionally unavailable or deprecated,
/// i.e. \c __attribute__((unavailable)) and \c __attribute__((deprecated)).
///
/// \returns \c std::nullopt if the symbol has default availability attributes,
/// or an \c Array containing an object with the formatted availability
/// information.
std::optional<Array> serializeAvailability(const AvailabilityInfo &Avail) {
  if (Avail.isDefault())
    return std::nullopt;

  Array AvailabilityArray;

  if (Avail.isUnconditionallyDeprecated()) {
    Object UnconditionallyDeprecated;
    UnconditionallyDeprecated["domain"] = "*";
    UnconditionallyDeprecated["isUnconditionallyDeprecated"] = true;
    AvailabilityArray.emplace_back(std::move(UnconditionallyDeprecated));
  }

  if (Avail.Domain.str() != "") {
    Object Availability;
    Availability["domain"] = Avail.Domain;

    if (Avail.isUnavailable()) {
      Availability["isUnconditionallyUnavailable"] = true;
    } else {
      serializeObject(Availability, "introduced",
                      serializeSemanticVersion(Avail.Introduced));
      serializeObject(Availability, "deprecated",
                      serializeSemanticVersion(Avail.Deprecated));
      serializeObject(Availability, "obsoleted",
                      serializeSemanticVersion(Avail.Obsoleted));
    }

    AvailabilityArray.emplace_back(std::move(Availability));
  }

  return AvailabilityArray;
}

/// Get the language name string for interface language references.
StringRef getLanguageName(Language Lang) {
  switch (Lang) {
  case Language::C:
    return "c";
  case Language::ObjC:
    return "objective-c";
  case Language::CXX:
    return "c++";
  case Language::ObjCXX:
    return "objective-c++";

  // Unsupported language currently
  case Language::OpenCL:
  case Language::OpenCLCXX:
  case Language::CUDA:
  case Language::HIP:
  case Language::HLSL:

  // Languages that the frontend cannot parse and compile
  case Language::Unknown:
  case Language::Asm:
  case Language::LLVM_IR:
  case Language::CIR:
    llvm_unreachable("Unsupported language kind");
  }

  llvm_unreachable("Unhandled language kind");
}

/// Serialize the identifier object as specified by the Symbol Graph format.
///
/// The identifier property of a symbol contains the USR for precise and unique
/// references, and the interface language name.
Object serializeIdentifier(const APIRecord &Record, Language Lang) {
  Object Identifier;
  Identifier["precise"] = Record.USR;
  Identifier["interfaceLanguage"] = getLanguageName(Lang);

  return Identifier;
}

/// Serialize the documentation comments attached to a symbol, as specified by
/// the Symbol Graph format.
///
/// The Symbol Graph \c docComment object contains an array of lines. Each line
/// represents one line of striped documentation comment, with source range
/// information.
/// e.g.
/// \code
///   /// This is a documentation comment
///       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'  First line.
///   ///     with multiple lines.
///       ^~~~~~~~~~~~~~~~~~~~~~~'         Second line.
/// \endcode
///
/// \returns \c std::nullopt if \p Comment is empty, or an \c Object containing
/// the formatted lines.
std::optional<Object> serializeDocComment(const DocComment &Comment) {
  if (Comment.empty())
    return std::nullopt;

  Object DocComment;

  Array LinesArray;
  for (const auto &CommentLine : Comment) {
    Object Line;
    Line["text"] = CommentLine.Text;
    serializeObject(Line, "range",
                    serializeSourceRange(CommentLine.Begin, CommentLine.End));
    LinesArray.emplace_back(std::move(Line));
  }

  serializeArray(DocComment, "lines", std::move(LinesArray));

  return DocComment;
}

/// Serialize the declaration fragments of a symbol.
///
/// The Symbol Graph declaration fragments is an array of tagged important
/// parts of a symbol's declaration. The fragments sequence can be joined to
/// form spans of declaration text, with attached information useful for
/// purposes like syntax-highlighting etc. For example:
/// \code
///   const int pi; -> "declarationFragments" : [
///                      {
///                        "kind" : "keyword",
///                        "spelling" : "const"
///                      },
///                      {
///                        "kind" : "text",
///                        "spelling" : " "
///                      },
///                      {
///                        "kind" : "typeIdentifier",
///                        "preciseIdentifier" : "c:I",
///                        "spelling" : "int"
///                      },
///                      {
///                        "kind" : "text",
///                        "spelling" : " "
///                      },
///                      {
///                        "kind" : "identifier",
///                        "spelling" : "pi"
///                      }
///                    ]
/// \endcode
///
/// \returns \c std::nullopt if \p DF is empty, or an \c Array containing the
/// formatted declaration fragments array.
std::optional<Array>
serializeDeclarationFragments(const DeclarationFragments &DF) {
  if (DF.getFragments().empty())
    return std::nullopt;

  Array Fragments;
  for (const auto &F : DF.getFragments()) {
    Object Fragment;
    Fragment["spelling"] = F.Spelling;
    Fragment["kind"] = DeclarationFragments::getFragmentKindString(F.Kind);
    if (!F.PreciseIdentifier.empty())
      Fragment["preciseIdentifier"] = F.PreciseIdentifier;
    Fragments.emplace_back(std::move(Fragment));
  }

  return Fragments;
}

/// Serialize the \c names field of a symbol as specified by the Symbol Graph
/// format.
///
/// The Symbol Graph names field contains multiple representations of a symbol
/// that can be used for different applications:
///   - \c title : The simple declared name of the symbol;
///   - \c subHeading : An array of declaration fragments that provides tags,
///     and potentially more tokens (for example the \c +/- symbol for
///     Objective-C methods). Can be used as sub-headings for documentation.
Object serializeNames(const APIRecord *Record) {
  Object Names;
  Names["title"] = Record->Name;

  serializeArray(Names, "subHeading",
                 serializeDeclarationFragments(Record->SubHeading));
  DeclarationFragments NavigatorFragments;
  // The +/- prefix for Objective-C methods is important information, and
  // should be included in the navigator fragment. The entire subheading is
  // not included as it can contain too much information for other records.
  switch (Record->getKind()) {
  case APIRecord::RK_ObjCClassMethod:
    NavigatorFragments.append("+ ", DeclarationFragments::FragmentKind::Text,
                              /*PreciseIdentifier*/ "");
    break;
  case APIRecord::RK_ObjCInstanceMethod:
    NavigatorFragments.append("- ", DeclarationFragments::FragmentKind::Text,
                              /*PreciseIdentifier*/ "");
    break;
  default:
    break;
  }

  NavigatorFragments.append(Record->Name,
                            DeclarationFragments::FragmentKind::Identifier,
                            /*PreciseIdentifier*/ "");
  serializeArray(Names, "navigator",
                 serializeDeclarationFragments(NavigatorFragments));

  return Names;
}

Object serializeSymbolKind(APIRecord::RecordKind RK, Language Lang) {
  auto AddLangPrefix = [&Lang](StringRef S) -> std::string {
    return (getLanguageName(Lang) + "." + S).str();
  };

  Object Kind;
  switch (RK) {
  case APIRecord::RK_Unknown:
    Kind["identifier"] = AddLangPrefix("unknown");
    Kind["displayName"] = "Unknown";
    break;
  case APIRecord::RK_Namespace:
    Kind["identifier"] = AddLangPrefix("namespace");
    Kind["displayName"] = "Namespace";
    break;
  case APIRecord::RK_GlobalFunction:
    Kind["identifier"] = AddLangPrefix("func");
    Kind["displayName"] = "Function";
    break;
  case APIRecord::RK_GlobalFunctionTemplate:
    Kind["identifier"] = AddLangPrefix("func");
    Kind["displayName"] = "Function Template";
    break;
  case APIRecord::RK_GlobalFunctionTemplateSpecialization:
    Kind["identifier"] = AddLangPrefix("func");
    Kind["displayName"] = "Function Template Specialization";
    break;
  case APIRecord::RK_GlobalVariableTemplate:
    Kind["identifier"] = AddLangPrefix("var");
    Kind["displayName"] = "Global Variable Template";
    break;
  case APIRecord::RK_GlobalVariableTemplateSpecialization:
    Kind["identifier"] = AddLangPrefix("var");
    Kind["displayName"] = "Global Variable Template Specialization";
    break;
  case APIRecord::RK_GlobalVariableTemplatePartialSpecialization:
    Kind["identifier"] = AddLangPrefix("var");
    Kind["displayName"] = "Global Variable Template Partial Specialization";
    break;
  case APIRecord::RK_GlobalVariable:
    Kind["identifier"] = AddLangPrefix("var");
    Kind["displayName"] = "Global Variable";
    break;
  case APIRecord::RK_EnumConstant:
    Kind["identifier"] = AddLangPrefix("enum.case");
    Kind["displayName"] = "Enumeration Case";
    break;
  case APIRecord::RK_Enum:
    Kind["identifier"] = AddLangPrefix("enum");
    Kind["displayName"] = "Enumeration";
    break;
  case APIRecord::RK_StructField:
    Kind["identifier"] = AddLangPrefix("property");
    Kind["displayName"] = "Instance Property";
    break;
  case APIRecord::RK_Struct:
    Kind["identifier"] = AddLangPrefix("struct");
    Kind["displayName"] = "Structure";
    break;
  case APIRecord::RK_UnionField:
    Kind["identifier"] = AddLangPrefix("property");
    Kind["displayName"] = "Instance Property";
    break;
  case APIRecord::RK_Union:
    Kind["identifier"] = AddLangPrefix("union");
    Kind["displayName"] = "Union";
    break;
  case APIRecord::RK_CXXField:
    Kind["identifier"] = AddLangPrefix("property");
    Kind["displayName"] = "Instance Property";
    break;
  case APIRecord::RK_StaticField:
    Kind["identifier"] = AddLangPrefix("type.property");
    Kind["displayName"] = "Type Property";
    break;
  case APIRecord::RK_ClassTemplate:
  case APIRecord::RK_ClassTemplateSpecialization:
  case APIRecord::RK_ClassTemplatePartialSpecialization:
  case APIRecord::RK_CXXClass:
    Kind["identifier"] = AddLangPrefix("class");
    Kind["displayName"] = "Class";
    break;
  case APIRecord::RK_CXXMethodTemplate:
    Kind["identifier"] = AddLangPrefix("method");
    Kind["displayName"] = "Method Template";
    break;
  case APIRecord::RK_CXXMethodTemplateSpecialization:
    Kind["identifier"] = AddLangPrefix("method");
    Kind["displayName"] = "Method Template Specialization";
    break;
  case APIRecord::RK_CXXFieldTemplate:
    Kind["identifier"] = AddLangPrefix("property");
    Kind["displayName"] = "Template Property";
    break;
  case APIRecord::RK_Concept:
    Kind["identifier"] = AddLangPrefix("concept");
    Kind["displayName"] = "Concept";
    break;
  case APIRecord::RK_CXXStaticMethod:
    Kind["identifier"] = AddLangPrefix("type.method");
    Kind["displayName"] = "Static Method";
    break;
  case APIRecord::RK_CXXInstanceMethod:
    Kind["identifier"] = AddLangPrefix("method");
    Kind["displayName"] = "Instance Method";
    break;
  case APIRecord::RK_CXXConstructorMethod:
    Kind["identifier"] = AddLangPrefix("method");
    Kind["displayName"] = "Constructor";
    break;
  case APIRecord::RK_CXXDestructorMethod:
    Kind["identifier"] = AddLangPrefix("method");
    Kind["displayName"] = "Destructor";
    break;
  case APIRecord::RK_ObjCIvar:
    Kind["identifier"] = AddLangPrefix("ivar");
    Kind["displayName"] = "Instance Variable";
    break;
  case APIRecord::RK_ObjCInstanceMethod:
    Kind["identifier"] = AddLangPrefix("method");
    Kind["displayName"] = "Instance Method";
    break;
  case APIRecord::RK_ObjCClassMethod:
    Kind["identifier"] = AddLangPrefix("type.method");
    Kind["displayName"] = "Type Method";
    break;
  case APIRecord::RK_ObjCInstanceProperty:
    Kind["identifier"] = AddLangPrefix("property");
    Kind["displayName"] = "Instance Property";
    break;
  case APIRecord::RK_ObjCClassProperty:
    Kind["identifier"] = AddLangPrefix("type.property");
    Kind["displayName"] = "Type Property";
    break;
  case APIRecord::RK_ObjCInterface:
    Kind["identifier"] = AddLangPrefix("class");
    Kind["displayName"] = "Class";
    break;
  case APIRecord::RK_ObjCCategory:
    Kind["identifier"] = AddLangPrefix("class.extension");
    Kind["displayName"] = "Class Extension";
    break;
  case APIRecord::RK_ObjCProtocol:
    Kind["identifier"] = AddLangPrefix("protocol");
    Kind["displayName"] = "Protocol";
    break;
  case APIRecord::RK_MacroDefinition:
    Kind["identifier"] = AddLangPrefix("macro");
    Kind["displayName"] = "Macro";
    break;
  case APIRecord::RK_Typedef:
    Kind["identifier"] = AddLangPrefix("typealias");
    Kind["displayName"] = "Type Alias";
    break;
  default:
    llvm_unreachable("API Record with uninstantiable kind");
  }

  return Kind;
}

/// Serialize the symbol kind information.
///
/// The Symbol Graph symbol kind property contains a shorthand \c identifier
/// which is prefixed by the source language name, useful for tooling to parse
/// the kind, and a \c displayName for rendering human-readable names.
Object serializeSymbolKind(const APIRecord &Record, Language Lang) {
  return serializeSymbolKind(Record.KindForDisplay, Lang);
}

/// Serialize the function signature field, as specified by the
/// Symbol Graph format.
///
/// The Symbol Graph function signature property contains two arrays.
///   - The \c returns array is the declaration fragments of the return type;
///   - The \c parameters array contains names and declaration fragments of the
///     parameters.
template <typename RecordTy>
void serializeFunctionSignatureMixin(Object &Paren, const RecordTy &Record) {
  const auto &FS = Record.Signature;
  if (FS.empty())
    return;

  Object Signature;
  serializeArray(Signature, "returns",
                 serializeDeclarationFragments(FS.getReturnType()));

  Array Parameters;
  for (const auto &P : FS.getParameters()) {
    Object Parameter;
    Parameter["name"] = P.Name;
    serializeArray(Parameter, "declarationFragments",
                   serializeDeclarationFragments(P.Fragments));
    Parameters.emplace_back(std::move(Parameter));
  }

  if (!Parameters.empty())
    Signature["parameters"] = std::move(Parameters);

  serializeObject(Paren, "functionSignature", std::move(Signature));
}

template <typename RecordTy>
void serializeTemplateMixin(Object &Paren, const RecordTy &Record) {
  const auto &Template = Record.Templ;
  if (Template.empty())
    return;

  Object Generics;
  Array GenericParameters;
  for (const auto &Param : Template.getParameters()) {
    Object Parameter;
    Parameter["name"] = Param.Name;
    Parameter["index"] = Param.Index;
    Parameter["depth"] = Param.Depth;
    GenericParameters.emplace_back(std::move(Parameter));
  }
  if (!GenericParameters.empty())
    Generics["parameters"] = std::move(GenericParameters);

  Array GenericConstraints;
  for (const auto &Constr : Template.getConstraints()) {
    Object Constraint;
    Constraint["kind"] = Constr.Kind;
    Constraint["lhs"] = Constr.LHS;
    Constraint["rhs"] = Constr.RHS;
    GenericConstraints.emplace_back(std::move(Constraint));
  }

  if (!GenericConstraints.empty())
    Generics["constraints"] = std::move(GenericConstraints);

  serializeObject(Paren, "swiftGenerics", Generics);
}

Array generateParentContexts(const SmallVectorImpl<SymbolReference> &Parents,
                             Language Lang) {
  Array ParentContexts;

  for (const auto &Parent : Parents) {
    Object Elem;
    Elem["usr"] = Parent.USR;
    Elem["name"] = Parent.Name;
    if (Parent.Record)
      Elem["kind"] = serializeSymbolKind(Parent.Record->KindForDisplay,
                                         Lang)["identifier"];
    else
      Elem["kind"] =
          serializeSymbolKind(APIRecord::RK_Unknown, Lang)["identifier"];
    ParentContexts.emplace_back(std::move(Elem));
  }

  return ParentContexts;
}

/// Walk the records parent information in reverse to generate a hierarchy
/// suitable for serialization.
SmallVector<SymbolReference, 8>
generateHierarchyFromRecord(const APIRecord *Record) {
  SmallVector<SymbolReference, 8> ReverseHierarchy;
  for (const auto *Current = Record; Current != nullptr;
       Current = Current->Parent.Record)
    ReverseHierarchy.emplace_back(Current);

  return SmallVector<SymbolReference, 8>(
      std::make_move_iterator(ReverseHierarchy.rbegin()),
      std::make_move_iterator(ReverseHierarchy.rend()));
}

SymbolReference getHierarchyReference(const APIRecord *Record,
                                      const APISet &API) {
  // If the parent is a category extended from internal module then we need to
  // pretend this belongs to the associated interface.
  if (auto *CategoryRecord = dyn_cast_or_null<ObjCCategoryRecord>(Record)) {
    return CategoryRecord->Interface;
    // FIXME: TODO generate path components correctly for categories extending
    // an external module.
  }

  return SymbolReference(Record);
}

} // namespace

Object *ExtendedModule::addSymbol(Object &&Symbol) {
  Symbols.emplace_back(std::move(Symbol));
  return Symbols.back().getAsObject();
}

void ExtendedModule::addRelationship(Object &&Relationship) {
  Relationships.emplace_back(std::move(Relationship));
}

/// Defines the format version emitted by SymbolGraphSerializer.
const VersionTuple SymbolGraphSerializer::FormatVersion{0, 5, 3};

Object SymbolGraphSerializer::serializeMetadata() const {
  Object Metadata;
  serializeObject(Metadata, "formatVersion",
                  serializeSemanticVersion(FormatVersion));
  Metadata["generator"] = clang::getClangFullVersion();
  return Metadata;
}

Object
SymbolGraphSerializer::serializeModuleObject(StringRef ModuleName) const {
  Object Module;
  Module["name"] = ModuleName;
  serializeObject(Module, "platform", serializePlatform(API.getTarget()));
  return Module;
}

bool SymbolGraphSerializer::shouldSkip(const APIRecord *Record) const {
  if (!Record)
    return true;

  // Skip unconditionally unavailable symbols
  if (Record->Availability.isUnconditionallyUnavailable())
    return true;

  // Filter out symbols prefixed with an underscored as they are understood to
  // be symbols clients should not use.
  if (Record->Name.starts_with("_"))
    return true;

  // Skip explicitly ignored symbols.
  if (IgnoresList.shouldIgnore(Record->Name))
    return true;

  return false;
}

ExtendedModule &SymbolGraphSerializer::getModuleForCurrentSymbol() {
  if (!ForceEmitToMainModule && ModuleForCurrentSymbol)
    return *ModuleForCurrentSymbol;

  return MainModule;
}

Array SymbolGraphSerializer::serializePathComponents(
    const APIRecord *Record) const {
  return Array(map_range(Hierarchy, [](auto Elt) { return Elt.Name; }));
}

StringRef SymbolGraphSerializer::getRelationshipString(RelationshipKind Kind) {
  switch (Kind) {
  case RelationshipKind::MemberOf:
    return "memberOf";
  case RelationshipKind::InheritsFrom:
    return "inheritsFrom";
  case RelationshipKind::ConformsTo:
    return "conformsTo";
  case RelationshipKind::ExtensionTo:
    return "extensionTo";
  }
  llvm_unreachable("Unhandled relationship kind");
}

void SymbolGraphSerializer::serializeRelationship(RelationshipKind Kind,
                                                  const SymbolReference &Source,
                                                  const SymbolReference &Target,
                                                  ExtendedModule &Into) {
  Object Relationship;
  SmallString<64> TestRelLabel;
  if (EmitSymbolLabelsForTesting) {
    llvm::raw_svector_ostream OS(TestRelLabel);
    OS << SymbolGraphSerializer::getRelationshipString(Kind) << " $ "
       << Source.USR << " $ ";
    if (Target.USR.empty())
      OS << Target.Name;
    else
      OS << Target.USR;
    Relationship["!testRelLabel"] = TestRelLabel;
  }
  Relationship["source"] = Source.USR;
  Relationship["target"] = Target.USR;
  Relationship["targetFallback"] = Target.Name;
  Relationship["kind"] = SymbolGraphSerializer::getRelationshipString(Kind);

  if (ForceEmitToMainModule)
    MainModule.addRelationship(std::move(Relationship));
  else
    Into.addRelationship(std::move(Relationship));
}

StringRef SymbolGraphSerializer::getConstraintString(ConstraintKind Kind) {
  switch (Kind) {
  case ConstraintKind::Conformance:
    return "conformance";
  case ConstraintKind::ConditionalConformance:
    return "conditionalConformance";
  }
  llvm_unreachable("Unhandled constraint kind");
}

void SymbolGraphSerializer::serializeAPIRecord(const APIRecord *Record) {
  Object Obj;

  // If we need symbol labels for testing emit the USR as the value and the key
  // starts with '!'' to ensure it ends up at the top of the object.
  if (EmitSymbolLabelsForTesting)
    Obj["!testLabel"] = Record->USR;

  serializeObject(Obj, "identifier",
                  serializeIdentifier(*Record, API.getLanguage()));
  serializeObject(Obj, "kind", serializeSymbolKind(*Record, API.getLanguage()));
  serializeObject(Obj, "names", serializeNames(Record));
  serializeObject(
      Obj, "location",
      serializeSourceLocation(Record->Location, /*IncludeFileURI=*/true));
  serializeArray(Obj, "availability",
                 serializeAvailability(Record->Availability));
  serializeObject(Obj, "docComment", serializeDocComment(Record->Comment));
  serializeArray(Obj, "declarationFragments",
                 serializeDeclarationFragments(Record->Declaration));

  Obj["pathComponents"] = serializePathComponents(Record);
  Obj["accessLevel"] = Record->Access.getAccess();

  ExtendedModule &Module = getModuleForCurrentSymbol();
  // If the hierarchy has at least one parent and child.
  if (Hierarchy.size() >= 2)
    serializeRelationship(MemberOf, Hierarchy.back(),
                          Hierarchy[Hierarchy.size() - 2], Module);

  CurrentSymbol = Module.addSymbol(std::move(Obj));
}

bool SymbolGraphSerializer::traverseAPIRecord(const APIRecord *Record) {
  if (!Record)
    return true;
  if (shouldSkip(Record))
    return true;
  Hierarchy.push_back(getHierarchyReference(Record, API));
  // Defer traversal mechanics to APISetVisitor base implementation
  auto RetVal = Base::traverseAPIRecord(Record);
  Hierarchy.pop_back();
  return RetVal;
}

bool SymbolGraphSerializer::visitAPIRecord(const APIRecord *Record) {
  serializeAPIRecord(Record);
  return true;
}

bool SymbolGraphSerializer::visitGlobalFunctionRecord(
    const GlobalFunctionRecord *Record) {
  if (!CurrentSymbol)
    return true;

  serializeFunctionSignatureMixin(*CurrentSymbol, *Record);
  return true;
}

bool SymbolGraphSerializer::visitCXXClassRecord(const CXXClassRecord *Record) {
  if (!CurrentSymbol)
    return true;

  for (const auto &Base : Record->Bases)
    serializeRelationship(RelationshipKind::InheritsFrom, Record, Base,
                          getModuleForCurrentSymbol());
  return true;
}

bool SymbolGraphSerializer::visitClassTemplateRecord(
    const ClassTemplateRecord *Record) {
  if (!CurrentSymbol)
    return true;

  serializeTemplateMixin(*CurrentSymbol, *Record);
  return true;
}

bool SymbolGraphSerializer::visitClassTemplatePartialSpecializationRecord(
    const ClassTemplatePartialSpecializationRecord *Record) {
  if (!CurrentSymbol)
    return true;

  serializeTemplateMixin(*CurrentSymbol, *Record);
  return true;
}

bool SymbolGraphSerializer::visitCXXMethodRecord(
    const CXXMethodRecord *Record) {
  if (!CurrentSymbol)
    return true;

  serializeFunctionSignatureMixin(*CurrentSymbol, *Record);
  return true;
}

bool SymbolGraphSerializer::visitCXXMethodTemplateRecord(
    const CXXMethodTemplateRecord *Record) {
  if (!CurrentSymbol)
    return true;

  serializeTemplateMixin(*CurrentSymbol, *Record);
  return true;
}

bool SymbolGraphSerializer::visitCXXFieldTemplateRecord(
    const CXXFieldTemplateRecord *Record) {
  if (!CurrentSymbol)
    return true;

  serializeTemplateMixin(*CurrentSymbol, *Record);
  return true;
}

bool SymbolGraphSerializer::visitConceptRecord(const ConceptRecord *Record) {
  if (!CurrentSymbol)
    return true;

  serializeTemplateMixin(*CurrentSymbol, *Record);
  return true;
}

bool SymbolGraphSerializer::visitGlobalVariableTemplateRecord(
    const GlobalVariableTemplateRecord *Record) {
  if (!CurrentSymbol)
    return true;

  serializeTemplateMixin(*CurrentSymbol, *Record);
  return true;
}

bool SymbolGraphSerializer::
    visitGlobalVariableTemplatePartialSpecializationRecord(
        const GlobalVariableTemplatePartialSpecializationRecord *Record) {
  if (!CurrentSymbol)
    return true;

  serializeTemplateMixin(*CurrentSymbol, *Record);
  return true;
}

bool SymbolGraphSerializer::visitGlobalFunctionTemplateRecord(
    const GlobalFunctionTemplateRecord *Record) {
  if (!CurrentSymbol)
    return true;

  serializeTemplateMixin(*CurrentSymbol, *Record);
  return true;
}

bool SymbolGraphSerializer::visitObjCContainerRecord(
    const ObjCContainerRecord *Record) {
  if (!CurrentSymbol)
    return true;

  for (const auto &Protocol : Record->Protocols)
    serializeRelationship(ConformsTo, Record, Protocol,
                          getModuleForCurrentSymbol());

  return true;
}

bool SymbolGraphSerializer::visitObjCInterfaceRecord(
    const ObjCInterfaceRecord *Record) {
  if (!CurrentSymbol)
    return true;

  if (!Record->SuperClass.empty())
    serializeRelationship(InheritsFrom, Record, Record->SuperClass,
                          getModuleForCurrentSymbol());
  return true;
}

bool SymbolGraphSerializer::traverseObjCCategoryRecord(
    const ObjCCategoryRecord *Record) {
  if (SkipSymbolsInCategoriesToExternalTypes &&
      !API.findRecordForUSR(Record->Interface.USR))
    return true;

  auto *CurrentModule = ModuleForCurrentSymbol;
  if (auto ModuleExtendedByRecord = Record->getExtendedExternalModule())
    ModuleForCurrentSymbol = &ExtendedModules[*ModuleExtendedByRecord];

  if (!walkUpFromObjCCategoryRecord(Record))
    return false;

  bool RetVal = traverseRecordContext(Record);
  ModuleForCurrentSymbol = CurrentModule;
  return RetVal;
}

bool SymbolGraphSerializer::walkUpFromObjCCategoryRecord(
    const ObjCCategoryRecord *Record) {
  return visitObjCCategoryRecord(Record);
}

bool SymbolGraphSerializer::visitObjCCategoryRecord(
    const ObjCCategoryRecord *Record) {
  // If we need to create a record for the category in the future do so here,
  // otherwise everything is set up to pretend that the category is in fact the
  // interface it extends.
  for (const auto &Protocol : Record->Protocols)
    serializeRelationship(ConformsTo, Record->Interface, Protocol,
                          getModuleForCurrentSymbol());

  return true;
}

bool SymbolGraphSerializer::visitObjCMethodRecord(
    const ObjCMethodRecord *Record) {
  if (!CurrentSymbol)
    return true;

  serializeFunctionSignatureMixin(*CurrentSymbol, *Record);
  return true;
}

bool SymbolGraphSerializer::visitObjCInstanceVariableRecord(
    const ObjCInstanceVariableRecord *Record) {
  // FIXME: serialize ivar access control here.
  return true;
}

bool SymbolGraphSerializer::walkUpFromTypedefRecord(
    const TypedefRecord *Record) {
  // Short-circuit walking up the class hierarchy and handle creating typedef
  // symbol objects manually as there are additional symbol dropping rules to
  // respect.
  return visitTypedefRecord(Record);
}

bool SymbolGraphSerializer::visitTypedefRecord(const TypedefRecord *Record) {
  // Typedefs of anonymous types have their entries unified with the underlying
  // type.
  bool ShouldDrop = Record->UnderlyingType.Name.empty();
  // enums declared with `NS_OPTION` have a named enum and a named typedef, with
  // the same name
  ShouldDrop |= (Record->UnderlyingType.Name == Record->Name);
  if (ShouldDrop)
    return true;

  // Create the symbol record if the other symbol droppping rules permit it.
  serializeAPIRecord(Record);
  if (!CurrentSymbol)
    return true;

  (*CurrentSymbol)["type"] = Record->UnderlyingType.USR;

  return true;
}

void SymbolGraphSerializer::serializeSingleRecord(const APIRecord *Record) {
  switch (Record->getKind()) {
    // dispatch to the relevant walkUpFromMethod
#define CONCRETE_RECORD(CLASS, BASE, KIND)                                     \
  case APIRecord::KIND: {                                                      \
    walkUpFrom##CLASS(static_cast<const CLASS *>(Record));                     \
    break;                                                                     \
  }
#include "clang/ExtractAPI/APIRecords.inc"
  // otherwise fallback on the only behavior we can implement safely.
  case APIRecord::RK_Unknown:
    visitAPIRecord(Record);
    break;
  default:
    llvm_unreachable("API Record with uninstantiable kind");
  }
}

Object SymbolGraphSerializer::serializeGraph(StringRef ModuleName,
                                             ExtendedModule &&EM) {
  Object Root;
  serializeObject(Root, "metadata", serializeMetadata());
  serializeObject(Root, "module", serializeModuleObject(ModuleName));

  Root["symbols"] = std::move(EM.Symbols);
  Root["relationships"] = std::move(EM.Relationships);

  return Root;
}

void SymbolGraphSerializer::serializeGraphToStream(
    raw_ostream &OS, SymbolGraphSerializerOption Options, StringRef ModuleName,
    ExtendedModule &&EM) {
  Object Root = serializeGraph(ModuleName, std::move(EM));
  if (Options.Compact)
    OS << formatv("{0}", json::Value(std::move(Root))) << "\n";
  else
    OS << formatv("{0:2}", json::Value(std::move(Root))) << "\n";
}

void SymbolGraphSerializer::serializeMainSymbolGraph(
    raw_ostream &OS, const APISet &API, const APIIgnoresList &IgnoresList,
    SymbolGraphSerializerOption Options) {
  SymbolGraphSerializer Serializer(
      API, IgnoresList, Options.EmitSymbolLabelsForTesting,
      /*ForceEmitToMainModule=*/true,
      /*SkipSymbolsInCategoriesToExternalTypes=*/true);

  Serializer.traverseAPISet();
  Serializer.serializeGraphToStream(OS, Options, API.ProductName,
                                    std::move(Serializer.MainModule));
  // FIXME: TODO handle extended modules here
}

void SymbolGraphSerializer::serializeWithExtensionGraphs(
    raw_ostream &MainOutput, const APISet &API,
    const APIIgnoresList &IgnoresList,
    llvm::function_ref<std::unique_ptr<llvm::raw_pwrite_stream>(Twine BaseName)>
        CreateOutputStream,
    SymbolGraphSerializerOption Options) {
  SymbolGraphSerializer Serializer(API, IgnoresList,
                                   Options.EmitSymbolLabelsForTesting);
  Serializer.traverseAPISet();

  Serializer.serializeGraphToStream(MainOutput, Options, API.ProductName,
                                    std::move(Serializer.MainModule));

  for (auto &ExtensionSGF : Serializer.ExtendedModules) {
    if (auto ExtensionOS =
            CreateOutputStream(API.ProductName + "@" + ExtensionSGF.getKey()))
      Serializer.serializeGraphToStream(*ExtensionOS, Options, API.ProductName,
                                        std::move(ExtensionSGF.getValue()));
  }
}

std::optional<Object>
SymbolGraphSerializer::serializeSingleSymbolSGF(StringRef USR,
                                                const APISet &API) {
  APIRecord *Record = API.findRecordForUSR(USR);
  if (!Record)
    return {};

  Object Root;
  APIIgnoresList EmptyIgnores;
  SymbolGraphSerializer Serializer(API, EmptyIgnores,
                                   /*EmitSymbolLabelsForTesting*/ false,
                                   /*ForceEmitToMainModule*/ true);

  // Set up serializer parent chain
  Serializer.Hierarchy = generateHierarchyFromRecord(Record);

  Serializer.serializeSingleRecord(Record);
  serializeObject(Root, "symbolGraph",
                  Serializer.serializeGraph(API.ProductName,
                                            std::move(Serializer.MainModule)));

  Language Lang = API.getLanguage();
  serializeArray(Root, "parentContexts",
                 generateParentContexts(Serializer.Hierarchy, Lang));

  Array RelatedSymbols;

  for (const auto &Fragment : Record->Declaration.getFragments()) {
    // If we don't have a USR there isn't much we can do.
    if (Fragment.PreciseIdentifier.empty())
      continue;

    APIRecord *RelatedRecord = API.findRecordForUSR(Fragment.PreciseIdentifier);

    // If we can't find the record let's skip.
    if (!RelatedRecord)
      continue;

    Object RelatedSymbol;
    RelatedSymbol["usr"] = RelatedRecord->USR;
    RelatedSymbol["declarationLanguage"] = getLanguageName(Lang);
    RelatedSymbol["accessLevel"] = RelatedRecord->Access.getAccess();
    RelatedSymbol["filePath"] = RelatedRecord->Location.getFilename();
    RelatedSymbol["moduleName"] = API.ProductName;
    RelatedSymbol["isSystem"] = RelatedRecord->IsFromSystemHeader;

    serializeArray(RelatedSymbol, "parentContexts",
                   generateParentContexts(
                       generateHierarchyFromRecord(RelatedRecord), Lang));

    RelatedSymbols.push_back(std::move(RelatedSymbol));
  }

  serializeArray(Root, "relatedSymbols", RelatedSymbols);
  return Root;
}
