//===- LLDBPropertyDefEmitter.cpp -----------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// These tablegen backends emits LLDB's PropertyDefinition values.
//
//===----------------------------------------------------------------------===//

#include "LLDBTableGenBackends.h"
#include "LLDBTableGenUtils.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringMatcher.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <optional>
#include <vector>

using namespace llvm;
using namespace lldb_private;

static void emitPropertyEnum(const Record *Property, raw_ostream &OS) {
  OS << "eProperty";
  OS << Property->getName();
  OS << ",\n";
}

static void emitProperty(const Record *Property, raw_ostream &OS) {
  OS << "  {";

  // Emit the property name.
  OS << "\"" << Property->getValueAsString("Name") << "\"";
  OS << ", ";

  // Emit the property type.
  llvm::StringRef type = Property->getValueAsString("Type");
  OS << "OptionValue::eType";
  OS << type;
  OS << ", ";

  // Emit the property's global value.
  OS << (Property->getValue("Global") ? "true" : "false");
  OS << ", ";

  bool hasDefaultUnsignedValue = Property->getValue("HasDefaultUnsignedValue");
  bool hasDefaultEnumValue = Property->getValue("HasDefaultEnumValue");
  bool hasDefaultStringValue = Property->getValue("HasDefaultStringValue");
  bool hasElementType = Property->getValue("HasElementType");

  // Guarantee that every property has a default value.
  assert((hasDefaultUnsignedValue || hasDefaultEnumValue ||
          hasDefaultStringValue || hasElementType) &&
         "Property must have a default value or an element type");

  // Guarantee that no property has both a default unsigned value and a default
  // enum value, since they're bothed stored in the same field.
  assert(!(hasDefaultUnsignedValue && hasDefaultEnumValue) &&
         "Property cannot have both a unsigned and enum default value.");

  // Guarantee that every boolean property has a boolean default value.
  assert(!(Property->getValueAsString("Type") == "Boolean" &&
           !Property->getValue("HasDefaultBooleanValue")) &&
         "Boolean property must have a boolean default value.");

  // Guarantee that every string property has a string default value.
  assert(!(Property->getValueAsString("Type") == "String" &&
           !hasDefaultStringValue) &&
         "String property must have a string default value.");

  // Guarantee that every enum property has an enum default value.
  assert(
      !(Property->getValueAsString("Type") == "Enum" && !hasDefaultEnumValue) &&
      "Enum property must have a enum default value.");

  // Guarantee that only arrays and dictionaries have an element type;
  assert(((type != "Array" && type != "Dictionary") || hasElementType) &&
         "Only dictionaries and arrays can have an element type.");

  // Emit the default uint value.
  if (hasDefaultUnsignedValue) {
    OS << std::to_string(Property->getValueAsInt("DefaultUnsignedValue"));
  } else if (hasDefaultEnumValue) {
    OS << Property->getValueAsString("DefaultEnumValue");
  } else if (hasElementType) {
    OS << "OptionValue::eType";
    OS << Property->getValueAsString("ElementType");
  } else {
    OS << "0";
  }
  OS << ", ";

  // Emit the default string value.
  if (hasDefaultStringValue) {
    if (auto D = Property->getValue("DefaultStringValue")) {
      OS << "\"";
      OS << D->getValue()->getAsUnquotedString();
      OS << "\"";
    } else {
      OS << "\"\"";
    }
  } else {
    OS << "nullptr";
  }
  OS << ", ";

  // Emit the enum values value.
  if (Property->getValue("EnumValues"))
    OS << Property->getValueAsString("EnumValues");
  else
    OS << "{}";
  OS << ", ";

  // Emit the property description.
  if (auto D = Property->getValue("Description")) {
    OS << "\"";
    OS << D->getValue()->getAsUnquotedString();
    OS << "\"";
  } else {
    OS << "\"\"";
  }

  OS << "},\n";
}

static std::optional<StringRef>
getPropertyPath(const std::vector<const Record *> &PropertyRecords) {
  std::optional<StringRef> Path;
  for (const Record *R : PropertyRecords) {
    StringRef P = R->getValueAsString("Path");
    if (!Path)
      Path.emplace(P);
    assert(*Path == P &&
           "All records with one definition should have the same path");
  }
  return Path;
}

/// Emits all property initializers to the raw_ostream.
static void emityProperties(std::string PropertyName,
                            const std::vector<const Record *> &PropertyRecords,
                            raw_ostream &OS) {
  // Generate the macro that the user needs to define before including the
  // *.inc file.
  std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
  llvm::replace(NeededMacro, ' ', '_');

  std::optional<StringRef> Path = getPropertyPath(PropertyRecords);

  // All options are in one file, so we need put them behind macros and ask the
  // user to define the macro for the options that are needed.
  OS << "// Property definitions for " << PropertyName << "\n";
  OS << "#ifdef " << NeededMacro << "\n";
  OS << "static constexpr PropertyDefinition g_" << PropertyName
     << "_properties[] = {\n";
  for (const Record *R : PropertyRecords)
    emitProperty(R, OS);
  OS << "};\n";

  OS << "static constexpr PropertyCollectionDefinition g_" << PropertyName
     << "_properties_def = {\n";
  OS << "/*properties=*/g_" << PropertyName << "_properties,\n";
  if (Path)
    OS << "/*expected_path=*/\"" << *Path << "\",\n";
  OS << "};\n";

  // We undefine the macro for the user like Clang's include files are doing it.
  OS << "#undef " << NeededMacro << "\n";
  OS << "#endif // " << PropertyName << " Property\n\n";
}

/// Emits all property initializers to the raw_ostream.
static void emitPropertyEnum(std::string PropertyName,
                             ArrayRef<const Record *> PropertyRecords,
                             raw_ostream &OS) {
  // Generate the macro that the user needs to define before including the
  // *.inc file.
  std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
  llvm::replace(NeededMacro, ' ', '_');

  // All options are in one file, so we need put them behind macros and ask the
  // user to define the macro for the options that are needed.
  OS << "// Property enum cases for " << PropertyName << "\n";
  OS << "#ifdef " << NeededMacro << "\n";
  for (const Record *R : PropertyRecords)
    emitPropertyEnum(R, OS);
  // We undefine the macro for the user like Clang's include files are doing it.
  OS << "#undef " << NeededMacro << "\n";
  OS << "#endif // " << PropertyName << " Property\n\n";
}

void lldb_private::EmitPropertyDefs(const RecordKeeper &Records,
                                    raw_ostream &OS) {
  emitSourceFileHeader("Property definitions for LLDB.", OS, Records);

  ArrayRef<const Record *> Properties =
      Records.getAllDerivedDefinitions("Property");
  for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
    emityProperties(PropertyRecordPair.first, PropertyRecordPair.second, OS);
  }
}

void lldb_private::EmitPropertyEnumDefs(const RecordKeeper &Records,
                                        raw_ostream &OS) {
  emitSourceFileHeader("Property definition enum for LLDB.", OS, Records);

  ArrayRef<const Record *> Properties =
      Records.getAllDerivedDefinitions("Property");
  for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
    emitPropertyEnum(PropertyRecordPair.first, PropertyRecordPair.second, OS);
  }
}
