//===-- MsgPackDocumentYAML.cpp - MsgPack Document YAML interface -------*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// This file implements YAMLIO on a msgpack::Document.
//
//===----------------------------------------------------------------------===//

#include "llvm/BinaryFormat/MsgPackDocument.h"
#include "llvm/Support/YAMLTraits.h"

using namespace llvm;
using namespace msgpack;

namespace {

// Struct used to represent scalar node. (MapDocNode and ArrayDocNode already
// exist in MsgPackDocument.h.)
struct ScalarDocNode : DocNode {
  ScalarDocNode(DocNode N) : DocNode(N) {}

  /// Get the YAML tag for this ScalarDocNode. This normally returns ""; it only
  /// returns something else if the result of toString would be ambiguous, e.g.
  /// a string that parses as a number or boolean.
  StringRef getYAMLTag() const;
};

} // namespace

/// Convert this DocNode to a string, assuming it is scalar.
std::string DocNode::toString() const {
  std::string S;
  raw_string_ostream OS(S);
  switch (getKind()) {
  case msgpack::Type::String:
    OS << Raw;
    break;
  case msgpack::Type::Nil:
    break;
  case msgpack::Type::Boolean:
    OS << (Bool ? "true" : "false");
    break;
  case msgpack::Type::Int:
    OS << Int;
    break;
  case msgpack::Type::UInt:
    if (getDocument()->getHexMode())
      OS << format("%#llx", (unsigned long long)UInt);
    else
      OS << UInt;
    break;
  case msgpack::Type::Float:
    OS << Float;
    break;
  default:
    llvm_unreachable("not scalar");
    break;
  }
  return OS.str();
}

/// Convert the StringRef and use it to set this DocNode (assuming scalar). If
/// it is a string, copy the string into the Document's strings list so we do
/// not rely on S having a lifetime beyond this call. Tag is "" or a YAML tag.
StringRef DocNode::fromString(StringRef S, StringRef Tag) {
  if (Tag == "tag:yaml.org,2002:str")
    Tag = "";
  if (Tag == "!int" || Tag == "") {
    // Try unsigned int then signed int.
    *this = getDocument()->getNode(uint64_t(0));
    StringRef Err = yaml::ScalarTraits<uint64_t>::input(S, nullptr, getUInt());
    if (Err != "") {
      *this = getDocument()->getNode(int64_t(0));
      Err = yaml::ScalarTraits<int64_t>::input(S, nullptr, getInt());
    }
    if (Err == "" || Tag != "")
      return Err;
  }
  if (Tag == "!nil") {
    *this = getDocument()->getNode();
    return "";
  }
  if (Tag == "!bool" || Tag == "") {
    *this = getDocument()->getNode(false);
    StringRef Err = yaml::ScalarTraits<bool>::input(S, nullptr, getBool());
    if (Err == "" || Tag != "")
      return Err;
  }
  if (Tag == "!float" || Tag == "") {
    *this = getDocument()->getNode(0.0);
    StringRef Err = yaml::ScalarTraits<double>::input(S, nullptr, getFloat());
    if (Err == "" || Tag != "")
      return Err;
  }
  assert((Tag == "!str" || Tag == "") && "unsupported tag");
  std::string V;
  StringRef Err = yaml::ScalarTraits<std::string>::input(S, nullptr, V);
  if (Err == "")
    *this = getDocument()->getNode(V, /*Copy=*/true);
  return Err;
}

/// Get the YAML tag for this ScalarDocNode. This normally returns ""; it only
/// returns something else if the result of toString would be ambiguous, e.g.
/// a string that parses as a number or boolean.
StringRef ScalarDocNode::getYAMLTag() const {
  if (getKind() == msgpack::Type::Nil)
    return "!nil";
  // Try converting both ways and see if we get the same kind. If not, we need
  // a tag.
  ScalarDocNode N = getDocument()->getNode();
  N.fromString(toString(), "");
  if (N.getKind() == getKind())
    return "";
  // Tolerate signedness of int changing, as tags do not differentiate between
  // them anyway.
  if (N.getKind() == msgpack::Type::UInt && getKind() == msgpack::Type::Int)
    return "";
  if (N.getKind() == msgpack::Type::Int && getKind() == msgpack::Type::UInt)
    return "";
  // We do need a tag.
  switch (getKind()) {
  case msgpack::Type::String:
    return "!str";
  case msgpack::Type::Int:
    return "!int";
  case msgpack::Type::UInt:
    return "!int";
  case msgpack::Type::Boolean:
    return "!bool";
  case msgpack::Type::Float:
    return "!float";
  default:
    llvm_unreachable("unrecognized kind");
  }
}

namespace llvm {
namespace yaml {

/// YAMLIO for DocNode
template <> struct PolymorphicTraits<DocNode> {

  static NodeKind getKind(const DocNode &N) {
    switch (N.getKind()) {
    case msgpack::Type::Map:
      return NodeKind::Map;
    case msgpack::Type::Array:
      return NodeKind::Sequence;
    default:
      return NodeKind::Scalar;
    }
  }

  static MapDocNode &getAsMap(DocNode &N) { return N.getMap(/*Convert=*/true); }

  static ArrayDocNode &getAsSequence(DocNode &N) {
    N.getArray(/*Convert=*/true);
    return *static_cast<ArrayDocNode *>(&N);
  }

  static ScalarDocNode &getAsScalar(DocNode &N) {
    return *static_cast<ScalarDocNode *>(&N);
  }
};

/// YAMLIO for ScalarDocNode
template <> struct TaggedScalarTraits<ScalarDocNode> {

  static void output(const ScalarDocNode &S, void *Ctxt, raw_ostream &OS,
                     raw_ostream &TagOS) {
    TagOS << S.getYAMLTag();
    OS << S.toString();
  }

  static StringRef input(StringRef Str, StringRef Tag, void *Ctxt,
                         ScalarDocNode &S) {
    return S.fromString(Str, Tag);
  }

  static QuotingType mustQuote(const ScalarDocNode &S, StringRef ScalarStr) {
    switch (S.getKind()) {
    case Type::Int:
      return ScalarTraits<int64_t>::mustQuote(ScalarStr);
    case Type::UInt:
      return ScalarTraits<uint64_t>::mustQuote(ScalarStr);
    case Type::Nil:
      return ScalarTraits<StringRef>::mustQuote(ScalarStr);
    case Type::Boolean:
      return ScalarTraits<bool>::mustQuote(ScalarStr);
    case Type::Float:
      return ScalarTraits<double>::mustQuote(ScalarStr);
    case Type::Binary:
    case Type::String:
      return ScalarTraits<std::string>::mustQuote(ScalarStr);
    default:
      llvm_unreachable("unrecognized ScalarKind");
    }
  }
};

/// YAMLIO for MapDocNode
template <> struct CustomMappingTraits<MapDocNode> {

  static void inputOne(IO &IO, StringRef Key, MapDocNode &M) {
    ScalarDocNode KeyObj = M.getDocument()->getNode();
    KeyObj.fromString(Key, "");
    IO.mapRequired(Key.str().c_str(), M.getMap()[KeyObj]);
  }

  static void output(IO &IO, MapDocNode &M) {
    for (auto I : M.getMap()) {
      IO.mapRequired(I.first.toString().c_str(), I.second);
    }
  }
};

/// YAMLIO for ArrayNode
template <> struct SequenceTraits<ArrayDocNode> {

  static size_t size(IO &IO, ArrayDocNode &A) { return A.size(); }

  static DocNode &element(IO &IO, ArrayDocNode &A, size_t Index) {
    return A[Index];
  }
};

} // namespace yaml
} // namespace llvm

/// Convert MsgPack Document to YAML text.
void msgpack::Document::toYAML(raw_ostream &OS) {
  yaml::Output Yout(OS);
  Yout << getRoot();
}

/// Read YAML text into the MsgPack document. Returns false on failure.
bool msgpack::Document::fromYAML(StringRef S) {
  clear();
  yaml::Input Yin(S);
  Yin >> getRoot();
  return !Yin.error();
}

