//===--- Context.h - Mechanism for passing implicit data --------*- C++-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Context for storing and retrieving implicit data. Useful for passing implicit
// parameters on a per-request basis.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONTEXT_H_
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONTEXT_H_

#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include <memory>
#include <type_traits>

namespace clang {
namespace clangd {

/// Values in a Context are indexed by typed keys.
/// Key<T> serves two purposes:
///   - it provides a lookup key for the context (each Key is unique),
///   - it makes lookup type-safe: a Key<T> can only map to a T (or nothing).
///
/// Example:
///    Key<int> RequestID;
///    Key<int> Version;
///
///    Context Ctx = Context::empty().derive(RequestID, 10).derive(Version, 3);
///    assert(*Ctx.get(RequestID) == 10);
///    assert(*Ctx.get(Version) == 3);
///
/// Keys are typically used across multiple functions, so most of the time you
/// would want to make them static class members or global variables.
template <class Type> class Key {
public:
  static_assert(!std::is_reference<Type>::value,
                "Reference arguments to Key<> are not allowed");

  Key() = default;

  Key(Key const &) = delete;
  Key &operator=(Key const &) = delete;
  Key(Key &&) = delete;
  Key &operator=(Key &&) = delete;
};

/// A context is an immutable container for per-request data that must be
/// propagated through layers that don't care about it. An example is a request
/// ID that we may want to use when logging.
///
/// Conceptually, a context is a heterogeneous map<Key<T>, T>. Each key has
/// an associated value type, which allows the map to be typesafe.
///
/// There is an "ambient" context for each thread, Context::current().
/// Most functions should read from this, and use WithContextValue or
/// WithContext to extend or replace the context within a block scope.
/// Only code dealing with threads and extension points should need to use
/// other Context objects.
///
/// You can't add data to an existing context, instead you create a new
/// immutable context derived from it with extra data added. When you retrieve
/// data, the context will walk up the parent chain until the key is found.
class Context {
public:
  /// Returns an empty root context that contains no data.
  static Context empty();
  /// Returns the context for the current thread, creating it if needed.
  static const Context &current();
  // Sets the current() context to Replacement, and returns the old context.
  // Prefer to use WithContext or WithContextValue to do this safely.
  static Context swapCurrent(Context Replacement);

private:
  struct Data;
  Context(std::shared_ptr<const Data> DataPtr);

public:
  /// Same as Context::empty(), please use Context::empty() instead.
  /// Constructor is defined to workaround a bug in MSVC's version of STL.
  /// (arguments of std::future<> must be default-construcitble in MSVC).
  Context() = default;

  /// Copy operations for this class are deleted, use an explicit clone() method
  /// when you need a copy of the context instead.
  Context(Context const &) = delete;
  Context &operator=(const Context &) = delete;

  Context(Context &&) = default;
  Context &operator=(Context &&) = default;

  /// Get data stored for a typed \p Key. If values are not found
  /// \returns Pointer to the data associated with \p Key. If no data is
  /// specified for \p Key, return null.
  template <class Type> const Type *get(const Key<Type> &Key) const {
    for (const Data *DataPtr = this->DataPtr.get(); DataPtr != nullptr;
         DataPtr = DataPtr->Parent.get()) {
      if (DataPtr->KeyPtr == &Key)
        return static_cast<const Type *>(DataPtr->Value->getValuePtr());
    }
    return nullptr;
  }

  /// A helper to get a reference to a \p Key that must exist in the map.
  /// Must not be called for keys that are not in the map.
  template <class Type> const Type &getExisting(const Key<Type> &Key) const {
    auto Val = get(Key);
    assert(Val && "Key does not exist");
    return *Val;
  }

  /// Derives a child context
  /// It is safe to move or destroy a parent context after calling derive().
  /// The child will keep its parent alive, and its data remains accessible.
  template <class Type>
  Context derive(const Key<Type> &Key,
                 typename std::decay<Type>::type Value) const & {
    return Context(std::make_shared<Data>(Data{
        /*Parent=*/DataPtr, &Key,
        llvm::make_unique<TypedAnyStorage<typename std::decay<Type>::type>>(
            std::move(Value))}));
  }

  template <class Type>
  Context
  derive(const Key<Type> &Key,
         typename std::decay<Type>::type Value) && /* takes ownership */ {
    return Context(std::make_shared<Data>(Data{
        /*Parent=*/std::move(DataPtr), &Key,
        llvm::make_unique<TypedAnyStorage<typename std::decay<Type>::type>>(
            std::move(Value))}));
  }

  /// Derives a child context, using an anonymous key.
  /// Intended for objects stored only for their destructor's side-effect.
  template <class Type> Context derive(Type &&Value) const & {
    static Key<typename std::decay<Type>::type> Private;
    return derive(Private, std::forward<Type>(Value));
  }

  template <class Type> Context derive(Type &&Value) && {
    static Key<typename std::decay<Type>::type> Private;
    return std::move(this)->derive(Private, std::forward<Type>(Value));
  }

  /// Clone this context object.
  Context clone() const;

private:
  class AnyStorage {
  public:
    virtual ~AnyStorage() = default;
    virtual void *getValuePtr() = 0;
  };

  template <class T> class TypedAnyStorage : public Context::AnyStorage {
    static_assert(std::is_same<typename std::decay<T>::type, T>::value,
                  "Argument to TypedAnyStorage must be decayed");

  public:
    TypedAnyStorage(T &&Value) : Value(std::move(Value)) {}

    void *getValuePtr() override { return &Value; }

  private:
    T Value;
  };

  struct Data {
    // We need to make sure Parent outlives the Value, so the order of members
    // is important. We do that to allow classes stored in Context's child
    // layers to store references to the data in the parent layers.
    std::shared_ptr<const Data> Parent;
    const void *KeyPtr;
    std::unique_ptr<AnyStorage> Value;
  };

  std::shared_ptr<const Data> DataPtr;
};

/// WithContext replaces Context::current() with a provided scope.
/// When the WithContext is destroyed, the original scope is restored.
/// For extending the current context with new value, prefer WithContextValue.
class LLVM_NODISCARD WithContext {
public:
  WithContext(Context C) : Restore(Context::swapCurrent(std::move(C))) {}
  ~WithContext() { Context::swapCurrent(std::move(Restore)); }
  WithContext(const WithContext &) = delete;
  WithContext &operator=(const WithContext &) = delete;
  WithContext(WithContext &&) = delete;
  WithContext &operator=(WithContext &&) = delete;

private:
  Context Restore;
};

/// WithContextValue extends Context::current() with a single value.
/// When the WithContextValue is destroyed, the original scope is restored.
class LLVM_NODISCARD WithContextValue {
public:
  template <typename T>
  WithContextValue(const Key<T> &K, typename std::decay<T>::type V)
      : Restore(Context::current().derive(K, std::move(V))) {}

  // Anonymous values can be used for the destructor side-effect.
  template <typename T>
  WithContextValue(T &&V)
      : Restore(Context::current().derive(std::forward<T>(V))) {}

private:
  WithContext Restore;
};

} // namespace clangd
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONTEXT_H_
