//===- JSONBackend.cpp - Generate a JSON dump of all records. -*- 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
//
//===----------------------------------------------------------------------===//
//
// This TableGen back end generates a machine-readable representation
// of all the classes and records defined by the input, in JSON format.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/JSON.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"

#define DEBUG_TYPE "json-emitter"

using namespace llvm;

namespace {

class JSONEmitter {
private:
  RecordKeeper &Records;

  json::Value translateInit(const Init &I);

public:
  JSONEmitter(RecordKeeper &R);

  void run(raw_ostream &OS);
};

} // end anonymous namespace

JSONEmitter::JSONEmitter(RecordKeeper &R) : Records(R) {}

json::Value JSONEmitter::translateInit(const Init &I) {

  // Init subclasses that we return as JSON primitive values of one
  // kind or another.

  if (isa<UnsetInit>(&I)) {
    return nullptr;
  } else if (auto *Bit = dyn_cast<BitInit>(&I)) {
    return Bit->getValue() ? 1 : 0;
  } else if (auto *Bits = dyn_cast<BitsInit>(&I)) {
    json::Array array;
    for (unsigned i = 0, limit = Bits->getNumBits(); i < limit; i++)
      array.push_back(translateInit(*Bits->getBit(i)));
    return std::move(array);
  } else if (auto *Int = dyn_cast<IntInit>(&I)) {
    return Int->getValue();
  } else if (auto *Str = dyn_cast<StringInit>(&I)) {
    return Str->getValue();
  } else if (auto *List = dyn_cast<ListInit>(&I)) {
    json::Array array;
    for (auto *val : *List)
      array.push_back(translateInit(*val));
    return std::move(array);
  }

  // Init subclasses that we return as JSON objects containing a
  // 'kind' discriminator. For these, we also provide the same
  // translation back into TableGen input syntax that -print-records
  // would give.

  json::Object obj;
  obj["printable"] = I.getAsString();

  if (auto *Def = dyn_cast<DefInit>(&I)) {
    obj["kind"] = "def";
    obj["def"] = Def->getDef()->getName();
    return std::move(obj);
  } else if (auto *Var = dyn_cast<VarInit>(&I)) {
    obj["kind"] = "var";
    obj["var"] = Var->getName();
    return std::move(obj);
  } else if (auto *VarBit = dyn_cast<VarBitInit>(&I)) {
    if (auto *Var = dyn_cast<VarInit>(VarBit->getBitVar())) {
      obj["kind"] = "varbit";
      obj["var"] = Var->getName();
      obj["index"] = VarBit->getBitNum();
      return std::move(obj);
    }
  } else if (auto *Dag = dyn_cast<DagInit>(&I)) {
    obj["kind"] = "dag";
    obj["operator"] = translateInit(*Dag->getOperator());
    if (auto name = Dag->getName())
      obj["name"] = name->getAsUnquotedString();
    json::Array args;
    for (unsigned i = 0, limit = Dag->getNumArgs(); i < limit; ++i) {
      json::Array arg;
      arg.push_back(translateInit(*Dag->getArg(i)));
      if (auto argname = Dag->getArgName(i))
        arg.push_back(argname->getAsUnquotedString());
      else
        arg.push_back(nullptr);
      args.push_back(std::move(arg));
    }
    obj["args"] = std::move(args);
    return std::move(obj);
  }

  // Final fallback: anything that gets past here is simply given a
  // kind field of 'complex', and the only other field is the standard
  // 'printable' representation.

  assert(!I.isConcrete());
  obj["kind"] = "complex";
  return std::move(obj);
}

void JSONEmitter::run(raw_ostream &OS) {
  json::Object root;

  root["!tablegen_json_version"] = 1;

  // Prepare the arrays that will list the instances of every class.
  // We mostly fill those in by iterating over the superclasses of
  // each def, but we also want to ensure we store an empty list for a
  // class with no instances at all, so we do a preliminary iteration
  // over the classes, invoking std::map::operator[] to default-
  // construct the array for each one.
  std::map<std::string, json::Array> instance_lists;
  for (const auto &C : Records.getClasses()) {
    const auto Name = C.second->getNameInitAsString();
    (void)instance_lists[Name];
  }

  // Main iteration over the defs.
  for (const auto &D : Records.getDefs()) {
    const auto Name = D.second->getNameInitAsString();
    auto &Def = *D.second;

    json::Object obj;
    json::Array fields;

    for (const RecordVal &RV : Def.getValues()) {
      if (!Def.isTemplateArg(RV.getNameInit())) {
        auto Name = RV.getNameInitAsString();
        if (RV.isNonconcreteOK())
          fields.push_back(Name);
        obj[Name] = translateInit(*RV.getValue());
      }
    }

    obj["!fields"] = std::move(fields);

    json::Array superclasses;
    for (const auto &SuperPair : Def.getSuperClasses())
      superclasses.push_back(SuperPair.first->getNameInitAsString());
    obj["!superclasses"] = std::move(superclasses);

    obj["!name"] = Name;
    obj["!anonymous"] = Def.isAnonymous();

    json::Array locs;
    for (const SMLoc Loc : Def.getLoc())
      locs.push_back(SrcMgr.getFormattedLocationNoOffset(Loc));
    obj["!locs"] = std::move(locs);

    root[Name] = std::move(obj);

    // Add this def to the instance list for each of its superclasses.
    for (const auto &SuperPair : Def.getSuperClasses()) {
      auto SuperName = SuperPair.first->getNameInitAsString();
      instance_lists[SuperName].push_back(Name);
    }
  }

  // Make a JSON object from the std::map of instance lists.
  json::Object instanceof;
  for (auto kv: instance_lists)
    instanceof[kv.first] = std::move(kv.second);
  root["!instanceof"] = std::move(instanceof);

  // Done. Write the output.
  OS << json::Value(std::move(root)) << "\n";
}

namespace llvm {

void EmitJSON(RecordKeeper &RK, raw_ostream &OS) { JSONEmitter(RK).run(OS); }
} // end namespace llvm
