//===--- LogDiagnosticPrinter.cpp - Log Diagnostic Printer ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/LogDiagnosticPrinter.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.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;

LogDiagnosticPrinter::LogDiagnosticPrinter(raw_ostream &os,
                                           DiagnosticOptions *diags,
                                           bool _OwnsOutputStream)
  : OS(os), LangOpts(0), DiagOpts(diags),
    OwnsOutputStream(_OwnsOutputStream) {
}

LogDiagnosticPrinter::~LogDiagnosticPrinter() {
  if (OwnsOutputStream)
    delete &OS;
}

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!");
}

// Escape XML characters inside the raw string.
static void emitString(llvm::raw_svector_ostream &OS, const StringRef Raw) {
  for (StringRef::iterator I = Raw.begin(), E = Raw.end(); I != E; ++I) {
    char c = *I;
    switch (c) {
    default:   OS << c; break;
    case '&':  OS << "&amp;"; break;
    case '<':  OS << "&lt;"; break;
    case '>':  OS << "&gt;"; break;
    case '\'': OS << "&apos;"; break;
    case '\"': OS << "&quot;"; break;
    }
  }
}

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"
       << "  <string>";
    emitString(OS, MainFilename);
    OS << "</string>\n";
  }
  if (!DwarfDebugFlags.empty()) {
    OS << "  <key>dwarf-debug-flags</key>\n"
       << "  <string>";
    emitString(OS, DwarfDebugFlags);
    OS << "</string>\n";
  }
  OS << "  <key>diagnostics</key>\n";
  OS << "  <array>\n";
  for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
    DiagEntry &DE = Entries[i];

    OS << "    <dict>\n";
    OS << "      <key>level</key>\n"
       << "      <string>";
    emitString(OS, getLevelName(DE.DiagnosticLevel));
    OS << "</string>\n";
    if (!DE.Filename.empty()) {
      OS << "      <key>filename</key>\n"
         << "      <string>";
      emitString(OS, DE.Filename);
      OS << "</string>\n";
    }
    if (DE.Line != 0) {
      OS << "      <key>line</key>\n"
         << "      <integer>" << DE.Line << "</integer>\n";
    }
    if (DE.Column != 0) {
      OS << "      <key>column</key>\n"
         << "      <integer>" << DE.Column << "</integer>\n";
    }
    if (!DE.Message.empty()) {
      OS << "      <key>message</key>\n"
         << "      <string>";
      emitString(OS, DE.Message);
      OS << "</string>\n";
    }
    OS << "    </dict>\n";
  }
  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.isInvalid()) {
      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;

  // 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.isInvalid()) {
        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);
}

