//===- 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/ADT/ArrayRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/JSON.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();

    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
