//===- 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/Casting.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>
#include <type_traits>

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::RenderScript:
  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;
  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(ExtensionSGF.getKey() + "@" + API.ProductName))
      Serializer.serializeGraphToStream(*ExtensionOS, Options,
                                        ExtensionSGF.getKey(),
                                        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;
}
