//===--- Protocol.cpp - Language Server Protocol Implementation -----------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file contains the serialization code for the LSP structs.
//
//===----------------------------------------------------------------------===//

#include "Protocol.h"
#include "URI.h"
#include "support/Logger.h"
#include "clang/Basic/LLVM.h"
#include "clang/Index/IndexSymbol.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

namespace clang {
namespace clangd {
namespace {

// Helper that doesn't treat `null` and absent fields as failures.
template <typename T>
bool mapOptOrNull(const llvm::json::Value &Params, llvm::StringLiteral Prop,
                  T &Out, llvm::json::Path P) {
  auto *O = Params.getAsObject();
  assert(O);
  auto *V = O->get(Prop);
  // Field is missing or null.
  if (!V || V->getAsNull())
    return true;
  return fromJSON(*V, Out, P.field(Prop));
}
} // namespace

char LSPError::ID;

URIForFile URIForFile::canonicalize(llvm::StringRef AbsPath,
                                    llvm::StringRef TUPath) {
  assert(llvm::sys::path::is_absolute(AbsPath) && "the path is relative");
  auto Resolved = URI::resolvePath(AbsPath, TUPath);
  if (!Resolved) {
    elog("URIForFile: failed to resolve path {0} with TU path {1}: "
         "{2}.\nUsing unresolved path.",
         AbsPath, TUPath, Resolved.takeError());
    return URIForFile(std::string(AbsPath));
  }
  return URIForFile(std::move(*Resolved));
}

llvm::Expected<URIForFile> URIForFile::fromURI(const URI &U,
                                               llvm::StringRef HintPath) {
  auto Resolved = URI::resolve(U, HintPath);
  if (!Resolved)
    return Resolved.takeError();
  return URIForFile(std::move(*Resolved));
}

bool fromJSON(const llvm::json::Value &E, URIForFile &R, llvm::json::Path P) {
  if (auto S = E.getAsString()) {
    auto Parsed = URI::parse(*S);
    if (!Parsed) {
      consumeError(Parsed.takeError());
      P.report("failed to parse URI");
      return false;
    }
    if (Parsed->scheme() != "file" && Parsed->scheme() != "test") {
      P.report("clangd only supports 'file' URI scheme for workspace files");
      return false;
    }
    // "file" and "test" schemes do not require hint path.
    auto U = URIForFile::fromURI(*Parsed, /*HintPath=*/"");
    if (!U) {
      P.report("unresolvable URI");
      consumeError(U.takeError());
      return false;
    }
    R = std::move(*U);
    return true;
  }
  return false;
}

llvm::json::Value toJSON(const URIForFile &U) { return U.uri(); }

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const URIForFile &U) {
  return OS << U.uri();
}

llvm::json::Value toJSON(const TextDocumentIdentifier &R) {
  return llvm::json::Object{{"uri", R.uri}};
}

bool fromJSON(const llvm::json::Value &Params, TextDocumentIdentifier &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("uri", R.uri);
}

llvm::json::Value toJSON(const VersionedTextDocumentIdentifier &R) {
  auto Result = toJSON(static_cast<const TextDocumentIdentifier &>(R));
  Result.getAsObject()->try_emplace("version", R.version);
  return Result;
}

bool fromJSON(const llvm::json::Value &Params,
              VersionedTextDocumentIdentifier &R, llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return fromJSON(Params, static_cast<TextDocumentIdentifier &>(R), P) && O &&
         O.map("version", R.version);
}

bool fromJSON(const llvm::json::Value &Params, Position &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("line", R.line) && O.map("character", R.character);
}

llvm::json::Value toJSON(const Position &P) {
  return llvm::json::Object{
      {"line", P.line},
      {"character", P.character},
  };
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Position &P) {
  return OS << P.line << ':' << P.character;
}

bool fromJSON(const llvm::json::Value &Params, Range &R, llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("start", R.start) && O.map("end", R.end);
}

llvm::json::Value toJSON(const Range &P) {
  return llvm::json::Object{
      {"start", P.start},
      {"end", P.end},
  };
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Range &R) {
  return OS << R.start << '-' << R.end;
}

llvm::json::Value toJSON(const Location &P) {
  return llvm::json::Object{
      {"uri", P.uri},
      {"range", P.range},
  };
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Location &L) {
  return OS << L.range << '@' << L.uri;
}

llvm::json::Value toJSON(const ReferenceLocation &P) {
  llvm::json::Object Result{
      {"uri", P.uri},
      {"range", P.range},
  };
  if (P.containerName)
    Result.insert({"containerName", P.containerName});
  return Result;
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
                              const ReferenceLocation &L) {
  return OS << L.range << '@' << L.uri << " (container: " << L.containerName
            << ")";
}

bool fromJSON(const llvm::json::Value &Params, TextDocumentItem &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("uri", R.uri) && O.map("languageId", R.languageId) &&
         O.map("version", R.version) && O.map("text", R.text);
}

bool fromJSON(const llvm::json::Value &Params, TextEdit &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("range", R.range) && O.map("newText", R.newText) &&
         O.mapOptional("annotationId", R.annotationId);
}

llvm::json::Value toJSON(const TextEdit &P) {
  llvm::json::Object Result{
      {"range", P.range},
      {"newText", P.newText},
  };
  if (!P.annotationId.empty())
    Result["annotationId"] = P.annotationId;
  return Result;
}

bool fromJSON(const llvm::json::Value &Params, ChangeAnnotation &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("label", R.label) &&
         O.map("needsConfirmation", R.needsConfirmation) &&
         O.mapOptional("description", R.description);
}
llvm::json::Value toJSON(const ChangeAnnotation & CA) {
  llvm::json::Object Result{{"label", CA.label}};
  if (CA.needsConfirmation)
    Result["needsConfirmation"] = *CA.needsConfirmation;
  if (!CA.description.empty())
    Result["description"] = CA.description;
  return Result;
}

bool fromJSON(const llvm::json::Value &Params, TextDocumentEdit &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument) && O.map("edits", R.edits);
}
llvm::json::Value toJSON(const TextDocumentEdit &P) {
  llvm::json::Object Result{{"textDocument", P.textDocument},
                            {"edits", P.edits}};
  return Result;
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const TextEdit &TE) {
  OS << TE.range << " => \"";
  llvm::printEscapedString(TE.newText, OS);
  return OS << '"';
}

bool fromJSON(const llvm::json::Value &E, TraceLevel &Out, llvm::json::Path P) {
  if (auto S = E.getAsString()) {
    if (*S == "off") {
      Out = TraceLevel::Off;
      return true;
    }
    if (*S == "messages") {
      Out = TraceLevel::Messages;
      return true;
    }
    if (*S == "verbose") {
      Out = TraceLevel::Verbose;
      return true;
    }
  }
  return false;
}

bool fromJSON(const llvm::json::Value &E, SymbolKind &Out, llvm::json::Path P) {
  if (auto T = E.getAsInteger()) {
    if (*T < static_cast<int>(SymbolKind::File) ||
        *T > static_cast<int>(SymbolKind::TypeParameter))
      return false;
    Out = static_cast<SymbolKind>(*T);
    return true;
  }
  return false;
}

bool fromJSON(const llvm::json::Value &E, SymbolKindBitset &Out,
              llvm::json::Path P) {
  if (auto *A = E.getAsArray()) {
    for (size_t I = 0; I < A->size(); ++I) {
      SymbolKind KindOut;
      if (fromJSON((*A)[I], KindOut, P.index(I)))
        Out.set(size_t(KindOut));
    }
    return true;
  }
  return false;
}

SymbolKind adjustKindToCapability(SymbolKind Kind,
                                  SymbolKindBitset &SupportedSymbolKinds) {
  auto KindVal = static_cast<size_t>(Kind);
  if (KindVal >= SymbolKindMin && KindVal <= SupportedSymbolKinds.size() &&
      SupportedSymbolKinds[KindVal])
    return Kind;

  switch (Kind) {
  // Provide some fall backs for common kinds that are close enough.
  case SymbolKind::Struct:
    return SymbolKind::Class;
  case SymbolKind::EnumMember:
    return SymbolKind::Enum;
  default:
    return SymbolKind::String;
  }
}

SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind) {
  switch (Kind) {
  case index::SymbolKind::Unknown:
    return SymbolKind::Variable;
  case index::SymbolKind::Module:
    return SymbolKind::Module;
  case index::SymbolKind::Namespace:
    return SymbolKind::Namespace;
  case index::SymbolKind::NamespaceAlias:
    return SymbolKind::Namespace;
  case index::SymbolKind::Macro:
    return SymbolKind::String;
  case index::SymbolKind::Enum:
    return SymbolKind::Enum;
  case index::SymbolKind::Struct:
    return SymbolKind::Struct;
  case index::SymbolKind::Class:
    return SymbolKind::Class;
  case index::SymbolKind::Protocol:
    return SymbolKind::Interface;
  case index::SymbolKind::Extension:
    return SymbolKind::Interface;
  case index::SymbolKind::Union:
    return SymbolKind::Class;
  case index::SymbolKind::TypeAlias:
    return SymbolKind::Class;
  case index::SymbolKind::Function:
    return SymbolKind::Function;
  case index::SymbolKind::Variable:
    return SymbolKind::Variable;
  case index::SymbolKind::Field:
    return SymbolKind::Field;
  case index::SymbolKind::EnumConstant:
    return SymbolKind::EnumMember;
  case index::SymbolKind::InstanceMethod:
  case index::SymbolKind::ClassMethod:
  case index::SymbolKind::StaticMethod:
    return SymbolKind::Method;
  case index::SymbolKind::InstanceProperty:
  case index::SymbolKind::ClassProperty:
  case index::SymbolKind::StaticProperty:
    return SymbolKind::Property;
  case index::SymbolKind::Constructor:
  case index::SymbolKind::Destructor:
    return SymbolKind::Constructor;
  case index::SymbolKind::ConversionFunction:
    return SymbolKind::Function;
  case index::SymbolKind::Parameter:
  case index::SymbolKind::NonTypeTemplateParm:
    return SymbolKind::Variable;
  case index::SymbolKind::Using:
    return SymbolKind::Namespace;
  case index::SymbolKind::TemplateTemplateParm:
  case index::SymbolKind::TemplateTypeParm:
    return SymbolKind::TypeParameter;
  case index::SymbolKind::Concept:
    return SymbolKind::Interface;
  }
  llvm_unreachable("invalid symbol kind");
}

bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R,
              llvm::json::Path P) {
  const llvm::json::Object *O = Params.getAsObject();
  if (!O) {
    P.report("expected object");
    return false;
  }
  if (auto *TextDocument = O->getObject("textDocument")) {
    if (auto *SemanticHighlighting =
            TextDocument->getObject("semanticHighlightingCapabilities")) {
      if (auto SemanticHighlightingSupport =
              SemanticHighlighting->getBoolean("semanticHighlighting"))
        R.TheiaSemanticHighlighting = *SemanticHighlightingSupport;
    }
    if (auto *InactiveRegions =
            TextDocument->getObject("inactiveRegionsCapabilities")) {
      if (auto InactiveRegionsSupport =
              InactiveRegions->getBoolean("inactiveRegions")) {
        R.InactiveRegions = *InactiveRegionsSupport;
      }
    }
    if (TextDocument->getObject("semanticTokens"))
      R.SemanticTokens = true;
    if (auto *Diagnostics = TextDocument->getObject("publishDiagnostics")) {
      if (auto CategorySupport = Diagnostics->getBoolean("categorySupport"))
        R.DiagnosticCategory = *CategorySupport;
      if (auto CodeActions = Diagnostics->getBoolean("codeActionsInline"))
        R.DiagnosticFixes = *CodeActions;
      if (auto RelatedInfo = Diagnostics->getBoolean("relatedInformation"))
        R.DiagnosticRelatedInformation = *RelatedInfo;
    }
    if (auto *References = TextDocument->getObject("references"))
      if (auto ContainerSupport = References->getBoolean("container"))
        R.ReferenceContainer = *ContainerSupport;
    if (auto *Completion = TextDocument->getObject("completion")) {
      if (auto *Item = Completion->getObject("completionItem")) {
        if (auto SnippetSupport = Item->getBoolean("snippetSupport"))
          R.CompletionSnippets = *SnippetSupport;
        if (auto LabelDetailsSupport = Item->getBoolean("labelDetailsSupport"))
          R.CompletionLabelDetail = *LabelDetailsSupport;
        if (const auto *DocumentationFormat =
                Item->getArray("documentationFormat")) {
          for (const auto &Format : *DocumentationFormat) {
            if (fromJSON(Format, R.CompletionDocumentationFormat, P))
              break;
          }
        }
      }
      if (auto *ItemKind = Completion->getObject("completionItemKind")) {
        if (auto *ValueSet = ItemKind->get("valueSet")) {
          R.CompletionItemKinds.emplace();
          if (!fromJSON(*ValueSet, *R.CompletionItemKinds,
                        P.field("textDocument")
                            .field("completion")
                            .field("completionItemKind")
                            .field("valueSet")))
            return false;
        }
      }
      if (auto EditsNearCursor = Completion->getBoolean("editsNearCursor"))
        R.CompletionFixes = *EditsNearCursor;
    }
    if (auto *CodeAction = TextDocument->getObject("codeAction")) {
      if (CodeAction->getObject("codeActionLiteralSupport"))
        R.CodeActionStructure = true;
    }
    if (auto *DocumentSymbol = TextDocument->getObject("documentSymbol")) {
      if (auto HierarchicalSupport =
              DocumentSymbol->getBoolean("hierarchicalDocumentSymbolSupport"))
        R.HierarchicalDocumentSymbol = *HierarchicalSupport;
    }
    if (auto *Hover = TextDocument->getObject("hover")) {
      if (auto *ContentFormat = Hover->getArray("contentFormat")) {
        for (const auto &Format : *ContentFormat) {
          if (fromJSON(Format, R.HoverContentFormat, P))
            break;
        }
      }
    }
    if (auto *Help = TextDocument->getObject("signatureHelp")) {
      R.HasSignatureHelp = true;
      if (auto *Info = Help->getObject("signatureInformation")) {
        if (auto *Parameter = Info->getObject("parameterInformation")) {
          if (auto OffsetSupport = Parameter->getBoolean("labelOffsetSupport"))
            R.OffsetsInSignatureHelp = *OffsetSupport;
        }
        if (const auto *DocumentationFormat =
                Info->getArray("documentationFormat")) {
          for (const auto &Format : *DocumentationFormat) {
            if (fromJSON(Format, R.SignatureHelpDocumentationFormat, P))
              break;
          }
        }
      }
    }
    if (auto *Folding = TextDocument->getObject("foldingRange")) {
      if (auto LineFolding = Folding->getBoolean("lineFoldingOnly"))
        R.LineFoldingOnly = *LineFolding;
    }
    if (auto *Rename = TextDocument->getObject("rename")) {
      if (auto RenameSupport = Rename->getBoolean("prepareSupport"))
        R.RenamePrepareSupport = *RenameSupport;
    }
  }
  if (auto *Workspace = O->getObject("workspace")) {
    if (auto *Symbol = Workspace->getObject("symbol")) {
      if (auto *SymbolKind = Symbol->getObject("symbolKind")) {
        if (auto *ValueSet = SymbolKind->get("valueSet")) {
          R.WorkspaceSymbolKinds.emplace();
          if (!fromJSON(*ValueSet, *R.WorkspaceSymbolKinds,
                        P.field("workspace")
                            .field("symbol")
                            .field("symbolKind")
                            .field("valueSet")))
            return false;
        }
      }
    }
    if (auto *SemanticTokens = Workspace->getObject("semanticTokens")) {
      if (auto RefreshSupport = SemanticTokens->getBoolean("refreshSupport"))
        R.SemanticTokenRefreshSupport = *RefreshSupport;
    }
    if (auto *WorkspaceEdit = Workspace->getObject("workspaceEdit")) {
      if (auto DocumentChanges = WorkspaceEdit->getBoolean("documentChanges"))
        R.DocumentChanges = *DocumentChanges;
      if (WorkspaceEdit->getObject("changeAnnotationSupport")) {
        R.ChangeAnnotation = true;
      }
    }
  }
  if (auto *Window = O->getObject("window")) {
    if (auto WorkDoneProgress = Window->getBoolean("workDoneProgress"))
      R.WorkDoneProgress = *WorkDoneProgress;
    if (auto Implicit = Window->getBoolean("implicitWorkDoneProgressCreate"))
      R.ImplicitProgressCreation = *Implicit;
  }
  if (auto *General = O->getObject("general")) {
    if (auto *StaleRequestSupport = General->getObject("staleRequestSupport")) {
      if (auto Cancel = StaleRequestSupport->getBoolean("cancel"))
        R.CancelsStaleRequests = *Cancel;
    }
  }
  if (auto *OffsetEncoding = O->get("offsetEncoding")) {
    R.offsetEncoding.emplace();
    if (!fromJSON(*OffsetEncoding, *R.offsetEncoding,
                  P.field("offsetEncoding")))
      return false;
  }
  return true;
}

bool fromJSON(const llvm::json::Value &Params, InitializeParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  if (!O)
    return false;
  // We deliberately don't fail if we can't parse individual fields.
  // Failing to handle a slightly malformed initialize would be a disaster.
  O.map("processId", R.processId);
  O.map("rootUri", R.rootUri);
  O.map("rootPath", R.rootPath);
  O.map("capabilities", R.capabilities);
  if (auto *RawCaps = Params.getAsObject()->getObject("capabilities"))
    R.rawCapabilities = *RawCaps;
  O.map("trace", R.trace);
  O.map("initializationOptions", R.initializationOptions);
  return true;
}

llvm::json::Value toJSON(const WorkDoneProgressCreateParams &P) {
  return llvm::json::Object{{"token", P.token}};
}

llvm::json::Value toJSON(const WorkDoneProgressBegin &P) {
  llvm::json::Object Result{
      {"kind", "begin"},
      {"title", P.title},
  };
  if (P.cancellable)
    Result["cancellable"] = true;
  if (P.percentage)
    Result["percentage"] = 0;

  // FIXME: workaround for older gcc/clang
  return std::move(Result);
}

llvm::json::Value toJSON(const WorkDoneProgressReport &P) {
  llvm::json::Object Result{{"kind", "report"}};
  if (P.cancellable)
    Result["cancellable"] = *P.cancellable;
  if (P.message)
    Result["message"] = *P.message;
  if (P.percentage)
    Result["percentage"] = *P.percentage;
  // FIXME: workaround for older gcc/clang
  return std::move(Result);
}

llvm::json::Value toJSON(const WorkDoneProgressEnd &P) {
  llvm::json::Object Result{{"kind", "end"}};
  if (P.message)
    Result["message"] = *P.message;
  // FIXME: workaround for older gcc/clang
  return std::move(Result);
}

llvm::json::Value toJSON(const MessageType &R) {
  return static_cast<int64_t>(R);
}

llvm::json::Value toJSON(const ShowMessageParams &R) {
  return llvm::json::Object{{"type", R.type}, {"message", R.message}};
}

bool fromJSON(const llvm::json::Value &Params, DidOpenTextDocumentParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument);
}

bool fromJSON(const llvm::json::Value &Params, DidCloseTextDocumentParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument);
}

bool fromJSON(const llvm::json::Value &Params, DidSaveTextDocumentParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument);
}

bool fromJSON(const llvm::json::Value &Params, DidChangeTextDocumentParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument) &&
         O.map("contentChanges", R.contentChanges) &&
         O.map("wantDiagnostics", R.wantDiagnostics) &&
         mapOptOrNull(Params, "forceRebuild", R.forceRebuild, P);
}

bool fromJSON(const llvm::json::Value &E, FileChangeType &Out,
              llvm::json::Path P) {
  if (auto T = E.getAsInteger()) {
    if (*T < static_cast<int>(FileChangeType::Created) ||
        *T > static_cast<int>(FileChangeType::Deleted))
      return false;
    Out = static_cast<FileChangeType>(*T);
    return true;
  }
  return false;
}

bool fromJSON(const llvm::json::Value &Params, FileEvent &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("uri", R.uri) && O.map("type", R.type);
}

bool fromJSON(const llvm::json::Value &Params, DidChangeWatchedFilesParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("changes", R.changes);
}

bool fromJSON(const llvm::json::Value &Params,
              TextDocumentContentChangeEvent &R, llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("range", R.range) && O.map("rangeLength", R.rangeLength) &&
         O.map("text", R.text);
}

bool fromJSON(const llvm::json::Value &Params, DocumentRangeFormattingParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument) && O.map("range", R.range);
}

bool fromJSON(const llvm::json::Value &Params,
              DocumentOnTypeFormattingParams &R, llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument) &&
         O.map("position", R.position) && O.map("ch", R.ch);
}

bool fromJSON(const llvm::json::Value &Params, DocumentFormattingParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument);
}

bool fromJSON(const llvm::json::Value &Params, DocumentSymbolParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument);
}

llvm::json::Value toJSON(const DiagnosticRelatedInformation &DRI) {
  return llvm::json::Object{
      {"location", DRI.location},
      {"message", DRI.message},
  };
}

llvm::json::Value toJSON(DiagnosticTag Tag) { return static_cast<int>(Tag); }

llvm::json::Value toJSON(const CodeDescription &D) {
  return llvm::json::Object{{"href", D.href}};
}

llvm::json::Value toJSON(const Diagnostic &D) {
  llvm::json::Object Diag{
      {"range", D.range},
      {"severity", D.severity},
      {"message", D.message},
  };
  if (D.category)
    Diag["category"] = *D.category;
  if (D.codeActions)
    Diag["codeActions"] = D.codeActions;
  if (!D.code.empty())
    Diag["code"] = D.code;
  if (D.codeDescription)
    Diag["codeDescription"] = *D.codeDescription;
  if (!D.source.empty())
    Diag["source"] = D.source;
  if (D.relatedInformation)
    Diag["relatedInformation"] = *D.relatedInformation;
  if (!D.data.empty())
    Diag["data"] = llvm::json::Object(D.data);
  if (!D.tags.empty())
    Diag["tags"] = llvm::json::Array{D.tags};
  // FIXME: workaround for older gcc/clang
  return std::move(Diag);
}

bool fromJSON(const llvm::json::Value &Params, Diagnostic &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  if (!O)
    return false;
  if (auto *Data = Params.getAsObject()->getObject("data"))
    R.data = *Data;
  return O.map("range", R.range) && O.map("message", R.message) &&
         mapOptOrNull(Params, "severity", R.severity, P) &&
         mapOptOrNull(Params, "category", R.category, P) &&
         mapOptOrNull(Params, "code", R.code, P) &&
         mapOptOrNull(Params, "source", R.source, P);
}

llvm::json::Value toJSON(const PublishDiagnosticsParams &PDP) {
  llvm::json::Object Result{
      {"uri", PDP.uri},
      {"diagnostics", PDP.diagnostics},
  };
  if (PDP.version)
    Result["version"] = PDP.version;
  return std::move(Result);
}

bool fromJSON(const llvm::json::Value &Params, CodeActionContext &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  if (!O || !O.map("diagnostics", R.diagnostics))
    return false;
  O.map("only", R.only);
  return true;
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Diagnostic &D) {
  OS << D.range << " [";
  switch (D.severity) {
  case 1:
    OS << "error";
    break;
  case 2:
    OS << "warning";
    break;
  case 3:
    OS << "note";
    break;
  case 4:
    OS << "remark";
    break;
  default:
    OS << "diagnostic";
    break;
  }
  return OS << '(' << D.severity << "): " << D.message << "]";
}

bool fromJSON(const llvm::json::Value &Params, CodeActionParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument) &&
         O.map("range", R.range) && O.map("context", R.context);
}

bool fromJSON(const llvm::json::Value &Params, WorkspaceEdit &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("changes", R.changes) &&
         O.map("documentChanges", R.documentChanges) &&
         O.mapOptional("changeAnnotations", R.changeAnnotations);
}

bool fromJSON(const llvm::json::Value &Params, ExecuteCommandParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  if (!O || !O.map("command", R.command))
    return false;

  const auto *Args = Params.getAsObject()->get("arguments");
  if (!Args)
    return true; // Missing args is ok, argument is null.
  const auto *ArgsArray = Args->getAsArray();
  if (!ArgsArray) {
    P.field("arguments").report("expected array");
    return false;
  }
  if (ArgsArray->size() > 1) {
    P.field("arguments").report("Command should have 0 or 1 argument");
    return false;
  }
  if (ArgsArray->size() == 1) {
    R.argument = ArgsArray->front();
  }
  return true;
}

llvm::json::Value toJSON(const SymbolInformation &P) {
  llvm::json::Object O{
      {"name", P.name},
      {"kind", static_cast<int>(P.kind)},
      {"location", P.location},
      {"containerName", P.containerName},
  };
  if (P.score)
    O["score"] = *P.score;
  return std::move(O);
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
                              const SymbolInformation &SI) {
  O << SI.containerName << "::" << SI.name << " - " << toJSON(SI);
  return O;
}

bool operator==(const SymbolDetails &LHS, const SymbolDetails &RHS) {
  return LHS.name == RHS.name && LHS.containerName == RHS.containerName &&
         LHS.USR == RHS.USR && LHS.ID == RHS.ID &&
         LHS.declarationRange == RHS.declarationRange &&
         LHS.definitionRange == RHS.definitionRange;
}

llvm::json::Value toJSON(const SymbolDetails &P) {
  llvm::json::Object Result{{"name", llvm::json::Value(nullptr)},
                            {"containerName", llvm::json::Value(nullptr)},
                            {"usr", llvm::json::Value(nullptr)},
                            {"id", llvm::json::Value(nullptr)}};

  if (!P.name.empty())
    Result["name"] = P.name;

  if (!P.containerName.empty())
    Result["containerName"] = P.containerName;

  if (!P.USR.empty())
    Result["usr"] = P.USR;

  if (P.ID)
    Result["id"] = P.ID.str();

  if (P.declarationRange)
    Result["declarationRange"] = *P.declarationRange;

  if (P.definitionRange)
    Result["definitionRange"] = *P.definitionRange;

  // FIXME: workaround for older gcc/clang
  return std::move(Result);
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const SymbolDetails &S) {
  if (!S.containerName.empty()) {
    O << S.containerName;
    llvm::StringRef ContNameRef;
    if (!ContNameRef.endswith("::")) {
      O << " ";
    }
  }
  O << S.name << " - " << toJSON(S);
  return O;
}

bool fromJSON(const llvm::json::Value &Params, WorkspaceSymbolParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("query", R.query) &&
         mapOptOrNull(Params, "limit", R.limit, P);
}

llvm::json::Value toJSON(const Command &C) {
  auto Cmd = llvm::json::Object{{"title", C.title}, {"command", C.command}};
  if (!C.argument.getAsNull())
    Cmd["arguments"] = llvm::json::Array{C.argument};
  return std::move(Cmd);
}

const llvm::StringLiteral CodeAction::QUICKFIX_KIND = "quickfix";
const llvm::StringLiteral CodeAction::REFACTOR_KIND = "refactor";
const llvm::StringLiteral CodeAction::INFO_KIND = "info";

llvm::json::Value toJSON(const CodeAction &CA) {
  auto CodeAction = llvm::json::Object{{"title", CA.title}};
  if (CA.kind)
    CodeAction["kind"] = *CA.kind;
  if (CA.diagnostics)
    CodeAction["diagnostics"] = llvm::json::Array(*CA.diagnostics);
  if (CA.isPreferred)
    CodeAction["isPreferred"] = true;
  if (CA.edit)
    CodeAction["edit"] = *CA.edit;
  if (CA.command)
    CodeAction["command"] = *CA.command;
  return std::move(CodeAction);
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const DocumentSymbol &S) {
  return O << S.name << " - " << toJSON(S);
}

llvm::json::Value toJSON(const DocumentSymbol &S) {
  llvm::json::Object Result{{"name", S.name},
                            {"kind", static_cast<int>(S.kind)},
                            {"range", S.range},
                            {"selectionRange", S.selectionRange}};

  if (!S.detail.empty())
    Result["detail"] = S.detail;
  if (!S.children.empty())
    Result["children"] = S.children;
  if (S.deprecated)
    Result["deprecated"] = true;
  // FIXME: workaround for older gcc/clang
  return std::move(Result);
}

llvm::json::Value toJSON(const WorkspaceEdit &WE) {
  llvm::json::Object Result;
  if (WE.changes) {
    llvm::json::Object FileChanges;
    for (auto &Change : *WE.changes)
      FileChanges[Change.first] = llvm::json::Array(Change.second);
    Result["changes"] = std::move(FileChanges);
  }
  if (WE.documentChanges)
    Result["documentChanges"] = *WE.documentChanges;
  if (!WE.changeAnnotations.empty()) {
    llvm::json::Object ChangeAnnotations;
    for (auto &Annotation : WE.changeAnnotations)
      ChangeAnnotations[Annotation.first] = Annotation.second;
    Result["changeAnnotations"] = std::move(ChangeAnnotations);
  }
  return Result;
}

bool fromJSON(const llvm::json::Value &Params, TweakArgs &A,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("file", A.file) && O.map("selection", A.selection) &&
         O.map("tweakID", A.tweakID);
}

llvm::json::Value toJSON(const TweakArgs &A) {
  return llvm::json::Object{
      {"tweakID", A.tweakID}, {"selection", A.selection}, {"file", A.file}};
}

llvm::json::Value toJSON(const ApplyWorkspaceEditParams &Params) {
  return llvm::json::Object{{"edit", Params.edit}};
}

bool fromJSON(const llvm::json::Value &Response, ApplyWorkspaceEditResponse &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Response, P);
  return O && O.map("applied", R.applied) &&
         O.map("failureReason", R.failureReason);
}

bool fromJSON(const llvm::json::Value &Params, TextDocumentPositionParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument) &&
         O.map("position", R.position);
}

bool fromJSON(const llvm::json::Value &Params, CompletionContext &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  int TriggerKind;
  if (!O || !O.map("triggerKind", TriggerKind) ||
      !mapOptOrNull(Params, "triggerCharacter", R.triggerCharacter, P))
    return false;
  R.triggerKind = static_cast<CompletionTriggerKind>(TriggerKind);
  return true;
}

bool fromJSON(const llvm::json::Value &Params, CompletionParams &R,
              llvm::json::Path P) {
  if (!fromJSON(Params, static_cast<TextDocumentPositionParams &>(R), P) ||
      !mapOptOrNull(Params, "limit", R.limit, P))
    return false;
  if (auto *Context = Params.getAsObject()->get("context"))
    return fromJSON(*Context, R.context, P.field("context"));
  return true;
}

static llvm::StringRef toTextKind(MarkupKind Kind) {
  switch (Kind) {
  case MarkupKind::PlainText:
    return "plaintext";
  case MarkupKind::Markdown:
    return "markdown";
  }
  llvm_unreachable("Invalid MarkupKind");
}

bool fromJSON(const llvm::json::Value &V, MarkupKind &K, llvm::json::Path P) {
  auto Str = V.getAsString();
  if (!Str) {
    P.report("expected string");
    return false;
  }
  if (*Str == "plaintext")
    K = MarkupKind::PlainText;
  else if (*Str == "markdown")
    K = MarkupKind::Markdown;
  else {
    P.report("unknown markup kind");
    return false;
  }
  return true;
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, MarkupKind K) {
  return OS << toTextKind(K);
}

llvm::json::Value toJSON(const MarkupContent &MC) {
  if (MC.value.empty())
    return nullptr;

  return llvm::json::Object{
      {"kind", toTextKind(MC.kind)},
      {"value", MC.value},
  };
}

llvm::json::Value toJSON(const Hover &H) {
  llvm::json::Object Result{{"contents", toJSON(H.contents)}};

  if (H.range)
    Result["range"] = toJSON(*H.range);

  return std::move(Result);
}

bool fromJSON(const llvm::json::Value &E, CompletionItemKind &Out,
              llvm::json::Path P) {
  if (auto T = E.getAsInteger()) {
    if (*T < static_cast<int>(CompletionItemKind::Text) ||
        *T > static_cast<int>(CompletionItemKind::TypeParameter))
      return false;
    Out = static_cast<CompletionItemKind>(*T);
    return true;
  }
  return false;
}

CompletionItemKind
adjustKindToCapability(CompletionItemKind Kind,
                       CompletionItemKindBitset &SupportedCompletionItemKinds) {
  auto KindVal = static_cast<size_t>(Kind);
  if (KindVal >= CompletionItemKindMin &&
      KindVal <= SupportedCompletionItemKinds.size() &&
      SupportedCompletionItemKinds[KindVal])
    return Kind;

  switch (Kind) {
  // Provide some fall backs for common kinds that are close enough.
  case CompletionItemKind::Folder:
    return CompletionItemKind::File;
  case CompletionItemKind::EnumMember:
    return CompletionItemKind::Enum;
  case CompletionItemKind::Struct:
    return CompletionItemKind::Class;
  default:
    return CompletionItemKind::Text;
  }
}

bool fromJSON(const llvm::json::Value &E, CompletionItemKindBitset &Out,
              llvm::json::Path P) {
  if (auto *A = E.getAsArray()) {
    for (size_t I = 0; I < A->size(); ++I) {
      CompletionItemKind KindOut;
      if (fromJSON((*A)[I], KindOut, P.index(I)))
        Out.set(size_t(KindOut));
    }
    return true;
  }
  return false;
}

llvm::json::Value toJSON(const CompletionItemLabelDetails &CD) {
  llvm::json::Object Result;
  if (!CD.detail.empty())
    Result["detail"] = CD.detail;
  if (!CD.description.empty())
    Result["description"] = CD.description;
  return Result;
}

void removeCompletionLabelDetails(CompletionItem &C) {
  if (!C.labelDetails)
    return;
  if (!C.labelDetails->detail.empty())
    C.label += C.labelDetails->detail;
  if (!C.labelDetails->description.empty())
    C.label = C.labelDetails->description + C.label;
  C.labelDetails.reset();
}

llvm::json::Value toJSON(const CompletionItem &CI) {
  assert(!CI.label.empty() && "completion item label is required");
  llvm::json::Object Result{{"label", CI.label}};
  if (CI.kind != CompletionItemKind::Missing)
    Result["kind"] = static_cast<int>(CI.kind);
  if (!CI.detail.empty())
    Result["detail"] = CI.detail;
  if (CI.labelDetails)
    Result["labelDetails"] = *CI.labelDetails;
  if (CI.documentation)
    Result["documentation"] = CI.documentation;
  if (!CI.sortText.empty())
    Result["sortText"] = CI.sortText;
  if (!CI.filterText.empty())
    Result["filterText"] = CI.filterText;
  if (!CI.insertText.empty())
    Result["insertText"] = CI.insertText;
  if (CI.insertTextFormat != InsertTextFormat::Missing)
    Result["insertTextFormat"] = static_cast<int>(CI.insertTextFormat);
  if (CI.textEdit)
    Result["textEdit"] = *CI.textEdit;
  if (!CI.additionalTextEdits.empty())
    Result["additionalTextEdits"] = llvm::json::Array(CI.additionalTextEdits);
  if (CI.deprecated)
    Result["deprecated"] = CI.deprecated;
  Result["score"] = CI.score;
  return std::move(Result);
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const CompletionItem &I) {
  O << I.label << " - " << toJSON(I);
  return O;
}

bool operator<(const CompletionItem &L, const CompletionItem &R) {
  return (L.sortText.empty() ? L.label : L.sortText) <
         (R.sortText.empty() ? R.label : R.sortText);
}

llvm::json::Value toJSON(const CompletionList &L) {
  return llvm::json::Object{
      {"isIncomplete", L.isIncomplete},
      {"items", llvm::json::Array(L.items)},
  };
}

llvm::json::Value toJSON(const ParameterInformation &PI) {
  assert((PI.labelOffsets || !PI.labelString.empty()) &&
         "parameter information label is required");
  llvm::json::Object Result;
  if (PI.labelOffsets)
    Result["label"] =
        llvm::json::Array({PI.labelOffsets->first, PI.labelOffsets->second});
  else
    Result["label"] = PI.labelString;
  if (!PI.documentation.empty())
    Result["documentation"] = PI.documentation;
  return std::move(Result);
}

llvm::json::Value toJSON(const SignatureInformation &SI) {
  assert(!SI.label.empty() && "signature information label is required");
  llvm::json::Object Result{
      {"label", SI.label},
      {"parameters", llvm::json::Array(SI.parameters)},
  };
  if (!SI.documentation.value.empty())
    Result["documentation"] = SI.documentation;
  return std::move(Result);
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
                              const SignatureInformation &I) {
  O << I.label << " - " << toJSON(I);
  return O;
}

llvm::json::Value toJSON(const SignatureHelp &SH) {
  assert(SH.activeSignature >= 0 &&
         "Unexpected negative value for number of active signatures.");
  assert(SH.activeParameter >= 0 &&
         "Unexpected negative value for active parameter index");
  return llvm::json::Object{
      {"activeSignature", SH.activeSignature},
      {"activeParameter", SH.activeParameter},
      {"signatures", llvm::json::Array(SH.signatures)},
  };
}

bool fromJSON(const llvm::json::Value &Params, RenameParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument) &&
         O.map("position", R.position) && O.map("newName", R.newName);
}

llvm::json::Value toJSON(const DocumentHighlight &DH) {
  return llvm::json::Object{
      {"range", toJSON(DH.range)},
      {"kind", static_cast<int>(DH.kind)},
  };
}

llvm::json::Value toJSON(const FileStatus &FStatus) {
  return llvm::json::Object{
      {"uri", FStatus.uri},
      {"state", FStatus.state},
  };
}

constexpr unsigned SemanticTokenEncodingSize = 5;
static llvm::json::Value encodeTokens(llvm::ArrayRef<SemanticToken> Toks) {
  llvm::json::Array Result;
  Result.reserve(SemanticTokenEncodingSize * Toks.size());
  for (const auto &Tok : Toks) {
    Result.push_back(Tok.deltaLine);
    Result.push_back(Tok.deltaStart);
    Result.push_back(Tok.length);
    Result.push_back(Tok.tokenType);
    Result.push_back(Tok.tokenModifiers);
  }
  assert(Result.size() == SemanticTokenEncodingSize * Toks.size());
  return std::move(Result);
}

bool operator==(const SemanticToken &L, const SemanticToken &R) {
  return std::tie(L.deltaLine, L.deltaStart, L.length, L.tokenType,
                  L.tokenModifiers) == std::tie(R.deltaLine, R.deltaStart,
                                                R.length, R.tokenType,
                                                R.tokenModifiers);
}

llvm::json::Value toJSON(const SemanticTokens &Tokens) {
  return llvm::json::Object{{"resultId", Tokens.resultId},
                            {"data", encodeTokens(Tokens.tokens)}};
}

llvm::json::Value toJSON(const SemanticTokensEdit &Edit) {
  return llvm::json::Object{
      {"start", SemanticTokenEncodingSize * Edit.startToken},
      {"deleteCount", SemanticTokenEncodingSize * Edit.deleteTokens},
      {"data", encodeTokens(Edit.tokens)}};
}

llvm::json::Value toJSON(const SemanticTokensOrDelta &TE) {
  llvm::json::Object Result{{"resultId", TE.resultId}};
  if (TE.edits)
    Result["edits"] = *TE.edits;
  if (TE.tokens)
    Result["data"] = encodeTokens(*TE.tokens);
  return std::move(Result);
}

bool fromJSON(const llvm::json::Value &Params, SemanticTokensParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument);
}

bool fromJSON(const llvm::json::Value &Params, SemanticTokensDeltaParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument) &&
         O.map("previousResultId", R.previousResultId);
}

llvm::json::Value toJSON(const InactiveRegionsParams &InactiveRegions) {
  return llvm::json::Object{
      {"textDocument", InactiveRegions.TextDocument},
      {"regions", std::move(InactiveRegions.InactiveRegions)}};
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
                              const DocumentHighlight &V) {
  O << V.range;
  if (V.kind == DocumentHighlightKind::Read)
    O << "(r)";
  if (V.kind == DocumentHighlightKind::Write)
    O << "(w)";
  return O;
}

bool fromJSON(const llvm::json::Value &Params,
              DidChangeConfigurationParams &CCP, llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("settings", CCP.settings);
}

bool fromJSON(const llvm::json::Value &Params, ClangdCompileCommand &CDbUpdate,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("workingDirectory", CDbUpdate.workingDirectory) &&
         O.map("compilationCommand", CDbUpdate.compilationCommand);
}

bool fromJSON(const llvm::json::Value &Params, ConfigurationSettings &S,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  if (!O)
    return true; // 'any' type in LSP.
  return mapOptOrNull(Params, "compilationDatabaseChanges",
                      S.compilationDatabaseChanges, P);
}

bool fromJSON(const llvm::json::Value &Params, InitializationOptions &Opts,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  if (!O)
    return true; // 'any' type in LSP.

  return fromJSON(Params, Opts.ConfigSettings, P) &&
         O.map("compilationDatabasePath", Opts.compilationDatabasePath) &&
         mapOptOrNull(Params, "fallbackFlags", Opts.fallbackFlags, P) &&
         mapOptOrNull(Params, "clangdFileStatus", Opts.FileStatus, P);
}

bool fromJSON(const llvm::json::Value &E, TypeHierarchyDirection &Out,
              llvm::json::Path P) {
  auto T = E.getAsInteger();
  if (!T)
    return false;
  if (*T < static_cast<int>(TypeHierarchyDirection::Children) ||
      *T > static_cast<int>(TypeHierarchyDirection::Both))
    return false;
  Out = static_cast<TypeHierarchyDirection>(*T);
  return true;
}

bool fromJSON(const llvm::json::Value &Params, TypeHierarchyPrepareParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument) &&
         O.map("position", R.position) &&
         mapOptOrNull(Params, "resolve", R.resolve, P) &&
         mapOptOrNull(Params, "direction", R.direction, P);
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
                              const TypeHierarchyItem &I) {
  return O << I.name << " - " << toJSON(I);
}

llvm::json::Value toJSON(const TypeHierarchyItem::ResolveParams &RP) {
  llvm::json::Object Result{{"symbolID", RP.symbolID}};
  if (RP.parents)
    Result["parents"] = RP.parents;
  return std::move(Result);
}
bool fromJSON(const llvm::json::Value &Params,
              TypeHierarchyItem::ResolveParams &RP, llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("symbolID", RP.symbolID) &&
         mapOptOrNull(Params, "parents", RP.parents, P);
}

llvm::json::Value toJSON(const TypeHierarchyItem &I) {
  llvm::json::Object Result{
      {"name", I.name},   {"kind", static_cast<int>(I.kind)},
      {"range", I.range}, {"selectionRange", I.selectionRange},
      {"uri", I.uri},     {"data", I.data},
  };

  if (I.detail)
    Result["detail"] = I.detail;
  return std::move(Result);
}

bool fromJSON(const llvm::json::Value &Params, TypeHierarchyItem &I,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);

  // Required fields.
  return O && O.map("name", I.name) && O.map("kind", I.kind) &&
         O.map("uri", I.uri) && O.map("range", I.range) &&
         O.map("selectionRange", I.selectionRange) &&
         mapOptOrNull(Params, "detail", I.detail, P) &&
         mapOptOrNull(Params, "deprecated", I.deprecated, P) &&
         mapOptOrNull(Params, "parents", I.parents, P) &&
         mapOptOrNull(Params, "children", I.children, P) &&
         mapOptOrNull(Params, "data", I.data, P);
}

bool fromJSON(const llvm::json::Value &Params,
              ResolveTypeHierarchyItemParams &R, llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("item", R.item) &&
         mapOptOrNull(Params, "resolve", R.resolve, P) &&
         mapOptOrNull(Params, "direction", R.direction, P);
}

bool fromJSON(const llvm::json::Value &Params, ReferenceContext &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.mapOptional("includeDeclaration", R.includeDeclaration);
}

bool fromJSON(const llvm::json::Value &Params, ReferenceParams &R,
              llvm::json::Path P) {
  TextDocumentPositionParams &Base = R;
  llvm::json::ObjectMapper O(Params, P);
  return fromJSON(Params, Base, P) && O && O.mapOptional("context", R.context);
}

llvm::json::Value toJSON(SymbolTag Tag) {
  return llvm::json::Value{static_cast<int>(Tag)};
}

llvm::json::Value toJSON(const CallHierarchyItem &I) {
  llvm::json::Object Result{{"name", I.name},
                            {"kind", static_cast<int>(I.kind)},
                            {"range", I.range},
                            {"selectionRange", I.selectionRange},
                            {"uri", I.uri}};
  if (!I.tags.empty())
    Result["tags"] = I.tags;
  if (!I.detail.empty())
    Result["detail"] = I.detail;
  if (!I.data.empty())
    Result["data"] = I.data;
  return std::move(Result);
}

bool fromJSON(const llvm::json::Value &Params, CallHierarchyItem &I,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);

  // Populate the required fields only. We don't care about the
  // optional fields `Tags` and `Detail` for the purpose of
  // client --> server communication.
  return O && O.map("name", I.name) && O.map("kind", I.kind) &&
         O.map("uri", I.uri) && O.map("range", I.range) &&
         O.map("selectionRange", I.selectionRange) &&
         mapOptOrNull(Params, "data", I.data, P);
}

bool fromJSON(const llvm::json::Value &Params,
              CallHierarchyIncomingCallsParams &C, llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O.map("item", C.item);
}

llvm::json::Value toJSON(const CallHierarchyIncomingCall &C) {
  return llvm::json::Object{{"from", C.from}, {"fromRanges", C.fromRanges}};
}

bool fromJSON(const llvm::json::Value &Params,
              CallHierarchyOutgoingCallsParams &C, llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O.map("item", C.item);
}

llvm::json::Value toJSON(const CallHierarchyOutgoingCall &C) {
  return llvm::json::Object{{"to", C.to}, {"fromRanges", C.fromRanges}};
}

bool fromJSON(const llvm::json::Value &Params, InlayHintsParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument) && O.map("range", R.range);
}

llvm::json::Value toJSON(const InlayHintKind &Kind) {
  switch (Kind) {
  case InlayHintKind::Type:
    return 1;
  case InlayHintKind::Parameter:
    return 2;
  case InlayHintKind::Designator:
  case InlayHintKind::BlockEnd:
    // This is an extension, don't serialize.
    return nullptr;
  }
  llvm_unreachable("Unknown clang.clangd.InlayHintKind");
}

llvm::json::Value toJSON(const InlayHint &H) {
  llvm::json::Object Result{{"position", H.position},
                            {"label", H.label},
                            {"paddingLeft", H.paddingLeft},
                            {"paddingRight", H.paddingRight}};
  auto K = toJSON(H.kind);
  if (!K.getAsNull())
    Result["kind"] = std::move(K);
  return std::move(Result);
}
bool operator==(const InlayHint &A, const InlayHint &B) {
  return std::tie(A.position, A.range, A.kind, A.label) ==
         std::tie(B.position, B.range, B.kind, B.label);
}
bool operator<(const InlayHint &A, const InlayHint &B) {
  return std::tie(A.position, A.range, A.kind, A.label) <
         std::tie(B.position, B.range, B.kind, B.label);
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, InlayHintKind Kind) {
  auto ToString = [](InlayHintKind K) {
    switch (K) {
    case InlayHintKind::Parameter:
      return "parameter";
    case InlayHintKind::Type:
      return "type";
    case InlayHintKind::Designator:
      return "designator";
    case InlayHintKind::BlockEnd:
      return "block-end";
    }
    llvm_unreachable("Unknown clang.clangd.InlayHintKind");
  };
  return OS << ToString(Kind);
}

static const char *toString(OffsetEncoding OE) {
  switch (OE) {
  case OffsetEncoding::UTF8:
    return "utf-8";
  case OffsetEncoding::UTF16:
    return "utf-16";
  case OffsetEncoding::UTF32:
    return "utf-32";
  case OffsetEncoding::UnsupportedEncoding:
    return "unknown";
  }
  llvm_unreachable("Unknown clang.clangd.OffsetEncoding");
}
llvm::json::Value toJSON(const OffsetEncoding &OE) { return toString(OE); }
bool fromJSON(const llvm::json::Value &V, OffsetEncoding &OE,
              llvm::json::Path P) {
  auto Str = V.getAsString();
  if (!Str)
    return false;
  OE = llvm::StringSwitch<OffsetEncoding>(*Str)
           .Case("utf-8", OffsetEncoding::UTF8)
           .Case("utf-16", OffsetEncoding::UTF16)
           .Case("utf-32", OffsetEncoding::UTF32)
           .Default(OffsetEncoding::UnsupportedEncoding);
  return true;
}
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, OffsetEncoding Enc) {
  return OS << toString(Enc);
}

bool fromJSON(const llvm::json::Value &Params, SelectionRangeParams &S,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", S.textDocument) &&
         O.map("positions", S.positions);
}

llvm::json::Value toJSON(const SelectionRange &Out) {
  if (Out.parent) {
    return llvm::json::Object{{"range", Out.range},
                              {"parent", toJSON(*Out.parent)}};
  }
  return llvm::json::Object{{"range", Out.range}};
}

bool fromJSON(const llvm::json::Value &Params, DocumentLinkParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument);
}

llvm::json::Value toJSON(const DocumentLink &DocumentLink) {
  return llvm::json::Object{
      {"range", DocumentLink.range},
      {"target", DocumentLink.target},
  };
}

bool fromJSON(const llvm::json::Value &Params, FoldingRangeParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument);
}

const llvm::StringLiteral FoldingRange::REGION_KIND = "region";
const llvm::StringLiteral FoldingRange::COMMENT_KIND = "comment";
const llvm::StringLiteral FoldingRange::IMPORT_KIND = "import";

llvm::json::Value toJSON(const FoldingRange &Range) {
  llvm::json::Object Result{
      {"startLine", Range.startLine},
      {"endLine", Range.endLine},
  };
  if (Range.startCharacter)
    Result["startCharacter"] = Range.startCharacter;
  if (Range.endCharacter)
    Result["endCharacter"] = Range.endCharacter;
  if (!Range.kind.empty())
    Result["kind"] = Range.kind;
  return Result;
}

llvm::json::Value toJSON(const MemoryTree &MT) {
  llvm::json::Object Out;
  int64_t Total = MT.self();
  Out["_self"] = Total;
  for (const auto &Entry : MT.children()) {
    auto Child = toJSON(Entry.getSecond());
    Total += *Child.getAsObject()->getInteger("_total");
    Out[Entry.first] = std::move(Child);
  }
  Out["_total"] = Total;
  return Out;
}

bool fromJSON(const llvm::json::Value &Params, ASTParams &R,
              llvm::json::Path P) {
  llvm::json::ObjectMapper O(Params, P);
  return O && O.map("textDocument", R.textDocument) && O.map("range", R.range);
}

llvm::json::Value toJSON(const ASTNode &N) {
  llvm::json::Object Result{
      {"role", N.role},
      {"kind", N.kind},
  };
  if (!N.children.empty())
    Result["children"] = N.children;
  if (!N.detail.empty())
    Result["detail"] = N.detail;
  if (!N.arcana.empty())
    Result["arcana"] = N.arcana;
  if (N.range)
    Result["range"] = *N.range;
  return Result;
}

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const ASTNode &Root) {
  std::function<void(const ASTNode &, unsigned)> Print = [&](const ASTNode &N,
                                                             unsigned Level) {
    OS.indent(2 * Level) << N.role << ": " << N.kind;
    if (!N.detail.empty())
      OS << " - " << N.detail;
    OS << "\n";
    for (const ASTNode &C : N.children)
      Print(C, Level + 1);
  };
  Print(Root, 0);
  return OS;
}

bool fromJSON(const llvm::json::Value &E, SymbolID &S, llvm::json::Path P) {
  auto Str = E.getAsString();
  if (!Str) {
    P.report("expected a string");
    return false;
  }
  auto ID = SymbolID::fromStr(*Str);
  if (!ID) {
    elog("Malformed symbolid: {0}", ID.takeError());
    P.report("malformed symbolid");
    return false;
  }
  S = *ID;
  return true;
}
llvm::json::Value toJSON(const SymbolID &S) { return S.str(); }

} // namespace clangd
} // namespace clang
