//===--- Preamble.h - Reusing expensive parts of the AST ---------*- 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
//
//===----------------------------------------------------------------------===//
//
// The vast majority of code in a typical translation unit is in the headers
// included at the top of the file.
//
// The preamble optimization says that we can parse this code once, and reuse
// the result multiple times. The preamble is invalidated by changes to the
// code in the preamble region, to the compile command, or to files on disk.
//
// This is the most important optimization in clangd: it allows operations like
// code-completion to have sub-second latency. It is supported by the
// PrecompiledPreamble functionality in clang, which wraps the techniques used
// by PCH files, modules etc into a convenient interface.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREAMBLE_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREAMBLE_H

#include "CollectMacros.h"
#include "Compiler.h"
#include "Diagnostics.h"
#include "FS.h"
#include "Headers.h"
#include "ModulesBuilder.h"

#include "clang-include-cleaner/Record.h"
#include "support/Path.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/PrecompiledPreamble.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"

#include <cstddef>
#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <vector>

namespace clang {
namespace clangd {

/// The captured AST context.
/// Keeps necessary structs for an ASTContext and Preprocessor alive.
/// This enables consuming them after context that produced the AST is gone.
/// (e.g. indexing a preamble ast on a separate thread). ASTContext stored
/// inside is still not thread-safe.

struct CapturedASTCtx {
public:
  CapturedASTCtx(CompilerInstance &Clang)
      : Invocation(Clang.getInvocationPtr()),
        Diagnostics(Clang.getDiagnosticsPtr()), Target(Clang.getTargetPtr()),
        AuxTarget(Clang.getAuxTarget()), FileMgr(Clang.getFileManagerPtr()),
        SourceMgr(Clang.getSourceManagerPtr()), PP(Clang.getPreprocessorPtr()),
        Context(Clang.getASTContextPtr()) {}

  CapturedASTCtx(const CapturedASTCtx &) = delete;
  CapturedASTCtx &operator=(const CapturedASTCtx &) = delete;
  CapturedASTCtx(CapturedASTCtx &&) = default;
  CapturedASTCtx &operator=(CapturedASTCtx &&) = default;

  ASTContext &getASTContext() { return *Context; }
  Preprocessor &getPreprocessor() { return *PP; }
  CompilerInvocation &getCompilerInvocation() { return *Invocation; }
  FileManager &getFileManager() { return *FileMgr; }
  void setStatCache(std::shared_ptr<PreambleFileStatusCache> StatCache) {
    this->StatCache = StatCache;
  }

private:
  std::shared_ptr<CompilerInvocation> Invocation;
  IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
  IntrusiveRefCntPtr<TargetInfo> Target;
  IntrusiveRefCntPtr<TargetInfo> AuxTarget;
  IntrusiveRefCntPtr<FileManager> FileMgr;
  IntrusiveRefCntPtr<SourceManager> SourceMgr;
  std::shared_ptr<Preprocessor> PP;
  IntrusiveRefCntPtr<ASTContext> Context;
  std::shared_ptr<PreambleFileStatusCache> StatCache;
};

/// The parsed preamble and associated data.
///
/// As we must avoid re-parsing the preamble, any information that can only
/// be obtained during parsing must be eagerly captured and stored here.
struct PreambleData {
  PreambleData(PrecompiledPreamble Preamble) : Preamble(std::move(Preamble)) {}

  // Version of the ParseInputs this preamble was built from.
  std::string Version;
  tooling::CompileCommand CompileCommand;
  // Target options used when building the preamble. Changes in target can cause
  // crashes when deserializing preamble, this enables consumers to use the
  // same target (without reparsing CompileCommand).
  std::shared_ptr<TargetOptions> TargetOpts = nullptr;
  PrecompiledPreamble Preamble;
  std::vector<Diag> Diags;
  // Processes like code completions and go-to-definitions will need #include
  // information, and their compile action skips preamble range.
  IncludeStructure Includes;
  // Captures #include-mapping information in #included headers.
  std::shared_ptr<const include_cleaner::PragmaIncludes> Pragmas;
  // Information about required module files for this preamble.
  std::unique_ptr<PrerequisiteModules> RequiredModules;
  // Macros defined in the preamble section of the main file.
  // Users care about headers vs main-file, not preamble vs non-preamble.
  // These should be treated as main-file entities e.g. for code completion.
  MainFileMacros Macros;
  // Pragma marks defined in the preamble section of the main file.
  std::vector<PragmaMark> Marks;
  // Cache of FS operations performed when building the preamble.
  // When reusing a preamble, this cache can be consumed to save IO.
  std::shared_ptr<PreambleFileStatusCache> StatCache;
  // Whether there was a (possibly-incomplete) include-guard on the main file.
  // We need to propagate this information "by hand" to subsequent parses.
  bool MainIsIncludeGuarded = false;
};

using PreambleParsedCallback =
    std::function<void(CapturedASTCtx ASTCtx,
                       std::shared_ptr<const include_cleaner::PragmaIncludes>)>;

/// Timings and statistics from the premble build. Unlike PreambleData, these
/// do not need to be stored for later, but can be useful for logging, metrics,
/// etc.
struct PreambleBuildStats {
  /// Total wall time it took to build preamble, in seconds.
  double TotalBuildTime;
  /// Time spent in filesystem operations during the build, in seconds.
  double FileSystemTime;

  /// Estimate of the memory used while building the preamble.
  /// This memory has been released when buildPreamble returns.
  /// For example, this includes the size of the in-memory AST (ASTContext).
  size_t BuildSize;
  /// The serialized size of the preamble.
  /// This storage is needed while the preamble is used (but may be on disk).
  size_t SerializedSize;
};

/// Build a preamble for the new inputs unless an old one can be reused.
/// If \p PreambleCallback is set, it will be run on top of the AST while
/// building the preamble.
/// If Stats is not non-null, build statistics will be exported there.
std::shared_ptr<const PreambleData>
buildPreamble(PathRef FileName, CompilerInvocation CI,
              const ParseInputs &Inputs, bool StoreInMemory,
              PreambleParsedCallback PreambleCallback,
              PreambleBuildStats *Stats = nullptr);

/// Returns true if \p Preamble is reusable for \p Inputs. Note that it will
/// return true when some missing headers are now available.
/// FIXME: Should return more information about the delta between \p Preamble
/// and \p Inputs, e.g. new headers.
bool isPreambleCompatible(const PreambleData &Preamble,
                          const ParseInputs &Inputs, PathRef FileName,
                          const CompilerInvocation &CI);

/// Stores information required to parse a TU using a (possibly stale) Baseline
/// preamble. Later on this information can be injected into the main file by
/// updating compiler invocation with \c apply. This injected section
/// approximately reflects additions to the preamble in Modified contents, e.g.
/// new include directives.
class PreamblePatch {
public:
  enum class PatchType { MacroDirectives, All };
  /// \p Preamble is used verbatim.
  static PreamblePatch unmodified(const PreambleData &Preamble);
  /// Builds a patch that contains new PP directives introduced to the preamble
  /// section of \p Modified compared to \p Baseline.
  /// FIXME: This only handles include directives, we should at least handle
  /// define/undef.
  static PreamblePatch createFullPatch(llvm::StringRef FileName,
                                       const ParseInputs &Modified,
                                       const PreambleData &Baseline);
  static PreamblePatch createMacroPatch(llvm::StringRef FileName,
                                        const ParseInputs &Modified,
                                        const PreambleData &Baseline);
  /// Returns the FileEntry for the preamble patch of MainFilePath in SM, if
  /// any.
  static OptionalFileEntryRef getPatchEntry(llvm::StringRef MainFilePath,
                                            const SourceManager &SM);

  /// Adjusts CI (which compiles the modified inputs) to be used with the
  /// baseline preamble. This is done by inserting an artificial include to the
  /// \p CI that contains new directives calculated in create.
  void apply(CompilerInvocation &CI) const;

  /// Returns #include directives from the \c Modified preamble that were
  /// resolved using the \c Baseline preamble. This covers the new locations of
  /// inclusions that were moved around, but not inclusions of new files. Those
  /// will be recorded when parsing the main file: the includes in the injected
  /// section will be resolved back to their spelled positions in the main file
  /// using the presumed-location mechanism.
  std::vector<Inclusion> preambleIncludes() const;

  /// Returns preamble bounds for the Modified.
  PreambleBounds modifiedBounds() const { return ModifiedBounds; }

  /// Returns textual patch contents.
  llvm::StringRef text() const { return PatchContents; }

  /// Returns diag locations for Modified contents.
  llvm::ArrayRef<Diag> patchedDiags() const { return PatchedDiags; }

  static constexpr llvm::StringLiteral HeaderName = "__preamble_patch__.h";

  llvm::ArrayRef<PragmaMark> marks() const;
  const MainFileMacros &mainFileMacros() const;

private:
  static PreamblePatch create(llvm::StringRef FileName,
                              const ParseInputs &Modified,
                              const PreambleData &Baseline,
                              PatchType PatchType);

  PreamblePatch() = default;
  std::string PatchContents;
  std::string PatchFileName;
  // Includes that are present in both Baseline and Modified. Used for
  // patching includes of baseline preamble.
  std::vector<Inclusion> PreambleIncludes;
  // Diags that were attached to a line preserved in Modified contents.
  std::vector<Diag> PatchedDiags;
  PreambleBounds ModifiedBounds = {0, false};
  const PreambleData *Baseline = nullptr;
  std::vector<PragmaMark> PatchedMarks;
  MainFileMacros PatchedMacros;
};

} // namespace clangd
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREAMBLE_H
