//===- lib/DebugInfo/Symbolize/DIPrinter.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
//
//===----------------------------------------------------------------------===//
//
// This file defines the DIPrinter class, which is responsible for printing
// structures defined in DebugInfo/DIContext.h
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/Symbolize/DIPrinter.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>

namespace llvm {
namespace symbolize {

class SourceCode {
  std::unique_ptr<MemoryBuffer> MemBuf;

  Optional<StringRef> load(StringRef FileName,
                           const Optional<StringRef> &EmbeddedSource) {
    if (Lines <= 0)
      return None;

    if (EmbeddedSource)
      return EmbeddedSource;
    else {
      ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
          MemoryBuffer::getFile(FileName);
      if (!BufOrErr)
        return None;
      MemBuf = std::move(*BufOrErr);
      return MemBuf->getBuffer();
    }
  }

  Optional<StringRef> pruneSource(const Optional<StringRef> &Source) {
    if (!Source)
      return None;
    size_t FirstLinePos = StringRef::npos, Pos = 0;
    for (int64_t L = 1; L <= LastLine; ++L, ++Pos) {
      if (L == FirstLine)
        FirstLinePos = Pos;
      Pos = Source->find('\n', Pos);
      if (Pos == StringRef::npos)
        break;
    }
    if (FirstLinePos == StringRef::npos)
      return None;
    return Source->substr(FirstLinePos, (Pos == StringRef::npos)
                                            ? StringRef::npos
                                            : Pos - FirstLinePos);
  }

public:
  const int64_t Line;
  const int Lines;
  const int64_t FirstLine;
  const int64_t LastLine;
  const Optional<StringRef> PrunedSource;

  SourceCode(
      StringRef FileName, int64_t Line, int Lines,
      const Optional<StringRef> &EmbeddedSource = Optional<StringRef>(None))
      : Line(Line), Lines(Lines),
        FirstLine(std::max(static_cast<int64_t>(1), Line - Lines / 2)),
        LastLine(FirstLine + Lines - 1),
        PrunedSource(pruneSource(load(FileName, EmbeddedSource))) {}

  void format(raw_ostream &OS) {
    if (!PrunedSource)
      return;
    size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
    int64_t L = FirstLine;
    for (size_t Pos = 0; Pos < PrunedSource->size(); ++L) {
      size_t PosEnd = PrunedSource->find('\n', Pos);
      StringRef String = PrunedSource->substr(
          Pos, (PosEnd == StringRef::npos) ? StringRef::npos : (PosEnd - Pos));
      if (String.endswith("\r"))
        String = String.drop_back(1);
      OS << format_decimal(L, MaxLineNumberWidth);
      if (L == Line)
        OS << " >: ";
      else
        OS << "  : ";
      OS << String << '\n';
      if (PosEnd == StringRef::npos)
        break;
      Pos = PosEnd + 1;
    }
  }
};

void PlainPrinterBase::printHeader(uint64_t Address) {
  if (Config.PrintAddress) {
    OS << "0x";
    OS.write_hex(Address);
    StringRef Delimiter = Config.Pretty ? ": " : "\n";
    OS << Delimiter;
  }
}

// Prints source code around in the FileName the Line.
void PlainPrinterBase::printContext(SourceCode SourceCode) {
  SourceCode.format(OS);
}

void PlainPrinterBase::printFunctionName(StringRef FunctionName, bool Inlined) {
  if (Config.PrintFunctions) {
    if (FunctionName == DILineInfo::BadString)
      FunctionName = DILineInfo::Addr2LineBadString;
    StringRef Delimiter = Config.Pretty ? " at " : "\n";
    StringRef Prefix = (Config.Pretty && Inlined) ? " (inlined by) " : "";
    OS << Prefix << FunctionName << Delimiter;
  }
}

void LLVMPrinter::printSimpleLocation(StringRef Filename,
                                      const DILineInfo &Info) {
  OS << Filename << ':' << Info.Line << ':' << Info.Column << '\n';
  printContext(
      SourceCode(Filename, Info.Line, Config.SourceContextLines, Info.Source));
}

void GNUPrinter::printSimpleLocation(StringRef Filename,
                                     const DILineInfo &Info) {
  OS << Filename << ':' << Info.Line;
  if (Info.Discriminator)
    OS << " (discriminator " << Info.Discriminator << ')';
  OS << '\n';
  printContext(
      SourceCode(Filename, Info.Line, Config.SourceContextLines, Info.Source));
}

void PlainPrinterBase::printVerbose(StringRef Filename,
                                    const DILineInfo &Info) {
  OS << "  Filename: " << Filename << '\n';
  if (Info.StartLine) {
    OS << "  Function start filename: " << Info.StartFileName << '\n';
    OS << "  Function start line: " << Info.StartLine << '\n';
  }
  printStartAddress(Info);
  OS << "  Line: " << Info.Line << '\n';
  OS << "  Column: " << Info.Column << '\n';
  if (Info.Discriminator)
    OS << "  Discriminator: " << Info.Discriminator << '\n';
}

void LLVMPrinter::printStartAddress(const DILineInfo &Info) {
  if (Info.StartAddress) {
    OS << "  Function start address: 0x";
    OS.write_hex(*Info.StartAddress);
    OS << '\n';
  }
}

void LLVMPrinter::printFooter() { OS << '\n'; }

void PlainPrinterBase::print(const DILineInfo &Info, bool Inlined) {
  printFunctionName(Info.FunctionName, Inlined);
  StringRef Filename = Info.FileName;
  if (Filename == DILineInfo::BadString)
    Filename = DILineInfo::Addr2LineBadString;
  if (Config.Verbose)
    printVerbose(Filename, Info);
  else
    printSimpleLocation(Filename, Info);
}

void PlainPrinterBase::print(const Request &Request, const DILineInfo &Info) {
  printHeader(*Request.Address);
  print(Info, false);
  printFooter();
}

void PlainPrinterBase::print(const Request &Request,
                             const DIInliningInfo &Info) {
  printHeader(*Request.Address);
  uint32_t FramesNum = Info.getNumberOfFrames();
  if (FramesNum == 0)
    print(DILineInfo(), false);
  else
    for (uint32_t I = 0; I < FramesNum; ++I)
      print(Info.getFrame(I), I > 0);
  printFooter();
}

void PlainPrinterBase::print(const Request &Request, const DIGlobal &Global) {
  printHeader(*Request.Address);
  StringRef Name = Global.Name;
  if (Name == DILineInfo::BadString)
    Name = DILineInfo::Addr2LineBadString;
  OS << Name << "\n";
  OS << Global.Start << " " << Global.Size << "\n";
  if (Global.DeclFile.empty())
    OS << "??:?\n";
  else
    OS << Global.DeclFile << ":" << Global.DeclLine << "\n";
  printFooter();
}

void PlainPrinterBase::print(const Request &Request,
                             const std::vector<DILocal> &Locals) {
  printHeader(*Request.Address);
  if (Locals.empty())
    OS << DILineInfo::Addr2LineBadString << '\n';
  else
    for (const DILocal &L : Locals) {
      if (L.FunctionName.empty())
        OS << DILineInfo::Addr2LineBadString;
      else
        OS << L.FunctionName;
      OS << '\n';

      if (L.Name.empty())
        OS << DILineInfo::Addr2LineBadString;
      else
        OS << L.Name;
      OS << '\n';

      if (L.DeclFile.empty())
        OS << DILineInfo::Addr2LineBadString;
      else
        OS << L.DeclFile;

      OS << ':' << L.DeclLine << '\n';

      if (L.FrameOffset)
        OS << *L.FrameOffset;
      else
        OS << DILineInfo::Addr2LineBadString;
      OS << ' ';

      if (L.Size)
        OS << *L.Size;
      else
        OS << DILineInfo::Addr2LineBadString;
      OS << ' ';

      if (L.TagOffset)
        OS << *L.TagOffset;
      else
        OS << DILineInfo::Addr2LineBadString;
      OS << '\n';
    }
  printFooter();
}

void PlainPrinterBase::printInvalidCommand(const Request &Request,
                                           StringRef Command) {
  OS << Command << '\n';
}

bool PlainPrinterBase::printError(const Request &Request,
                                  const ErrorInfoBase &ErrorInfo,
                                  StringRef ErrorBanner) {
  ES << ErrorBanner;
  ErrorInfo.log(ES);
  ES << '\n';
  // Print an empty struct too.
  return true;
}

static std::string toHex(uint64_t V) {
  return ("0x" + Twine::utohexstr(V)).str();
}

static json::Object toJSON(const Request &Request, StringRef ErrorMsg = "") {
  json::Object Json({{"ModuleName", Request.ModuleName.str()}});
  if (Request.Address)
    Json["Address"] = toHex(*Request.Address);
  if (!ErrorMsg.empty())
    Json["Error"] = json::Object({{"Message", ErrorMsg.str()}});
  return Json;
}

void JSONPrinter::print(const Request &Request, const DILineInfo &Info) {
  DIInliningInfo InliningInfo;
  InliningInfo.addFrame(Info);
  print(Request, InliningInfo);
}

void JSONPrinter::print(const Request &Request, const DIInliningInfo &Info) {
  json::Array Array;
  for (uint32_t I = 0, N = Info.getNumberOfFrames(); I < N; ++I) {
    const DILineInfo &LineInfo = Info.getFrame(I);
    json::Object Object(
        {{"FunctionName", LineInfo.FunctionName != DILineInfo::BadString
                              ? LineInfo.FunctionName
                              : ""},
         {"StartFileName", LineInfo.StartFileName != DILineInfo::BadString
                               ? LineInfo.StartFileName
                               : ""},
         {"StartLine", LineInfo.StartLine},
         {"StartAddress",
          LineInfo.StartAddress ? toHex(*LineInfo.StartAddress) : ""},
         {"FileName",
          LineInfo.FileName != DILineInfo::BadString ? LineInfo.FileName : ""},
         {"Line", LineInfo.Line},
         {"Column", LineInfo.Column},
         {"Discriminator", LineInfo.Discriminator}});
    SourceCode SourceCode(LineInfo.FileName, LineInfo.Line,
                          Config.SourceContextLines, LineInfo.Source);
    std::string FormattedSource;
    raw_string_ostream Stream(FormattedSource);
    SourceCode.format(Stream);
    if (!FormattedSource.empty())
      Object["Source"] = std::move(FormattedSource);
    Array.push_back(std::move(Object));
  }
  json::Object Json = toJSON(Request);
  Json["Symbol"] = std::move(Array);
  if (ObjectList)
    ObjectList->push_back(std::move(Json));
  else
    printJSON(std::move(Json));
}

void JSONPrinter::print(const Request &Request, const DIGlobal &Global) {
  json::Object Data(
      {{"Name", Global.Name != DILineInfo::BadString ? Global.Name : ""},
       {"Start", toHex(Global.Start)},
       {"Size", toHex(Global.Size)}});
  json::Object Json = toJSON(Request);
  Json["Data"] = std::move(Data);
  if (ObjectList)
    ObjectList->push_back(std::move(Json));
  else
    printJSON(std::move(Json));
}

void JSONPrinter::print(const Request &Request,
                        const std::vector<DILocal> &Locals) {
  json::Array Frame;
  for (const DILocal &Local : Locals) {
    json::Object FrameObject(
        {{"FunctionName", Local.FunctionName},
         {"Name", Local.Name},
         {"DeclFile", Local.DeclFile},
         {"DeclLine", int64_t(Local.DeclLine)},
         {"Size", Local.Size ? toHex(*Local.Size) : ""},
         {"TagOffset", Local.TagOffset ? toHex(*Local.TagOffset) : ""}});
    if (Local.FrameOffset)
      FrameObject["FrameOffset"] = *Local.FrameOffset;
    Frame.push_back(std::move(FrameObject));
  }
  json::Object Json = toJSON(Request);
  Json["Frame"] = std::move(Frame);
  if (ObjectList)
    ObjectList->push_back(std::move(Json));
  else
    printJSON(std::move(Json));
}

void JSONPrinter::printInvalidCommand(const Request &Request,
                                      StringRef Command) {
  printError(Request,
             StringError("unable to parse arguments: " + Command,
                         std::make_error_code(std::errc::invalid_argument)),
             "");
}

bool JSONPrinter::printError(const Request &Request,
                             const ErrorInfoBase &ErrorInfo,
                             StringRef ErrorBanner) {
  json::Object Json = toJSON(Request, ErrorInfo.message());
  if (ObjectList)
    ObjectList->push_back(std::move(Json));
  else
    printJSON(std::move(Json));
  return false;
}

void JSONPrinter::listBegin() {
  assert(!ObjectList);
  ObjectList = std::make_unique<json::Array>();
}

void JSONPrinter::listEnd() {
  assert(ObjectList);
  printJSON(std::move(*ObjectList));
  ObjectList.reset();
}

} // end namespace symbolize
} // end namespace llvm
