//===-- YAMLSerialization.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
//
//===----------------------------------------------------------------------===//
//
// A YAML index file is a sequence of tagged entries.
// Each entry either encodes a Symbol or the list of references to a symbol
// (a "ref bundle").
//
//===----------------------------------------------------------------------===//

#include "Index.h"
#include "Relation.h"
#include "Serialization.h"
#include "SymbolLocation.h"
#include "SymbolOrigin.h"
#include "dex/Dex.h"
#include "support/Logger.h"
#include "support/Trace.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdint>

LLVM_YAML_IS_SEQUENCE_VECTOR(clang::clangd::Symbol::IncludeHeaderWithReferences)
LLVM_YAML_IS_SEQUENCE_VECTOR(clang::clangd::Ref)

namespace {
using RefBundle =
    std::pair<clang::clangd::SymbolID, std::vector<clang::clangd::Ref>>;
// This is a pale imitation of std::variant<Symbol, RefBundle, Relation>
struct VariantEntry {
  llvm::Optional<clang::clangd::Symbol> Symbol;
  llvm::Optional<RefBundle> Refs;
  llvm::Optional<clang::clangd::Relation> Relation;
  llvm::Optional<clang::clangd::IncludeGraphNode> Source;
  llvm::Optional<clang::tooling::CompileCommand> Cmd;
};
// A class helps YAML to serialize the 32-bit encoded position (Line&Column),
// as YAMLIO can't directly map bitfields.
struct YPosition {
  uint32_t Line;
  uint32_t Column;
};

// avoid ODR violation of specialization for non-owned CompileCommand
struct CompileCommandYAML : clang::tooling::CompileCommand {};

} // namespace
namespace llvm {
namespace yaml {

using clang::clangd::FileDigest;
using clang::clangd::IncludeGraph;
using clang::clangd::IncludeGraphNode;
using clang::clangd::Ref;
using clang::clangd::RefKind;
using clang::clangd::Relation;
using clang::clangd::RelationKind;
using clang::clangd::Symbol;
using clang::clangd::SymbolID;
using clang::clangd::SymbolLocation;
using clang::clangd::SymbolOrigin;
using clang::index::SymbolInfo;
using clang::index::SymbolKind;
using clang::index::SymbolLanguage;
using clang::index::SymbolRole;
using clang::tooling::CompileCommand;

// Helper to (de)serialize the SymbolID. We serialize it as a hex string.
struct NormalizedSymbolID {
  NormalizedSymbolID(IO &) {}
  NormalizedSymbolID(IO &, const SymbolID &ID) {
    llvm::raw_string_ostream OS(HexString);
    OS << ID;
  }

  SymbolID denormalize(IO &I) {
    auto ID = SymbolID::fromStr(HexString);
    if (!ID) {
      I.setError(llvm::toString(ID.takeError()));
      return SymbolID();
    }
    return *ID;
  }

  std::string HexString;
};

struct NormalizedSymbolFlag {
  NormalizedSymbolFlag(IO &) {}
  NormalizedSymbolFlag(IO &, Symbol::SymbolFlag F) {
    Flag = static_cast<uint8_t>(F);
  }

  Symbol::SymbolFlag denormalize(IO &) {
    return static_cast<Symbol::SymbolFlag>(Flag);
  }

  uint8_t Flag = 0;
};

struct NormalizedSymbolOrigin {
  NormalizedSymbolOrigin(IO &) {}
  NormalizedSymbolOrigin(IO &, SymbolOrigin O) {
    Origin = static_cast<uint8_t>(O);
  }

  SymbolOrigin denormalize(IO &) { return static_cast<SymbolOrigin>(Origin); }

  uint8_t Origin = 0;
};

template <> struct MappingTraits<YPosition> {
  static void mapping(IO &IO, YPosition &Value) {
    IO.mapRequired("Line", Value.Line);
    IO.mapRequired("Column", Value.Column);
  }
};

struct NormalizedPosition {
  using Position = clang::clangd::SymbolLocation::Position;
  NormalizedPosition(IO &) {}
  NormalizedPosition(IO &, const Position &Pos) {
    P.Line = Pos.line();
    P.Column = Pos.column();
  }

  Position denormalize(IO &) {
    Position Pos;
    Pos.setLine(P.Line);
    Pos.setColumn(P.Column);
    return Pos;
  }
  YPosition P;
};

struct NormalizedFileURI {
  NormalizedFileURI(IO &) {}
  NormalizedFileURI(IO &, const char *FileURI) { URI = FileURI; }

  const char *denormalize(IO &IO) {
    assert(IO.getContext() &&
           "Expecting an UniqueStringSaver to allocate data");
    return static_cast<llvm::UniqueStringSaver *>(IO.getContext())
        ->save(URI)
        .data();
  }

  std::string URI;
};

template <> struct MappingTraits<SymbolLocation> {
  static void mapping(IO &IO, SymbolLocation &Value) {
    MappingNormalization<NormalizedFileURI, const char *> NFile(IO,
                                                                Value.FileURI);
    IO.mapRequired("FileURI", NFile->URI);
    MappingNormalization<NormalizedPosition, SymbolLocation::Position> NStart(
        IO, Value.Start);
    IO.mapRequired("Start", NStart->P);
    MappingNormalization<NormalizedPosition, SymbolLocation::Position> NEnd(
        IO, Value.End);
    IO.mapRequired("End", NEnd->P);
  }
};

template <> struct MappingTraits<SymbolInfo> {
  static void mapping(IO &io, SymbolInfo &SymInfo) {
    // FIXME: expose other fields?
    io.mapRequired("Kind", SymInfo.Kind);
    io.mapRequired("Lang", SymInfo.Lang);
  }
};

template <>
struct MappingTraits<clang::clangd::Symbol::IncludeHeaderWithReferences> {
  static void mapping(IO &io,
                      clang::clangd::Symbol::IncludeHeaderWithReferences &Inc) {
    io.mapRequired("Header", Inc.IncludeHeader);
    io.mapRequired("References", Inc.References);
  }
};

template <> struct MappingTraits<Symbol> {
  static void mapping(IO &IO, Symbol &Sym) {
    MappingNormalization<NormalizedSymbolID, SymbolID> NSymbolID(IO, Sym.ID);
    MappingNormalization<NormalizedSymbolFlag, Symbol::SymbolFlag> NSymbolFlag(
        IO, Sym.Flags);
    MappingNormalization<NormalizedSymbolOrigin, SymbolOrigin> NSymbolOrigin(
        IO, Sym.Origin);
    IO.mapRequired("ID", NSymbolID->HexString);
    IO.mapRequired("Name", Sym.Name);
    IO.mapRequired("Scope", Sym.Scope);
    IO.mapRequired("SymInfo", Sym.SymInfo);
    IO.mapOptional("CanonicalDeclaration", Sym.CanonicalDeclaration,
                   SymbolLocation());
    IO.mapOptional("Definition", Sym.Definition, SymbolLocation());
    IO.mapOptional("References", Sym.References, 0u);
    IO.mapOptional("Origin", NSymbolOrigin->Origin);
    IO.mapOptional("Flags", NSymbolFlag->Flag);
    IO.mapOptional("Signature", Sym.Signature);
    IO.mapOptional("TemplateSpecializationArgs",
                   Sym.TemplateSpecializationArgs);
    IO.mapOptional("CompletionSnippetSuffix", Sym.CompletionSnippetSuffix);
    IO.mapOptional("Documentation", Sym.Documentation);
    IO.mapOptional("ReturnType", Sym.ReturnType);
    IO.mapOptional("Type", Sym.Type);
    IO.mapOptional("IncludeHeaders", Sym.IncludeHeaders);
  }
};

template <> struct ScalarEnumerationTraits<SymbolLanguage> {
  static void enumeration(IO &IO, SymbolLanguage &Value) {
    IO.enumCase(Value, "C", SymbolLanguage::C);
    IO.enumCase(Value, "Cpp", SymbolLanguage::CXX);
    IO.enumCase(Value, "ObjC", SymbolLanguage::ObjC);
    IO.enumCase(Value, "Swift", SymbolLanguage::Swift);
  }
};

template <> struct ScalarEnumerationTraits<SymbolKind> {
  static void enumeration(IO &IO, SymbolKind &Value) {
#define DEFINE_ENUM(name) IO.enumCase(Value, #name, SymbolKind::name)

    DEFINE_ENUM(Unknown);
    DEFINE_ENUM(Function);
    DEFINE_ENUM(Module);
    DEFINE_ENUM(Namespace);
    DEFINE_ENUM(NamespaceAlias);
    DEFINE_ENUM(Macro);
    DEFINE_ENUM(Enum);
    DEFINE_ENUM(Struct);
    DEFINE_ENUM(Class);
    DEFINE_ENUM(Protocol);
    DEFINE_ENUM(Extension);
    DEFINE_ENUM(Union);
    DEFINE_ENUM(TypeAlias);
    DEFINE_ENUM(Function);
    DEFINE_ENUM(Variable);
    DEFINE_ENUM(Field);
    DEFINE_ENUM(EnumConstant);
    DEFINE_ENUM(InstanceMethod);
    DEFINE_ENUM(ClassMethod);
    DEFINE_ENUM(StaticMethod);
    DEFINE_ENUM(InstanceProperty);
    DEFINE_ENUM(ClassProperty);
    DEFINE_ENUM(StaticProperty);
    DEFINE_ENUM(Constructor);
    DEFINE_ENUM(Destructor);
    DEFINE_ENUM(ConversionFunction);
    DEFINE_ENUM(Parameter);
    DEFINE_ENUM(Using);

#undef DEFINE_ENUM
  }
};

template <> struct MappingTraits<RefBundle> {
  static void mapping(IO &IO, RefBundle &Refs) {
    MappingNormalization<NormalizedSymbolID, SymbolID> NSymbolID(IO,
                                                                 Refs.first);
    IO.mapRequired("ID", NSymbolID->HexString);
    IO.mapRequired("References", Refs.second);
  }
};

struct NormalizedRefKind {
  NormalizedRefKind(IO &) {}
  NormalizedRefKind(IO &, RefKind O) { Kind = static_cast<uint8_t>(O); }

  RefKind denormalize(IO &) { return static_cast<RefKind>(Kind); }

  uint8_t Kind = 0;
};

template <> struct MappingTraits<Ref> {
  static void mapping(IO &IO, Ref &R) {
    MappingNormalization<NormalizedRefKind, RefKind> NKind(IO, R.Kind);
    IO.mapRequired("Kind", NKind->Kind);
    IO.mapRequired("Location", R.Location);
  }
};

struct NormalizedSymbolRole {
  NormalizedSymbolRole(IO &) {}
  NormalizedSymbolRole(IO &IO, RelationKind R) {
    Kind = static_cast<uint8_t>(R);
  }

  RelationKind denormalize(IO &IO) { return static_cast<RelationKind>(Kind); }

  uint8_t Kind = 0;
};

template <> struct MappingTraits<SymbolID> {
  static void mapping(IO &IO, SymbolID &ID) {
    MappingNormalization<NormalizedSymbolID, SymbolID> NSymbolID(IO, ID);
    IO.mapRequired("ID", NSymbolID->HexString);
  }
};

template <> struct MappingTraits<Relation> {
  static void mapping(IO &IO, Relation &Relation) {
    MappingNormalization<NormalizedSymbolRole, RelationKind> NRole(
        IO, Relation.Predicate);
    IO.mapRequired("Subject", Relation.Subject);
    IO.mapRequired("Predicate", NRole->Kind);
    IO.mapRequired("Object", Relation.Object);
  }
};

struct NormalizedSourceFlag {
  NormalizedSourceFlag(IO &) {}
  NormalizedSourceFlag(IO &, IncludeGraphNode::SourceFlag O) {
    Flag = static_cast<uint8_t>(O);
  }

  IncludeGraphNode::SourceFlag denormalize(IO &) {
    return static_cast<IncludeGraphNode::SourceFlag>(Flag);
  }

  uint8_t Flag = 0;
};

struct NormalizedFileDigest {
  NormalizedFileDigest(IO &) {}
  NormalizedFileDigest(IO &, const FileDigest &Digest) {
    HexString = llvm::toHex(Digest);
  }

  FileDigest denormalize(IO &I) {
    FileDigest Digest;
    if (HexString.size() == Digest.size() * 2 &&
        llvm::all_of(HexString, llvm::isHexDigit)) {
      memcpy(Digest.data(), llvm::fromHex(HexString).data(), Digest.size());
    } else {
      I.setError(std::string("Bad hex file digest: ") + HexString);
    }
    return Digest;
  }

  std::string HexString;
};

template <> struct MappingTraits<IncludeGraphNode> {
  static void mapping(IO &IO, IncludeGraphNode &Node) {
    IO.mapRequired("URI", Node.URI);
    MappingNormalization<NormalizedSourceFlag, IncludeGraphNode::SourceFlag>
        NSourceFlag(IO, Node.Flags);
    IO.mapRequired("Flags", NSourceFlag->Flag);
    MappingNormalization<NormalizedFileDigest, FileDigest> NDigest(IO,
                                                                   Node.Digest);
    IO.mapRequired("Digest", NDigest->HexString);
    IO.mapRequired("DirectIncludes", Node.DirectIncludes);
  }
};

template <> struct MappingTraits<CompileCommandYAML> {
  static void mapping(IO &IO, CompileCommandYAML &Cmd) {
    IO.mapRequired("Directory", Cmd.Directory);
    IO.mapRequired("CommandLine", Cmd.CommandLine);
  }
};

template <> struct MappingTraits<VariantEntry> {
  static void mapping(IO &IO, VariantEntry &Variant) {
    if (IO.mapTag("!Symbol", Variant.Symbol.hasValue())) {
      if (!IO.outputting())
        Variant.Symbol.emplace();
      MappingTraits<Symbol>::mapping(IO, *Variant.Symbol);
    } else if (IO.mapTag("!Refs", Variant.Refs.hasValue())) {
      if (!IO.outputting())
        Variant.Refs.emplace();
      MappingTraits<RefBundle>::mapping(IO, *Variant.Refs);
    } else if (IO.mapTag("!Relations", Variant.Relation.hasValue())) {
      if (!IO.outputting())
        Variant.Relation.emplace();
      MappingTraits<Relation>::mapping(IO, *Variant.Relation);
    } else if (IO.mapTag("!Source", Variant.Source.hasValue())) {
      if (!IO.outputting())
        Variant.Source.emplace();
      MappingTraits<IncludeGraphNode>::mapping(IO, *Variant.Source);
    } else if (IO.mapTag("!Cmd", Variant.Cmd.hasValue())) {
      if (!IO.outputting())
        Variant.Cmd.emplace();
      MappingTraits<CompileCommandYAML>::mapping(
          IO, static_cast<CompileCommandYAML &>(*Variant.Cmd));
    }
  }
};

} // namespace yaml
} // namespace llvm

namespace clang {
namespace clangd {

void writeYAML(const IndexFileOut &O, llvm::raw_ostream &OS) {
  llvm::yaml::Output Yout(OS);
  for (const auto &Sym : *O.Symbols) {
    VariantEntry Entry;
    Entry.Symbol = Sym;
    Yout << Entry;
  }
  if (O.Refs)
    for (auto &Sym : *O.Refs) {
      VariantEntry Entry;
      Entry.Refs = Sym;
      Yout << Entry;
    }
  if (O.Relations)
    for (auto &R : *O.Relations) {
      VariantEntry Entry;
      Entry.Relation = R;
      Yout << Entry;
    }
  if (O.Sources) {
    for (const auto &Source : *O.Sources) {
      VariantEntry Entry;
      Entry.Source = Source.getValue();
      Yout << Entry;
    }
  }
  if (O.Cmd) {
    VariantEntry Entry;
    Entry.Cmd = *O.Cmd;
    Yout << Entry;
  }
}

llvm::Expected<IndexFileIn> readYAML(llvm::StringRef Data) {
  SymbolSlab::Builder Symbols;
  RefSlab::Builder Refs;
  RelationSlab::Builder Relations;
  llvm::BumpPtrAllocator
      Arena; // store the underlying data of Position::FileURI.
  llvm::UniqueStringSaver Strings(Arena);
  llvm::yaml::Input Yin(Data, &Strings);
  IncludeGraph Sources;
  llvm::Optional<tooling::CompileCommand> Cmd;
  while (Yin.setCurrentDocument()) {
    llvm::yaml::EmptyContext Ctx;
    VariantEntry Variant;
    yamlize(Yin, Variant, true, Ctx);
    if (Yin.error())
      return llvm::errorCodeToError(Yin.error());

    if (Variant.Symbol)
      Symbols.insert(*Variant.Symbol);
    if (Variant.Refs)
      for (const auto &Ref : Variant.Refs->second)
        Refs.insert(Variant.Refs->first, Ref);
    if (Variant.Relation)
      Relations.insert(*Variant.Relation);
    if (Variant.Source) {
      auto &IGN = Variant.Source.getValue();
      auto Entry = Sources.try_emplace(IGN.URI).first;
      Entry->getValue() = std::move(IGN);
      // Fixup refs to refer to map keys which will live on
      Entry->getValue().URI = Entry->getKey();
      for (auto &Include : Entry->getValue().DirectIncludes)
        Include = Sources.try_emplace(Include).first->getKey();
    }
    if (Variant.Cmd)
      Cmd = *Variant.Cmd;
    Yin.nextDocument();
  }

  IndexFileIn Result;
  Result.Symbols.emplace(std::move(Symbols).build());
  Result.Refs.emplace(std::move(Refs).build());
  Result.Relations.emplace(std::move(Relations).build());
  if (Sources.size())
    Result.Sources = std::move(Sources);
  Result.Cmd = std::move(Cmd);
  return std::move(Result);
}

std::string toYAML(const Symbol &S) {
  std::string Buf;
  {
    llvm::raw_string_ostream OS(Buf);
    llvm::yaml::Output Yout(OS);
    Symbol Sym = S; // copy: Yout<< requires mutability.
    Yout << Sym;
  }
  return Buf;
}

std::string toYAML(const std::pair<SymbolID, llvm::ArrayRef<Ref>> &Data) {
  RefBundle Refs = {Data.first, Data.second};
  std::string Buf;
  {
    llvm::raw_string_ostream OS(Buf);
    llvm::yaml::Output Yout(OS);
    Yout << Refs;
  }
  return Buf;
}

std::string toYAML(const Relation &R) {
  std::string Buf;
  {
    llvm::raw_string_ostream OS(Buf);
    llvm::yaml::Output Yout(OS);
    Relation Rel = R; // copy: Yout<< requires mutability.
    Yout << Rel;
  }
  return Buf;
}

std::string toYAML(const Ref &R) {
  std::string Buf;
  {
    llvm::raw_string_ostream OS(Buf);
    llvm::yaml::Output Yout(OS);
    Ref Reference = R; // copy: Yout<< requires mutability.
    Yout << Reference;
  }
  return Buf;
}

llvm::Expected<clangd::Symbol>
symbolFromYAML(StringRef YAML, llvm::UniqueStringSaver *Strings) {
  clangd::Symbol Deserialized;
  llvm::yaml::Input YAMLInput(YAML, Strings);
  if (YAMLInput.error())
    return error("Unable to deserialize Symbol from YAML: {0}", YAML);
  YAMLInput >> Deserialized;
  return Deserialized;
}

llvm::Expected<clangd::Ref> refFromYAML(StringRef YAML,
                                        llvm::UniqueStringSaver *Strings) {
  clangd::Ref Deserialized;
  llvm::yaml::Input YAMLInput(YAML, Strings);
  if (YAMLInput.error())
    return error("Unable to deserialize Symbol from YAML: {0}", YAML);
  YAMLInput >> Deserialized;
  return Deserialized;
}

} // namespace clangd
} // namespace clang
