//===--- IncludeFixer.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
//
//===----------------------------------------------------------------------===//

#include "IncludeFixer.h"
#include "AST.h"
#include "Diagnostics.h"
#include "SourceCode.h"
#include "index/Index.h"
#include "index/Symbol.h"
#include "support/Logger.h"
#include "support/Trace.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticParse.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/Lexer.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/TypoCorrection.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
#include <algorithm>
#include <optional>
#include <set>
#include <string>
#include <vector>

namespace clang {
namespace clangd {
namespace {

std::optional<llvm::StringRef> getArgStr(const clang::Diagnostic &Info,
                                         unsigned Index) {
  switch (Info.getArgKind(Index)) {
  case DiagnosticsEngine::ak_c_string:
    return llvm::StringRef(Info.getArgCStr(Index));
  case DiagnosticsEngine::ak_std_string:
    return llvm::StringRef(Info.getArgStdStr(Index));
  default:
    return std::nullopt;
  }
}

std::vector<Fix> only(std::optional<Fix> F) {
  if (F)
    return {std::move(*F)};
  return {};
}

} // namespace

std::vector<Fix> IncludeFixer::fix(DiagnosticsEngine::Level DiagLevel,
                                   const clang::Diagnostic &Info) const {
  switch (Info.getID()) {
  /*
   There are many "incomplete type" diagnostics!
   They are almost all Sema diagnostics with "incomplete" in the name.

   sed -n '/CLASS_NOTE/! s/DIAG(\\([^,]*\\).*)/  case diag::\\1:/p' \
     tools/clang/include/clang/Basic/DiagnosticSemaKinds.inc | grep incomplete
  */
  // clang-format off
  //case diag::err_alignof_member_of_incomplete_type:
  case diag::err_array_incomplete_or_sizeless_type:
  case diag::err_array_size_incomplete_type:
  case diag::err_asm_incomplete_type:
  case diag::err_assoc_type_incomplete:
  case diag::err_bad_cast_incomplete:
  case diag::err_call_function_incomplete_return:
  case diag::err_call_incomplete_argument:
  case diag::err_call_incomplete_return:
  case diag::err_capture_of_incomplete_or_sizeless_type:
  case diag::err_catch_incomplete:
  case diag::err_catch_incomplete_ptr:
  case diag::err_catch_incomplete_ref:
  case diag::err_cconv_incomplete_param_type:
  case diag::err_coroutine_promise_type_incomplete:
  case diag::err_covariant_return_incomplete:
  //case diag::err_deduced_class_template_incomplete:
  case diag::err_delete_incomplete_class_type:
  case diag::err_dereference_incomplete_type:
  case diag::err_exception_spec_incomplete_type:
  case diag::err_field_incomplete_or_sizeless:
  case diag::err_for_range_incomplete_type:
  case diag::err_func_def_incomplete_result:
  case diag::err_ice_incomplete_type:
  case diag::err_illegal_message_expr_incomplete_type:
  case diag::err_incomplete_base_class:
  case diag::err_incomplete_enum:
  case diag::err_incomplete_in_exception_spec:
  case diag::err_incomplete_member_access:
  case diag::err_incomplete_nested_name_spec:
  case diag::err_incomplete_object_call:
  case diag::err_incomplete_receiver_type:
  case diag::err_incomplete_synthesized_property:
  case diag::err_incomplete_type:
  case diag::err_incomplete_type_objc_at_encode:
  case diag::err_incomplete_type_used_in_type_trait_expr:
  case diag::err_incomplete_typeid:
  case diag::err_init_incomplete_type:
  case diag::err_invalid_incomplete_type_use:
  case diag::err_lambda_incomplete_result:
  //case diag::err_matrix_incomplete_index:
  //case diag::err_matrix_separate_incomplete_index:
  case diag::err_memptr_incomplete:
  case diag::err_new_incomplete_or_sizeless_type:
  case diag::err_objc_incomplete_boxed_expression_type:
  case diag::err_objc_index_incomplete_class_type:
  case diag::err_offsetof_incomplete_type:
  case diag::err_omp_firstprivate_incomplete_type:
  case diag::err_omp_incomplete_type:
  case diag::err_omp_lastprivate_incomplete_type:
  case diag::err_omp_linear_incomplete_type:
  case diag::err_omp_private_incomplete_type:
  case diag::err_omp_reduction_incomplete_type:
  case diag::err_omp_section_incomplete_type:
  case diag::err_omp_threadprivate_incomplete_type:
  case diag::err_second_parameter_to_va_arg_incomplete:
  case diag::err_sizeof_alignof_incomplete_or_sizeless_type:
  case diag::err_subscript_incomplete_or_sizeless_type:
  case diag::err_switch_incomplete_class_type:
  case diag::err_temp_copy_incomplete:
  //case diag::err_template_arg_deduced_incomplete_pack:
  case diag::err_template_nontype_parm_incomplete:
  //case diag::err_tentative_def_incomplete_type:
  case diag::err_throw_incomplete:
  case diag::err_throw_incomplete_ptr:
  case diag::err_typecheck_arithmetic_incomplete_or_sizeless_type:
  case diag::err_typecheck_cast_to_incomplete:
  case diag::err_typecheck_decl_incomplete_type:
  //case diag::err_typecheck_incomplete_array_needs_initializer:
  case diag::err_typecheck_incomplete_tag:
  case diag::err_typecheck_incomplete_type_not_modifiable_lvalue:
  case diag::err_typecheck_nonviable_condition_incomplete:
  case diag::err_underlying_type_of_incomplete_enum:
  case diag::ext_incomplete_in_exception_spec:
  //case diag::ext_typecheck_compare_complete_incomplete_pointers:
  case diag::ext_typecheck_decl_incomplete_type:
  case diag::warn_delete_incomplete:
  case diag::warn_incomplete_encoded_type:
  //case diag::warn_printf_incomplete_specifier:
  case diag::warn_return_value_udt_incomplete:
  //case diag::warn_scanf_scanlist_incomplete:
  //case diag::warn_tentative_incomplete_array:
    //  clang-format on
    // Incomplete type diagnostics should have a QualType argument for the
    // incomplete type.
    for (unsigned Idx = 0; Idx < Info.getNumArgs(); ++Idx) {
      if (Info.getArgKind(Idx) == DiagnosticsEngine::ak_qualtype) {
        auto QT = QualType::getFromOpaquePtr((void *)Info.getRawArg(Idx));
        if (const Type *T = QT.getTypePtrOrNull()) {
          if (T->isIncompleteType())
            return fixIncompleteType(*T);
          // `enum x : int;' is not formally an incomplete type.
          // We may need a full definition anyway.
          if (auto * ET = llvm::dyn_cast<EnumType>(T))
            if (!ET->getDecl()->getDefinition())
              return fixIncompleteType(*T);
        }
      }
    }
    break;

  case diag::err_unknown_typename:
  case diag::err_unknown_typename_suggest:
  case diag::err_unknown_type_or_class_name_suggest:
  case diag::err_expected_class_name:
  case diag::err_typename_nested_not_found:
  case diag::err_no_template:
  case diag::err_no_template_suggest:
  case diag::err_undeclared_use:
  case diag::err_undeclared_use_suggest:
  case diag::err_undeclared_var_use:
  case diag::err_undeclared_var_use_suggest:
  case diag::err_no_member: // Could be no member in namespace.
  case diag::err_no_member_suggest:
  case diag::err_no_member_template:
  case diag::err_no_member_template_suggest:
  case diag::warn_implicit_function_decl:
  case diag::ext_implicit_function_decl_c99:
    dlog("Unresolved name at {0}, last typo was {1}",
         Info.getLocation().printToString(Info.getSourceManager()),
         LastUnresolvedName
             ? LastUnresolvedName->Loc.printToString(Info.getSourceManager())
             : "none");
    if (LastUnresolvedName) {
      // Try to fix unresolved name caused by missing declaration.
      // E.g.
      //   clang::SourceManager SM;
      //          ~~~~~~~~~~~~~
      //          UnresolvedName
      //   or
      //   namespace clang {  SourceManager SM; }
      //                      ~~~~~~~~~~~~~
      //                      UnresolvedName
      // We only attempt to recover a diagnostic if it has the same location as
      // the last seen unresolved name.
      if (LastUnresolvedName->Loc == Info.getLocation())
        return fixUnresolvedName();
    }
    break;

  // Cases where clang explicitly knows which header to include.
  // (There's no fix provided for boring formatting reasons).
  case diag::err_implied_std_initializer_list_not_found:
    return only(insertHeader("<initializer_list>"));
  case diag::err_need_header_before_typeid:
    return only(insertHeader("<typeinfo>"));
  case diag::err_need_header_before_placement_new:
  case diag::err_implicit_coroutine_std_nothrow_type_not_found:
    return only(insertHeader("<new>"));
  case diag::err_omp_implied_type_not_found:
  case diag::err_omp_interop_type_not_found:
    return only(insertHeader("<omp.h>"));
  case diag::err_implied_coroutine_type_not_found:
    return only(insertHeader("<coroutine>"));
  case diag::err_implied_comparison_category_type_not_found:
    return only(insertHeader("<compare>"));
  case diag::note_include_header_or_declare:
    if (Info.getNumArgs() > 0)
      if (auto Header = getArgStr(Info, 0))
        return only(insertHeader(("<" + *Header + ">").str(),
                                 getArgStr(Info, 1).value_or("")));
    break;
  }

  return {};
}

std::optional<Fix> IncludeFixer::insertHeader(llvm::StringRef Spelled,
                                               llvm::StringRef Symbol,
                                               tooling::IncludeDirective Directive) const {
  Fix F;

  if (auto Edit = Inserter->insert(Spelled, Directive))
    F.Edits.push_back(std::move(*Edit));
  else
    return std::nullopt;

  llvm::StringRef DirectiveSpelling =
      Directive == tooling::IncludeDirective::Include ? "Include" : "Import";
  if (Symbol.empty())
    F.Message = llvm::formatv("{0} {1}", DirectiveSpelling, Spelled);
  else
    F.Message = llvm::formatv("{0} {1} for symbol {2}",
        DirectiveSpelling, Spelled, Symbol);

  return F;
}

std::vector<Fix> IncludeFixer::fixIncompleteType(const Type &T) const {
  // Only handle incomplete TagDecl type.
  const TagDecl *TD = T.getAsTagDecl();
  if (!TD)
    return {};
  std::string TypeName = printQualifiedName(*TD);
  trace::Span Tracer("Fix include for incomplete type");
  SPAN_ATTACH(Tracer, "type", TypeName);
  vlog("Trying to fix include for incomplete type {0}", TypeName);

  auto ID = getSymbolID(TD);
  if (!ID)
    return {};
  std::optional<const SymbolSlab *> Symbols = lookupCached(ID);
  if (!Symbols)
    return {};
  const SymbolSlab &Syms = **Symbols;
  std::vector<Fix> Fixes;
  if (!Syms.empty()) {
    auto &Matched = *Syms.begin();
    if (!Matched.IncludeHeaders.empty() && Matched.Definition &&
        Matched.CanonicalDeclaration.FileURI == Matched.Definition.FileURI)
      Fixes = fixesForSymbols(Syms);
  }
  return Fixes;
}

std::vector<Fix> IncludeFixer::fixesForSymbols(const SymbolSlab &Syms) const {
  auto Inserted = [&](const Symbol &Sym, llvm::StringRef Header)
      -> llvm::Expected<std::pair<std::string, bool>> {
    auto ResolvedDeclaring =
        URI::resolve(Sym.CanonicalDeclaration.FileURI, File);
    if (!ResolvedDeclaring)
      return ResolvedDeclaring.takeError();
    auto ResolvedInserted = toHeaderFile(Header, File);
    if (!ResolvedInserted)
      return ResolvedInserted.takeError();
    auto Spelled = Inserter->calculateIncludePath(*ResolvedInserted, File);
    if (!Spelled)
      return error("Header not on include path");
    return std::make_pair(
        std::move(*Spelled),
        Inserter->shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted));
  };

  std::vector<Fix> Fixes;
  // Deduplicate fixes by include headers. This doesn't distinguish symbols in
  // different scopes from the same header, but this case should be rare and is
  // thus ignored.
  llvm::StringSet<> InsertedHeaders;
  for (const auto &Sym : Syms) {
    for (const auto &Inc : getRankedIncludes(Sym)) {
      if ((Inc.Directive & Directive) == 0)
        continue;
      if (auto ToInclude = Inserted(Sym, Inc.Header)) {
        if (ToInclude->second) {
          if (!InsertedHeaders.try_emplace(ToInclude->first).second)
            continue;
          if (auto Fix =
                  insertHeader(ToInclude->first, (Sym.Scope + Sym.Name).str(),
                               Directive == Symbol::Import
                                  ? tooling::IncludeDirective::Import
                                  : tooling::IncludeDirective::Include))
            Fixes.push_back(std::move(*Fix));
        }
      } else {
        vlog("Failed to calculate include insertion for {0} into {1}: {2}",
             Inc.Header, File, ToInclude.takeError());
      }
    }
  }
  return Fixes;
}

// Returns the identifiers qualified by an unresolved name. \p Loc is the
// start location of the unresolved name. For the example below, this returns
// "::X::Y" that is qualified by unresolved name "clangd":
//     clang::clangd::X::Y
//            ~
std::optional<std::string> qualifiedByUnresolved(const SourceManager &SM,
                                                  SourceLocation Loc,
                                                  const LangOptions &LangOpts) {
  std::string Result;
  // Accept qualifier written within macro arguments, but not macro bodies.
  SourceLocation NextLoc = SM.getTopMacroCallerLoc(Loc);
  while (auto CCTok = Lexer::findNextToken(NextLoc, SM, LangOpts)) {
    if (!CCTok->is(tok::coloncolon))
      break;
    auto IDTok = Lexer::findNextToken(CCTok->getLocation(), SM, LangOpts);
    if (!IDTok || !IDTok->is(tok::raw_identifier))
      break;
    Result.append(("::" + IDTok->getRawIdentifier()).str());
    NextLoc = IDTok->getLocation();
  }
  if (Result.empty())
    return std::nullopt;
  return Result;
}

// An unresolved name and its scope information that can be extracted cheaply.
struct CheapUnresolvedName {
  std::string Name;
  // This is the part of what was typed that was resolved, and it's in its
  // resolved form not its typed form (think `namespace clang { clangd::x }` -->
  // `clang::clangd::`).
  std::optional<std::string> ResolvedScope;

  // Unresolved part of the scope. When the unresolved name is a specifier, we
  // use the name that comes after it as the alternative name to resolve and use
  // the specifier as the extra scope in the accessible scopes.
  std::optional<std::string> UnresolvedScope;
};

std::optional<std::string> getSpelledSpecifier(const CXXScopeSpec &SS,
    const SourceManager &SM) {
  // Support specifiers written within a single macro argument.
  if (!SM.isWrittenInSameFile(SS.getBeginLoc(), SS.getEndLoc()))
    return std::nullopt;
  SourceRange Range(SM.getTopMacroCallerLoc(SS.getBeginLoc()), SM.getTopMacroCallerLoc(SS.getEndLoc()));
  if (Range.getBegin().isMacroID() || Range.getEnd().isMacroID())
    return std::nullopt;

  return (toSourceCode(SM, Range) + "::").str();
}

// Extracts unresolved name and scope information around \p Unresolved.
// FIXME: try to merge this with the scope-wrangling code in CodeComplete.
std::optional<CheapUnresolvedName> extractUnresolvedNameCheaply(
    const SourceManager &SM, const DeclarationNameInfo &Unresolved,
    CXXScopeSpec *SS, const LangOptions &LangOpts, bool UnresolvedIsSpecifier) {
  CheapUnresolvedName Result;
  Result.Name = Unresolved.getAsString();
  if (SS && SS->isNotEmpty()) { // "::" or "ns::"
    if (auto *Nested = SS->getScopeRep()) {
      if (Nested->getKind() == NestedNameSpecifier::Global) {
        Result.ResolvedScope = "";
      } else if (const auto *NS = Nested->getAsNamespace()) {
        std::string SpecifiedNS = printNamespaceScope(*NS);
        std::optional<std::string> Spelling = getSpelledSpecifier(*SS, SM);

        // Check the specifier spelled in the source.
        // If the resolved scope doesn't end with the spelled scope, the
        // resolved scope may come from a sema typo correction. For example,
        // sema assumes that "clangd::" is a typo of "clang::" and uses
        // "clang::" as the specified scope in:
        //     namespace clang { clangd::X; }
        // In this case, we use the "typo" specifier as extra scope instead
        // of using the scope assumed by sema.
        if (!Spelling || llvm::StringRef(SpecifiedNS).ends_with(*Spelling)) {
          Result.ResolvedScope = std::move(SpecifiedNS);
        } else {
          Result.UnresolvedScope = std::move(*Spelling);
        }
      } else if (const auto *ANS = Nested->getAsNamespaceAlias()) {
        Result.ResolvedScope = printNamespaceScope(*ANS->getNamespace());
      } else {
        // We don't fix symbols in scopes that are not top-level e.g. class
        // members, as we don't collect includes for them.
        return std::nullopt;
      }
    }
  }

  if (UnresolvedIsSpecifier) {
    // If the unresolved name is a specifier e.g.
    //      clang::clangd::X
    //             ~~~~~~
    // We try to resolve clang::clangd::X instead of clang::clangd.
    // FIXME: We won't be able to fix include if the specifier is what we
    // should resolve (e.g. it's a class scope specifier). Collecting include
    // headers for nested types could make this work.

    // Not using the end location as it doesn't always point to the end of
    // identifier.
    if (auto QualifiedByUnresolved =
            qualifiedByUnresolved(SM, Unresolved.getBeginLoc(), LangOpts)) {
      auto Split = splitQualifiedName(*QualifiedByUnresolved);
      if (!Result.UnresolvedScope)
        Result.UnresolvedScope.emplace();
      // If UnresolvedSpecifiedScope is already set, we simply append the
      // extra scope. Suppose the unresolved name is "index" in the following
      // example:
      //   namespace clang {  clangd::index::X; }
      //                      ~~~~~~  ~~~~~
      // "clangd::" is assumed to be clang:: by Sema, and we would have used
      // it as extra scope. With "index" being a specifier, we append "index::"
      // to the extra scope.
      Result.UnresolvedScope->append((Result.Name + Split.first).str());
      Result.Name = std::string(Split.second);
    }
  }
  return Result;
}

/// Returns all namespace scopes that the unqualified lookup would visit.
std::vector<std::string>
collectAccessibleScopes(Sema &Sem, const DeclarationNameInfo &Typo, Scope *S,
                        Sema::LookupNameKind LookupKind) {
  // Collects contexts visited during a Sema name lookup.
  struct VisitedContextCollector : public VisibleDeclConsumer {
    VisitedContextCollector(std::vector<std::string> &Out) : Out(Out) {}
    void EnteredContext(DeclContext *Ctx) override {
      if (llvm::isa<NamespaceDecl>(Ctx))
        Out.push_back(printNamespaceScope(*Ctx));
    }
    void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
                   bool InBaseClass) override {}
    std::vector<std::string> &Out;
  };

  std::vector<std::string> Scopes;
  Scopes.push_back("");
  VisitedContextCollector Collector(Scopes);
  Sem.LookupVisibleDecls(S, LookupKind, Collector,
                         /*IncludeGlobalScope=*/false,
                         /*LoadExternal=*/false);
  llvm::sort(Scopes);
  Scopes.erase(std::unique(Scopes.begin(), Scopes.end()), Scopes.end());
  return Scopes;
}

class IncludeFixer::UnresolvedNameRecorder : public ExternalSemaSource {
public:
  UnresolvedNameRecorder(std::optional<UnresolvedName> &LastUnresolvedName)
      : LastUnresolvedName(LastUnresolvedName) {}

  void InitializeSema(Sema &S) override { this->SemaPtr = &S; }

  // Captures the latest typo and treat it as an unresolved name that can
  // potentially be fixed by adding #includes.
  TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, int LookupKind,
                             Scope *S, CXXScopeSpec *SS,
                             CorrectionCandidateCallback &CCC,
                             DeclContext *MemberContext, bool EnteringContext,
                             const ObjCObjectPointerType *OPT) override {
    dlog("CorrectTypo: {0}", Typo.getAsString());
    assert(SemaPtr && "Sema must have been set.");
    if (SemaPtr->isSFINAEContext())
      return TypoCorrection();
    if (!isInsideMainFile(Typo.getLoc(), SemaPtr->SourceMgr))
      return clang::TypoCorrection();

    auto Extracted = extractUnresolvedNameCheaply(
        SemaPtr->SourceMgr, Typo, SS, SemaPtr->LangOpts,
        static_cast<Sema::LookupNameKind>(LookupKind) ==
            Sema::LookupNameKind::LookupNestedNameSpecifierName);
    if (!Extracted)
      return TypoCorrection();

    UnresolvedName Unresolved;
    Unresolved.Name = Extracted->Name;
    Unresolved.Loc = Typo.getBeginLoc();
    if (!Extracted->ResolvedScope && !S) // Give up if no scope available.
      return TypoCorrection();

    if (Extracted->ResolvedScope)
      Unresolved.Scopes.push_back(*Extracted->ResolvedScope);
    else // no qualifier or qualifier is unresolved.
      Unresolved.Scopes = collectAccessibleScopes(
          *SemaPtr, Typo, S, static_cast<Sema::LookupNameKind>(LookupKind));

    if (Extracted->UnresolvedScope) {
      for (std::string &Scope : Unresolved.Scopes)
        Scope += *Extracted->UnresolvedScope;
    }

    LastUnresolvedName = std::move(Unresolved);

    // Never return a valid correction to try to recover. Our suggested fixes
    // always require a rebuild.
    return TypoCorrection();
  }

private:
  Sema *SemaPtr = nullptr;

  std::optional<UnresolvedName> &LastUnresolvedName;
};

llvm::IntrusiveRefCntPtr<ExternalSemaSource>
IncludeFixer::unresolvedNameRecorder() {
  return new UnresolvedNameRecorder(LastUnresolvedName);
}

std::vector<Fix> IncludeFixer::fixUnresolvedName() const {
  assert(LastUnresolvedName);
  auto &Unresolved = *LastUnresolvedName;
  vlog("Trying to fix unresolved name \"{0}\" in scopes: [{1}]",
       Unresolved.Name, llvm::join(Unresolved.Scopes, ", "));

  FuzzyFindRequest Req;
  Req.AnyScope = false;
  Req.Query = Unresolved.Name;
  Req.Scopes = Unresolved.Scopes;
  Req.RestrictForCodeCompletion = true;
  Req.Limit = 100;

  if (std::optional<const SymbolSlab *> Syms = fuzzyFindCached(Req))
    return fixesForSymbols(**Syms);

  return {};
}

std::optional<const SymbolSlab *>
IncludeFixer::fuzzyFindCached(const FuzzyFindRequest &Req) const {
  auto ReqStr = llvm::formatv("{0}", toJSON(Req)).str();
  auto I = FuzzyFindCache.find(ReqStr);
  if (I != FuzzyFindCache.end())
    return &I->second;

  if (IndexRequestCount >= IndexRequestLimit)
    return std::nullopt;
  IndexRequestCount++;

  SymbolSlab::Builder Matches;
  Index.fuzzyFind(Req, [&](const Symbol &Sym) {
    if (Sym.Name != Req.Query)
      return;
    if (!Sym.IncludeHeaders.empty())
      Matches.insert(Sym);
  });
  auto Syms = std::move(Matches).build();
  auto E = FuzzyFindCache.try_emplace(ReqStr, std::move(Syms));
  return &E.first->second;
}

std::optional<const SymbolSlab *>
IncludeFixer::lookupCached(const SymbolID &ID) const {
  LookupRequest Req;
  Req.IDs.insert(ID);

  auto I = LookupCache.find(ID);
  if (I != LookupCache.end())
    return &I->second;

  if (IndexRequestCount >= IndexRequestLimit)
    return std::nullopt;
  IndexRequestCount++;

  // FIXME: consider batching the requests for all diagnostics.
  SymbolSlab::Builder Matches;
  Index.lookup(Req, [&](const Symbol &Sym) { Matches.insert(Sym); });
  auto Syms = std::move(Matches).build();

  std::vector<Fix> Fixes;
  if (!Syms.empty()) {
    auto &Matched = *Syms.begin();
    if (!Matched.IncludeHeaders.empty() && Matched.Definition &&
        Matched.CanonicalDeclaration.FileURI == Matched.Definition.FileURI)
      Fixes = fixesForSymbols(Syms);
  }
  auto E = LookupCache.try_emplace(ID, std::move(Syms));
  return &E.first->second;
}

} // namespace clangd
} // namespace clang
