//===--- PrecompiledPreamble.h - Build precompiled preambles ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Helper class to build precompiled preamble.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_FRONTEND_PRECOMPILED_PREAMBLE_H
#define LLVM_CLANG_FRONTEND_PRECOMPILED_PREAMBLE_H

#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/MD5.h"
#include <cstddef>
#include <memory>
#include <system_error>
#include <type_traits>

namespace llvm {
class MemoryBuffer;
}

namespace clang {
namespace vfs {
class FileSystem;
}

class CompilerInstance;
class CompilerInvocation;
class DeclGroupRef;
class PCHContainerOperations;

/// \brief Runs lexer to compute suggested preamble bounds.
PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts,
                                     llvm::MemoryBuffer *Buffer,
                                     unsigned MaxLines);

class PreambleCallbacks;

/// A class holding a PCH and all information to check whether it is valid to
/// reuse the PCH for the subsequent runs. Use BuildPreamble to create PCH and
/// CanReusePreamble + AddImplicitPreamble to make use of it.
class PrecompiledPreamble {
  class PCHStorage;
  struct PreambleFileHash;

public:
  /// \brief Try to build PrecompiledPreamble for \p Invocation. See
  /// BuildPreambleError for possible error codes.
  ///
  /// \param Invocation Original CompilerInvocation with options to compile the
  /// file.
  ///
  /// \param MainFileBuffer Buffer with the contents of the main file.
  ///
  /// \param Bounds Bounds of the preamble, result of calling
  /// ComputePreambleBounds.
  ///
  /// \param Diagnostics Diagnostics engine to be used while building the
  /// preamble.
  ///
  /// \param VFS An instance of vfs::FileSystem to be used for file
  /// accesses.
  ///
  /// \param PCHContainerOps An instance of PCHContainerOperations.
  ///
  /// \param StoreInMemory Store PCH in memory. If false, PCH will be stored in
  /// a temporary file.
  ///
  /// \param Callbacks A set of callbacks to be executed when building
  /// the preamble.
  static llvm::ErrorOr<PrecompiledPreamble>
  Build(const CompilerInvocation &Invocation,
        const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
        DiagnosticsEngine &Diagnostics, IntrusiveRefCntPtr<vfs::FileSystem> VFS,
        std::shared_ptr<PCHContainerOperations> PCHContainerOps,
        bool StoreInMemory, PreambleCallbacks &Callbacks);

  PrecompiledPreamble(PrecompiledPreamble &&) = default;
  PrecompiledPreamble &operator=(PrecompiledPreamble &&) = default;

  /// PreambleBounds used to build the preamble.
  PreambleBounds getBounds() const;

  /// Returns the size, in bytes, that preamble takes on disk or in memory.
  /// For on-disk preambles returns 0 if filesystem operations fail. Intended to
  /// be used for logging and debugging purposes only.
  std::size_t getSize() const;

  /// Check whether PrecompiledPreamble can be reused for the new contents(\p
  /// MainFileBuffer) of the main file.
  bool CanReuse(const CompilerInvocation &Invocation,
                const llvm::MemoryBuffer *MainFileBuffer, PreambleBounds Bounds,
                vfs::FileSystem *VFS) const;

  /// Changes options inside \p CI to use PCH from this preamble. Also remaps
  /// main file to \p MainFileBuffer and updates \p VFS to ensure the preamble
  /// is accessible.
  /// For in-memory preambles, PrecompiledPreamble instance continues to own
  /// the MemoryBuffer with the Preamble after this method returns. The caller
  /// is reponsible for making sure the PrecompiledPreamble instance outlives
  /// the compiler run and the AST that will be using the PCH.
  void AddImplicitPreamble(CompilerInvocation &CI,
                           IntrusiveRefCntPtr<vfs::FileSystem> &VFS,
                           llvm::MemoryBuffer *MainFileBuffer) const;

private:
  PrecompiledPreamble(PCHStorage Storage, std::vector<char> PreambleBytes,
                      bool PreambleEndsAtStartOfLine,
                      llvm::StringMap<PreambleFileHash> FilesInPreamble);

  /// A temp file that would be deleted on destructor call. If destructor is not
  /// called for any reason, the file will be deleted at static objects'
  /// destruction.
  /// An assertion will fire if two TempPCHFiles are created with the same name,
  /// so it's not intended to be used outside preamble-handling.
  class TempPCHFile {
  public:
    // A main method used to construct TempPCHFile.
    static llvm::ErrorOr<TempPCHFile> CreateNewPreamblePCHFile();

    /// Call llvm::sys::fs::createTemporaryFile to create a new temporary file.
    static llvm::ErrorOr<TempPCHFile> createInSystemTempDir(const Twine &Prefix,
                                                            StringRef Suffix);
    /// Create a new instance of TemporaryFile for file at \p Path. Use with
    /// extreme caution, there's an assertion checking that there's only a
    /// single instance of TempPCHFile alive for each path.
    static llvm::ErrorOr<TempPCHFile> createFromCustomPath(const Twine &Path);

  private:
    TempPCHFile(std::string FilePath);

  public:
    TempPCHFile(TempPCHFile &&Other);
    TempPCHFile &operator=(TempPCHFile &&Other);

    TempPCHFile(const TempPCHFile &) = delete;
    ~TempPCHFile();

    /// A path where temporary file is stored.
    llvm::StringRef getFilePath() const;

  private:
    void RemoveFileIfPresent();

  private:
    llvm::Optional<std::string> FilePath;
  };

  class InMemoryPreamble {
  public:
    std::string Data;
  };

  class PCHStorage {
  public:
    enum class Kind { Empty, InMemory, TempFile };

    PCHStorage() = default;
    PCHStorage(TempPCHFile File);
    PCHStorage(InMemoryPreamble Memory);

    PCHStorage(const PCHStorage &) = delete;
    PCHStorage &operator=(const PCHStorage &) = delete;

    PCHStorage(PCHStorage &&Other);
    PCHStorage &operator=(PCHStorage &&Other);

    ~PCHStorage();

    Kind getKind() const;

    TempPCHFile &asFile();
    const TempPCHFile &asFile() const;

    InMemoryPreamble &asMemory();
    const InMemoryPreamble &asMemory() const;

  private:
    void destroy();
    void setEmpty();

  private:
    Kind StorageKind = Kind::Empty;
    llvm::AlignedCharArrayUnion<TempPCHFile, InMemoryPreamble> Storage = {};
  };

  /// Data used to determine if a file used in the preamble has been changed.
  struct PreambleFileHash {
    /// All files have size set.
    off_t Size = 0;

    /// Modification time is set for files that are on disk.  For memory
    /// buffers it is zero.
    time_t ModTime = 0;

    /// Memory buffers have MD5 instead of modification time.  We don't
    /// compute MD5 for on-disk files because we hope that modification time is
    /// enough to tell if the file was changed.
    llvm::MD5::MD5Result MD5 = {};

    static PreambleFileHash createForFile(off_t Size, time_t ModTime);
    static PreambleFileHash
    createForMemoryBuffer(const llvm::MemoryBuffer *Buffer);

    friend bool operator==(const PreambleFileHash &LHS,
                           const PreambleFileHash &RHS) {
      return LHS.Size == RHS.Size && LHS.ModTime == RHS.ModTime &&
             LHS.MD5 == RHS.MD5;
    }
    friend bool operator!=(const PreambleFileHash &LHS,
                           const PreambleFileHash &RHS) {
      return !(LHS == RHS);
    }
  };

  /// Sets up the PreprocessorOptions and changes VFS, so that PCH stored in \p
  /// Storage is accessible to clang. This method is an implementation detail of
  /// AddImplicitPreamble.
  static void setupPreambleStorage(const PCHStorage &Storage,
                                   PreprocessorOptions &PreprocessorOpts,
                                   IntrusiveRefCntPtr<vfs::FileSystem> &VFS);

  /// Manages the memory buffer or temporary file that stores the PCH.
  PCHStorage Storage;
  /// Keeps track of the files that were used when computing the
  /// preamble, with both their buffer size and their modification time.
  ///
  /// If any of the files have changed from one compile to the next,
  /// the preamble must be thrown away.
  llvm::StringMap<PreambleFileHash> FilesInPreamble;
  /// The contents of the file that was used to precompile the preamble. Only
  /// contains first PreambleBounds::Size bytes. Used to compare if the relevant
  /// part of the file has not changed, so that preamble can be reused.
  std::vector<char> PreambleBytes;
  /// See PreambleBounds::PreambleEndsAtStartOfLine
  bool PreambleEndsAtStartOfLine;
};

/// A set of callbacks to gather useful information while building a preamble.
class PreambleCallbacks {
public:
  virtual ~PreambleCallbacks() = default;

  /// Called before FrontendAction::BeginSourceFile.
  /// Can be used to store references to various CompilerInstance fields
  /// (e.g. SourceManager) that may be interesting to the consumers of other
  /// callbacks.
  virtual void BeforeExecute(CompilerInstance &CI);
  /// Called after FrontendAction::Execute(), but before
  /// FrontendAction::EndSourceFile(). Can be used to transfer ownership of
  /// various CompilerInstance fields before they are destroyed.
  virtual void AfterExecute(CompilerInstance &CI);
  /// Called after PCH has been emitted. \p Writer may be used to retrieve
  /// information about AST, serialized in PCH.
  virtual void AfterPCHEmitted(ASTWriter &Writer);
  /// Called for each TopLevelDecl.
  /// NOTE: To allow more flexibility a custom ASTConsumer could probably be
  /// used instead, but having only this method allows a simpler API.
  virtual void HandleTopLevelDecl(DeclGroupRef DG);
  /// Creates wrapper class for PPCallbacks so we can also process information
  /// about includes that are inside of a preamble
  virtual std::unique_ptr<PPCallbacks> createPPCallbacks();
};

enum class BuildPreambleError {
  PreambleIsEmpty = 1,
  CouldntCreateTempFile,
  CouldntCreateTargetInfo,
  CouldntCreateVFSOverlay,
  BeginSourceFileFailed,
  CouldntEmitPCH
};

class BuildPreambleErrorCategory final : public std::error_category {
public:
  const char *name() const noexcept override;
  std::string message(int condition) const override;
};

std::error_code make_error_code(BuildPreambleError Error);
} // namespace clang

namespace std {
template <>
struct is_error_code_enum<clang::BuildPreambleError> : std::true_type {};
} // namespace std

#endif
