//===--- JSONExpr.h - JSON expressions, parsing and serialization - C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//

// FIXME: rename to JSON.h now that the scope is wider?

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_JSON_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_JSON_H

#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include <map>

namespace clang {
namespace clangd {
namespace json {

// An Expr is an JSON value of unknown type.
// They can be copied, but should generally be moved.
//
// === Composing expressions ===
//
// You can implicitly construct Exprs from:
//   - strings: std::string, SmallString, formatv, StringRef, char*
//              (char*, and StringRef are references, not copies!)
//   - numbers
//   - booleans
//   - null: nullptr
//   - arrays: {"foo", 42.0, false}
//   - serializable things: types with toJSON(const T&)->Expr, found by ADL
//
// They can also be constructed from object/array helpers:
//   - json::obj is a type like map<StringExpr, Expr>
//   - json::ary is a type like vector<Expr>
// These can be list-initialized, or used to build up collections in a loop.
// json::ary(Collection) converts all items in a collection to Exprs.
//
// === Inspecting expressions ===
//
// Each Expr is one of the JSON kinds:
//   null    (nullptr_t)
//   boolean (bool)
//   number  (double)
//   string  (StringRef)
//   array   (json::ary)
//   object  (json::obj)
//
// The kind can be queried directly, or implicitly via the typed accessors:
//   if (Optional<StringRef> S = E.asString()
//     assert(E.kind() == Expr::String);
//
// Array and Object also have typed indexing accessors for easy traversal:
//   Expected<Expr> E = parse(R"( {"options": {"font": "sans-serif"}} )");
//   if (json::obj* O = E->asObject())
//     if (json::obj* Opts = O->getObject("options"))
//       if (Optional<StringRef> Font = Opts->getString("font"))
//         assert(Opts->at("font").kind() == Expr::String);
//
// === Converting expressions to objects ===
//
// The convention is to have a deserializer function findable via ADL:
//     fromJSON(const json::Expr&, T&)->bool
// Deserializers are provided for:
//   - bool
//   - int
//   - double
//   - std::string
//   - vector<T>, where T is deserializable
//   - map<string, T>, where T is deserializable
//   - Optional<T>, where T is deserializable
//
// ObjectMapper can help writing fromJSON() functions for object types:
//   bool fromJSON(const Expr &E, MyStruct &R) {
//     ObjectMapper O(E);
//     if (!O || !O.map("mandatory_field", R.MandatoryField))
//       return false;
//     O.map("optional_field", R.OptionalField);
//     return true;
//   }
//
// === Serialization ===
//
// Exprs can be serialized to JSON:
//   1) raw_ostream << Expr                    // Basic formatting.
//   2) raw_ostream << formatv("{0}", Expr)    // Basic formatting.
//   3) raw_ostream << formatv("{0:2}", Expr)  // Pretty-print with indent 2.
//
// And parsed:
//   Expected<Expr> E = json::parse("[1, 2, null]");
//   assert(E && E->kind() == Expr::Array);
class Expr {
public:
  enum Kind {
    Null,
    Boolean,
    Number,
    String,
    Array,
    Object,
  };
  class ObjectExpr;
  class ObjectKey;
  class ArrayExpr;

  // It would be nice to have Expr() be null. But that would make {} null too...
  Expr(const Expr &M) { copyFrom(M); }
  Expr(Expr &&M) { moveFrom(std::move(M)); }
  // "cheating" move-constructor for moving from initializer_list.
  Expr(const Expr &&M) { moveFrom(std::move(M)); }
  Expr(std::initializer_list<Expr> Elements) : Expr(ArrayExpr(Elements)) {}
  Expr(ArrayExpr &&Elements) : Type(T_Array) {
    create<ArrayExpr>(std::move(Elements));
  }
  Expr(ObjectExpr &&Properties) : Type(T_Object) {
    create<ObjectExpr>(std::move(Properties));
  }
  // Strings: types with value semantics.
  Expr(std::string &&V) : Type(T_String) { create<std::string>(std::move(V)); }
  Expr(const std::string &V) : Type(T_String) { create<std::string>(V); }
  Expr(const llvm::SmallVectorImpl<char> &V) : Type(T_String) {
    create<std::string>(V.begin(), V.end());
  }
  Expr(const llvm::formatv_object_base &V) : Expr(V.str()){};
  // Strings: types with reference semantics.
  Expr(llvm::StringRef V) : Type(T_StringRef) { create<llvm::StringRef>(V); }
  Expr(const char *V) : Type(T_StringRef) { create<llvm::StringRef>(V); }
  Expr(std::nullptr_t) : Type(T_Null) {}
  // Prevent implicit conversions to boolean.
  template <typename T, typename = typename std::enable_if<
                            std::is_same<T, bool>::value>::type>
  Expr(T B) : Type(T_Boolean) {
    create<bool>(B);
  }
  // Numbers: arithmetic types that are not boolean.
  template <
      typename T,
      typename = typename std::enable_if<std::is_arithmetic<T>::value>::type,
      typename = typename std::enable_if<std::integral_constant<
          bool, !std::is_same<T, bool>::value>::value>::type>
  Expr(T D) : Type(T_Number) {
    create<double>(D);
  }
  // Types with a toJSON(const T&)->Expr function, found by ADL.
  template <typename T,
            typename = typename std::enable_if<std::is_same<
                Expr, decltype(toJSON(*(const T *)nullptr))>::value>>
  Expr(const T &V) : Expr(toJSON(V)) {}

  Expr &operator=(const Expr &M) {
    destroy();
    copyFrom(M);
    return *this;
  }
  Expr &operator=(Expr &&M) {
    destroy();
    moveFrom(std::move(M));
    return *this;
  }
  ~Expr() { destroy(); }

  Kind kind() const {
    switch (Type) {
    case T_Null:
      return Null;
    case T_Boolean:
      return Boolean;
    case T_Number:
      return Number;
    case T_String:
    case T_StringRef:
      return String;
    case T_Object:
      return Object;
    case T_Array:
      return Array;
    }
    llvm_unreachable("Unknown kind");
  }

  // Typed accessors return None/nullptr if the Expr is not of this type.
  llvm::Optional<std::nullptr_t> asNull() const {
    if (LLVM_LIKELY(Type == T_Null))
      return nullptr;
    return llvm::None;
  }
  llvm::Optional<bool> asBoolean() const {
    if (LLVM_LIKELY(Type == T_Boolean))
      return as<bool>();
    return llvm::None;
  }
  llvm::Optional<double> asNumber() const {
    if (LLVM_LIKELY(Type == T_Number))
      return as<double>();
    return llvm::None;
  }
  llvm::Optional<int64_t> asInteger() const {
    if (LLVM_LIKELY(Type == T_Number)) {
      double D = as<double>();
      if (LLVM_LIKELY(std::modf(D, &D) == 0 &&
                      D >= std::numeric_limits<int64_t>::min() &&
                      D <= std::numeric_limits<int64_t>::max()))
        return D;
    }
    return llvm::None;
  }
  llvm::Optional<llvm::StringRef> asString() const {
    if (Type == T_String)
      return llvm::StringRef(as<std::string>());
    if (LLVM_LIKELY(Type == T_StringRef))
      return as<llvm::StringRef>();
    return llvm::None;
  }
  const ObjectExpr *asObject() const {
    return LLVM_LIKELY(Type == T_Object) ? &as<ObjectExpr>() : nullptr;
  }
  ObjectExpr *asObject() {
    return LLVM_LIKELY(Type == T_Object) ? &as<ObjectExpr>() : nullptr;
  }
  const ArrayExpr *asArray() const {
    return LLVM_LIKELY(Type == T_Array) ? &as<ArrayExpr>() : nullptr;
  }
  ArrayExpr *asArray() {
    return LLVM_LIKELY(Type == T_Array) ? &as<ArrayExpr>() : nullptr;
  }

  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Expr &);

private:
  void destroy();
  void copyFrom(const Expr &M);
  // We allow moving from *const* Exprs, by marking all members as mutable!
  // This hack is needed to support initializer-list syntax efficiently.
  // (std::initializer_list<T> is a container of const T).
  void moveFrom(const Expr &&M);

  template <typename T, typename... U> void create(U &&... V) {
    new (&as<T>()) T(std::forward<U>(V)...);
  }
  template <typename T> T &as() const {
    return *reinterpret_cast<T *>(Union.buffer);
  }

  template <typename Indenter>
  void print(llvm::raw_ostream &, const Indenter &) const;
  friend struct llvm::format_provider<clang::clangd::json::Expr>;

  enum ExprType : char {
    T_Null,
    T_Boolean,
    T_Number,
    T_StringRef,
    T_String,
    T_Object,
    T_Array,
  };
  mutable ExprType Type;

public:
  // ObjectKey is a used to capture keys in Expr::ObjectExpr. Like Expr but:
  //   - only strings are allowed
  //   - it's optimized for the string literal case (Owned == nullptr)
  class ObjectKey {
  public:
    ObjectKey(const char *S) : Data(S) {}
    ObjectKey(llvm::StringRef S) : Data(S) {}
    ObjectKey(std::string &&V)
        : Owned(new std::string(std::move(V))), Data(*Owned) {}
    ObjectKey(const std::string &V) : Owned(new std::string(V)), Data(*Owned) {}
    ObjectKey(const llvm::SmallVectorImpl<char> &V)
        : ObjectKey(std::string(V.begin(), V.end())) {}
    ObjectKey(const llvm::formatv_object_base &V) : ObjectKey(V.str()) {}

    ObjectKey(const ObjectKey &C) { *this = C; }
    ObjectKey(ObjectKey &&C) : ObjectKey(static_cast<const ObjectKey &&>(C)) {}
    ObjectKey &operator=(const ObjectKey &C) {
      if (C.Owned) {
        Owned.reset(new std::string(*C.Owned));
        Data = *Owned;
      } else {
        Data = C.Data;
      }
      return *this;
    }
    ObjectKey &operator=(ObjectKey &&) = default;

    operator llvm::StringRef() const { return Data; }

    friend bool operator<(const ObjectKey &L, const ObjectKey &R) {
      return L.Data < R.Data;
    }

    // "cheating" move-constructor for moving from initializer_list.
    ObjectKey(const ObjectKey &&V) {
      Owned = std::move(V.Owned);
      Data = V.Data;
    }

  private:
    mutable std::unique_ptr<std::string> Owned; // mutable for cheating.
    llvm::StringRef Data;
  };

  class ObjectExpr : public std::map<ObjectKey, Expr> {
  public:
    explicit ObjectExpr() {}
    // Use a custom struct for list-init, because pair forces extra copies.
    struct KV;
    explicit ObjectExpr(std::initializer_list<KV> Properties);

    // Allow [] as if Expr was default-constructible as null.
    Expr &operator[](const ObjectKey &K) {
      return emplace(K, Expr(nullptr)).first->second;
    }
    Expr &operator[](ObjectKey &&K) {
      return emplace(std::move(K), Expr(nullptr)).first->second;
    }

    // Look up a property, returning nullptr if it doesn't exist.
    json::Expr *get(const ObjectKey &K) {
      auto I = find(K);
      if (I == end())
        return nullptr;
      return &I->second;
    }
    const json::Expr *get(const ObjectKey &K) const {
      auto I = find(K);
      if (I == end())
        return nullptr;
      return &I->second;
    }
    // Typed accessors return None/nullptr if
    //   - the property doesn't exist
    //   - or it has the wrong type
    llvm::Optional<std::nullptr_t> getNull(const ObjectKey &K) const {
      if (auto *V = get(K))
        return V->asNull();
      return llvm::None;
    }
    llvm::Optional<bool> getBoolean(const ObjectKey &K) const {
      if (auto *V = get(K))
        return V->asBoolean();
      return llvm::None;
    }
    llvm::Optional<double> getNumber(const ObjectKey &K) const {
      if (auto *V = get(K))
        return V->asNumber();
      return llvm::None;
    }
    llvm::Optional<int64_t> getInteger(const ObjectKey &K) const {
      if (auto *V = get(K))
        return V->asInteger();
      return llvm::None;
    }
    llvm::Optional<llvm::StringRef> getString(const ObjectKey &K) const {
      if (auto *V = get(K))
        return V->asString();
      return llvm::None;
    }
    const ObjectExpr *getObject(const ObjectKey &K) const {
      if (auto *V = get(K))
        return V->asObject();
      return nullptr;
    }
    ObjectExpr *getObject(const ObjectKey &K) {
      if (auto *V = get(K))
        return V->asObject();
      return nullptr;
    }
    const ArrayExpr *getArray(const ObjectKey &K) const {
      if (auto *V = get(K))
        return V->asArray();
      return nullptr;
    }
    ArrayExpr *getArray(const ObjectKey &K) {
      if (auto *V = get(K))
        return V->asArray();
      return nullptr;
    }
  };

  class ArrayExpr : public std::vector<Expr> {
  public:
    explicit ArrayExpr() {}
    explicit ArrayExpr(std::initializer_list<Expr> Elements) {
      reserve(Elements.size());
      for (const Expr &V : Elements)
        emplace_back(std::move(V));
    };
    template <typename Collection> explicit ArrayExpr(const Collection &C) {
      for (const auto &V : C)
        emplace_back(V);
    }

    // Typed accessors return None/nullptr if the element has the wrong type.
    llvm::Optional<std::nullptr_t> getNull(size_t I) const {
      return (*this)[I].asNull();
    }
    llvm::Optional<bool> getBoolean(size_t I) const {
      return (*this)[I].asBoolean();
    }
    llvm::Optional<double> getNumber(size_t I) const {
      return (*this)[I].asNumber();
    }
    llvm::Optional<int64_t> getInteger(size_t I) const {
      return (*this)[I].asInteger();
    }
    llvm::Optional<llvm::StringRef> getString(size_t I) const {
      return (*this)[I].asString();
    }
    const ObjectExpr *getObject(size_t I) const {
      return (*this)[I].asObject();
    }
    ObjectExpr *getObject(size_t I) { return (*this)[I].asObject(); }
    const ArrayExpr *getArray(size_t I) const { return (*this)[I].asArray(); }
    ArrayExpr *getArray(size_t I) { return (*this)[I].asArray(); }
  };

private:
  mutable llvm::AlignedCharArrayUnion<bool, double, llvm::StringRef,
                                      std::string, ArrayExpr, ObjectExpr>
      Union;
};

bool operator==(const Expr &, const Expr &);
inline bool operator!=(const Expr &L, const Expr &R) { return !(L == R); }
inline bool operator==(const Expr::ObjectKey &L, const Expr::ObjectKey &R) {
  return llvm::StringRef(L) == llvm::StringRef(R);
}
inline bool operator!=(const Expr::ObjectKey &L, const Expr::ObjectKey &R) {
  return !(L == R);
}

struct Expr::ObjectExpr::KV {
  ObjectKey K;
  Expr V;
};

inline Expr::ObjectExpr::ObjectExpr(std::initializer_list<KV> Properties) {
  for (const auto &P : Properties)
    emplace(std::move(P.K), std::move(P.V));
}

// Give Expr::{Object,Array} more convenient names for literal use.
using obj = Expr::ObjectExpr;
using ary = Expr::ArrayExpr;

// Standard deserializers.
inline bool fromJSON(const json::Expr &E, std::string &Out) {
  if (auto S = E.asString()) {
    Out = *S;
    return true;
  }
  return false;
}
inline bool fromJSON(const json::Expr &E, int &Out) {
  if (auto S = E.asInteger()) {
    Out = *S;
    return true;
  }
  return false;
}
inline bool fromJSON(const json::Expr &E, double &Out) {
  if (auto S = E.asNumber()) {
    Out = *S;
    return true;
  }
  return false;
}
inline bool fromJSON(const json::Expr &E, bool &Out) {
  if (auto S = E.asBoolean()) {
    Out = *S;
    return true;
  }
  return false;
}
template <typename T>
bool fromJSON(const json::Expr &E, llvm::Optional<T> &Out) {
  if (E.asNull()) {
    Out = llvm::None;
    return true;
  }
  T Result;
  if (!fromJSON(E, Result))
    return false;
  Out = std::move(Result);
  return true;
}
template <typename T> bool fromJSON(const json::Expr &E, std::vector<T> &Out) {
  if (auto *A = E.asArray()) {
    Out.clear();
    Out.resize(A->size());
    for (size_t I = 0; I < A->size(); ++I)
      if (!fromJSON((*A)[I], Out[I]))
        return false;
    return true;
  }
  return false;
}
template <typename T>
bool fromJSON(const json::Expr &E, std::map<std::string, T> &Out) {
  if (auto *O = E.asObject()) {
    Out.clear();
    for (const auto &KV : *O)
      if (!fromJSON(KV.second, Out[llvm::StringRef(KV.first)]))
        return false;
    return true;
  }
  return false;
}

// Helper for mapping JSON objects onto protocol structs.
// See file header for example.
class ObjectMapper {
public:
  ObjectMapper(const json::Expr &E) : O(E.asObject()) {}

  // True if the expression is an object.
  // Must be checked before calling map().
  operator bool() { return O; }

  // Maps a property to a field, if it exists.
  template <typename T> bool map(const char *Prop, T &Out) {
    assert(*this && "Must check this is an object before calling map()");
    if (const json::Expr *E = O->get(Prop))
      return fromJSON(*E, Out);
    return false;
  }

  // Optional requires special handling, because missing keys are OK.
  template <typename T> bool map(const char *Prop, llvm::Optional<T> &Out) {
    assert(*this && "Must check this is an object before calling map()");
    if (const json::Expr *E = O->get(Prop))
      return fromJSON(*E, Out);
    Out = llvm::None;
    return true;
  }

private:
  const json::obj *O;
};

llvm::Expected<Expr> parse(llvm::StringRef JSON);

class ParseError : public llvm::ErrorInfo<ParseError> {
  const char *Msg;
  unsigned Line, Column, Offset;

public:
  static char ID;
  ParseError(const char *Msg, unsigned Line, unsigned Column, unsigned Offset)
      : Msg(Msg), Line(Line), Column(Column), Offset(Offset) {}
  void log(llvm::raw_ostream &OS) const override {
    OS << llvm::formatv("[{0}:{1}, byte={2}]: {3}", Line, Column, Offset, Msg);
  }
  std::error_code convertToErrorCode() const override {
    return llvm::inconvertibleErrorCode();
  }
};

} // namespace json
} // namespace clangd
} // namespace clang

namespace llvm {
template <> struct format_provider<clang::clangd::json::Expr> {
  static void format(const clang::clangd::json::Expr &, raw_ostream &,
                     StringRef);
};
} // namespace llvm

#endif
