//===--- LogDiagnosticPrinter.cpp - Log Diagnostic Printer ----------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/LogDiagnosticPrinter.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/PlistSupport.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
using namespace markup;

LogDiagnosticPrinter::LogDiagnosticPrinter(
    raw_ostream &os, DiagnosticOptions *diags,
    std::unique_ptr<raw_ostream> StreamOwner)
    : OS(os), StreamOwner(std::move(StreamOwner)), LangOpts(nullptr),
      DiagOpts(diags) {}

static StringRef getLevelName(DiagnosticsEngine::Level Level) {
  switch (Level) {
  case DiagnosticsEngine::Ignored: return "ignored";
  case DiagnosticsEngine::Remark:  return "remark";
  case DiagnosticsEngine::Note:    return "note";
  case DiagnosticsEngine::Warning: return "warning";
  case DiagnosticsEngine::Error:   return "error";
  case DiagnosticsEngine::Fatal:   return "fatal error";
  }
  llvm_unreachable("Invalid DiagnosticsEngine level!");
}

void
LogDiagnosticPrinter::EmitDiagEntry(llvm::raw_ostream &OS,
                                    const LogDiagnosticPrinter::DiagEntry &DE) {
  OS << "    <dict>\n";
  OS << "      <key>level</key>\n"
     << "      ";
  EmitString(OS, getLevelName(DE.DiagnosticLevel)) << '\n';
  if (!DE.Filename.empty()) {
    OS << "      <key>filename</key>\n"
       << "      ";
    EmitString(OS, DE.Filename) << '\n';
  }
  if (DE.Line != 0) {
    OS << "      <key>line</key>\n"
       << "      ";
    EmitInteger(OS, DE.Line) << '\n';
  }
  if (DE.Column != 0) {
    OS << "      <key>column</key>\n"
       << "      ";
    EmitInteger(OS, DE.Column) << '\n';
  }
  if (!DE.Message.empty()) {
    OS << "      <key>message</key>\n"
       << "      ";
    EmitString(OS, DE.Message) << '\n';
  }
  OS << "      <key>ID</key>\n"
     << "      ";
  EmitInteger(OS, DE.DiagnosticID) << '\n';
  if (!DE.WarningOption.empty()) {
    OS << "      <key>WarningOption</key>\n"
       << "      ";
    EmitString(OS, DE.WarningOption) << '\n';
  }
  OS << "    </dict>\n";
}

void LogDiagnosticPrinter::EndSourceFile() {
  // We emit all the diagnostics in EndSourceFile. However, we don't emit any
  // entry if no diagnostics were present.
  //
  // Note that DiagnosticConsumer has no "end-of-compilation" callback, so we
  // will miss any diagnostics which are emitted after and outside the
  // translation unit processing.
  if (Entries.empty())
    return;

  // Write to a temporary string to ensure atomic write of diagnostic object.
  SmallString<512> Msg;
  llvm::raw_svector_ostream OS(Msg);

  OS << "<dict>\n";
  if (!MainFilename.empty()) {
    OS << "  <key>main-file</key>\n"
       << "  ";
    EmitString(OS, MainFilename) << '\n';
  }
  if (!DwarfDebugFlags.empty()) {
    OS << "  <key>dwarf-debug-flags</key>\n"
       << "  ";
    EmitString(OS, DwarfDebugFlags) << '\n';
  }
  OS << "  <key>diagnostics</key>\n";
  OS << "  <array>\n";
  for (auto &DE : Entries)
    EmitDiagEntry(OS, DE);
  OS << "  </array>\n";
  OS << "</dict>\n";

  this->OS << OS.str();
}

void LogDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
                                            const Diagnostic &Info) {
  // Default implementation (Warnings/errors count).
  DiagnosticConsumer::HandleDiagnostic(Level, Info);

  // Initialize the main file name, if we haven't already fetched it.
  if (MainFilename.empty() && Info.hasSourceManager()) {
    const SourceManager &SM = Info.getSourceManager();
    FileID FID = SM.getMainFileID();
    if (FID.isValid()) {
      const FileEntry *FE = SM.getFileEntryForID(FID);
      if (FE && FE->isValid())
        MainFilename = FE->getName();
    }
  }

  // Create the diag entry.
  DiagEntry DE;
  DE.DiagnosticID = Info.getID();
  DE.DiagnosticLevel = Level;

  DE.WarningOption = DiagnosticIDs::getWarningOptionForDiag(DE.DiagnosticID);

  // Format the message.
  SmallString<100> MessageStr;
  Info.FormatDiagnostic(MessageStr);
  DE.Message = MessageStr.str();

  // Set the location information.
  DE.Filename = "";
  DE.Line = DE.Column = 0;
  if (Info.getLocation().isValid() && Info.hasSourceManager()) {
    const SourceManager &SM = Info.getSourceManager();
    PresumedLoc PLoc = SM.getPresumedLoc(Info.getLocation());

    if (PLoc.isInvalid()) {
      // At least print the file name if available:
      FileID FID = SM.getFileID(Info.getLocation());
      if (FID.isValid()) {
        const FileEntry *FE = SM.getFileEntryForID(FID);
        if (FE && FE->isValid())
          DE.Filename = FE->getName();
      }
    } else {
      DE.Filename = PLoc.getFilename();
      DE.Line = PLoc.getLine();
      DE.Column = PLoc.getColumn();
    }
  }

  // Record the diagnostic entry.
  Entries.push_back(DE);
}

