//===-- CXLoadedDiagnostic.cpp - Handling of persisent diags ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implements handling of persisent diagnostics.
//
//===----------------------------------------------------------------------===//

#include "CXLoadedDiagnostic.h"
#include "CXString.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
#include "clang/Frontend/SerializedDiagnosticReader.h"
#include "clang/Frontend/SerializedDiagnostics.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/ErrorHandling.h"

using namespace clang;

//===----------------------------------------------------------------------===//
// Extend CXDiagnosticSetImpl which contains strings for diagnostics.
//===----------------------------------------------------------------------===//

typedef llvm::DenseMap<unsigned, const char *> Strings;

namespace {
class CXLoadedDiagnosticSetImpl : public CXDiagnosticSetImpl {
public:
  CXLoadedDiagnosticSetImpl() : CXDiagnosticSetImpl(true), FakeFiles(FO) {}
  ~CXLoadedDiagnosticSetImpl() override {}

  llvm::BumpPtrAllocator Alloc;
  Strings Categories;
  Strings WarningFlags;
  Strings FileNames;
  
  FileSystemOptions FO;
  FileManager FakeFiles;
  llvm::DenseMap<unsigned, const FileEntry *> Files;

  /// Copy the string into our own allocator.
  const char *copyString(StringRef Blob) {
    char *mem = Alloc.Allocate<char>(Blob.size() + 1);
    memcpy(mem, Blob.data(), Blob.size());
    mem[Blob.size()] = '\0';
    return mem;
  }
};
} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Cleanup.
//===----------------------------------------------------------------------===//

CXLoadedDiagnostic::~CXLoadedDiagnostic() {}

//===----------------------------------------------------------------------===//
// Public CXLoadedDiagnostic methods.
//===----------------------------------------------------------------------===//

CXDiagnosticSeverity CXLoadedDiagnostic::getSeverity() const {
  // FIXME: Fail more softly if the diagnostic level is unknown?
  auto severityAsLevel = static_cast<serialized_diags::Level>(severity);
  assert(severity == static_cast<unsigned>(severityAsLevel) &&
         "unknown serialized diagnostic level");

  switch (severityAsLevel) {
#define CASE(X) case serialized_diags::X: return CXDiagnostic_##X;
  CASE(Ignored)
  CASE(Note)
  CASE(Warning)
  CASE(Error)
  CASE(Fatal)
#undef CASE
  // The 'Remark' level isn't represented in the stable API.
  case serialized_diags::Remark: return CXDiagnostic_Warning;
  }
  
  llvm_unreachable("Invalid diagnostic level");
}

static CXSourceLocation makeLocation(const CXLoadedDiagnostic::Location *DLoc) {
  // The lowest bit of ptr_data[0] is always set to 1 to indicate this
  // is a persistent diagnostic.
  uintptr_t V = (uintptr_t) DLoc;
  V |= 0x1;
  CXSourceLocation Loc = { {  (void*) V, nullptr }, 0 };
  return Loc;
}  

CXSourceLocation CXLoadedDiagnostic::getLocation() const {
  // The lowest bit of ptr_data[0] is always set to 1 to indicate this
  // is a persistent diagnostic.
  return makeLocation(&DiagLoc);
}

CXString CXLoadedDiagnostic::getSpelling() const {
  return cxstring::createRef(Spelling);
}

CXString CXLoadedDiagnostic::getDiagnosticOption(CXString *Disable) const {
  if (DiagOption.empty())
    return cxstring::createEmpty();

  // FIXME: possibly refactor with logic in CXStoredDiagnostic.
  if (Disable)
    *Disable = cxstring::createDup((Twine("-Wno-") + DiagOption).str());
  return cxstring::createDup((Twine("-W") + DiagOption).str());
}

unsigned CXLoadedDiagnostic::getCategory() const {
  return category;
}

CXString CXLoadedDiagnostic::getCategoryText() const {
  return cxstring::createDup(CategoryText);
}

unsigned CXLoadedDiagnostic::getNumRanges() const {
  return Ranges.size();
}

CXSourceRange CXLoadedDiagnostic::getRange(unsigned Range) const {
  assert(Range < Ranges.size());
  return Ranges[Range];
}

unsigned CXLoadedDiagnostic::getNumFixIts() const {
  return FixIts.size();
}

CXString CXLoadedDiagnostic::getFixIt(unsigned FixIt,
                                      CXSourceRange *ReplacementRange) const {
  assert(FixIt < FixIts.size());
  if (ReplacementRange)
    *ReplacementRange = FixIts[FixIt].first;
  return cxstring::createRef(FixIts[FixIt].second);
}

void CXLoadedDiagnostic::decodeLocation(CXSourceLocation location,
                                        CXFile *file,
                                        unsigned int *line,
                                        unsigned int *column,
                                        unsigned int *offset) {
  
  
  // CXSourceLocation consists of the following fields:
  //
  //   void *ptr_data[2];
  //   unsigned int_data;
  //
  // The lowest bit of ptr_data[0] is always set to 1 to indicate this
  // is a persistent diagnostic.
  //
  // For now, do the unoptimized approach and store the data in a side
  // data structure.  We can optimize this case later.
  
  uintptr_t V = (uintptr_t) location.ptr_data[0];
  assert((V & 0x1) == 1);
  V &= ~(uintptr_t)1;
  
  const Location &Loc = *((Location*)V);
  
  if (file)
    *file = Loc.file;  
  if (line)
    *line = Loc.line;
  if (column)
    *column = Loc.column;
  if (offset)
    *offset = Loc.offset;
}

//===----------------------------------------------------------------------===//
// Deserialize diagnostics.
//===----------------------------------------------------------------------===//

namespace {
class DiagLoader : serialized_diags::SerializedDiagnosticReader {
  enum CXLoadDiag_Error *error;
  CXString *errorString;
  std::unique_ptr<CXLoadedDiagnosticSetImpl> TopDiags;
  SmallVector<std::unique_ptr<CXLoadedDiagnostic>, 8> CurrentDiags;

  std::error_code reportBad(enum CXLoadDiag_Error code, llvm::StringRef err) {
    if (error)
      *error = code;
    if (errorString)
      *errorString = cxstring::createDup(err);
    return serialized_diags::SDError::HandlerFailed;
  }
  
  std::error_code reportInvalidFile(llvm::StringRef err) {
    return reportBad(CXLoadDiag_InvalidFile, err);
  }

  std::error_code readRange(const serialized_diags::Location &SDStart,
                            const serialized_diags::Location &SDEnd,
                            CXSourceRange &SR);

  std::error_code readLocation(const serialized_diags::Location &SDLoc,
                               CXLoadedDiagnostic::Location &LoadedLoc);

protected:
  std::error_code visitStartOfDiagnostic() override;
  std::error_code visitEndOfDiagnostic() override;

  std::error_code visitCategoryRecord(unsigned ID, StringRef Name) override;

  std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) override;

  std::error_code visitDiagnosticRecord(
      unsigned Severity, const serialized_diags::Location &Location,
      unsigned Category, unsigned Flag, StringRef Message) override;

  std::error_code visitFilenameRecord(unsigned ID, unsigned Size,
                                      unsigned Timestamp,
                                      StringRef Name) override;

  std::error_code visitFixitRecord(const serialized_diags::Location &Start,
                                   const serialized_diags::Location &End,
                                   StringRef CodeToInsert) override;

  std::error_code
  visitSourceRangeRecord(const serialized_diags::Location &Start,
                         const serialized_diags::Location &End) override;

public:
  DiagLoader(enum CXLoadDiag_Error *e, CXString *es)
      : SerializedDiagnosticReader(), error(e), errorString(es) {
    if (error)
      *error = CXLoadDiag_None;
    if (errorString)
      *errorString = cxstring::createEmpty();
  }

  CXDiagnosticSet load(const char *file);
};
} // end anonymous namespace

CXDiagnosticSet DiagLoader::load(const char *file) {
  TopDiags = llvm::make_unique<CXLoadedDiagnosticSetImpl>();

  std::error_code EC = readDiagnostics(file);
  if (EC) {
    switch (EC.value()) {
    case static_cast<int>(serialized_diags::SDError::HandlerFailed):
      // We've already reported the problem.
      break;
    case static_cast<int>(serialized_diags::SDError::CouldNotLoad):
      reportBad(CXLoadDiag_CannotLoad, EC.message());
      break;
    default:
      reportInvalidFile(EC.message());
      break;
    }
    return nullptr;
  }

  return (CXDiagnosticSet)TopDiags.release();
}

std::error_code
DiagLoader::readLocation(const serialized_diags::Location &SDLoc,
                         CXLoadedDiagnostic::Location &LoadedLoc) {
  unsigned FileID = SDLoc.FileID;
  if (FileID == 0)
    LoadedLoc.file = nullptr;
  else {
    LoadedLoc.file = const_cast<FileEntry *>(TopDiags->Files[FileID]);
    if (!LoadedLoc.file)
      return reportInvalidFile("Corrupted file entry in source location");
  }
  LoadedLoc.line = SDLoc.Line;
  LoadedLoc.column = SDLoc.Col;
  LoadedLoc.offset = SDLoc.Offset;
  return std::error_code();
}

std::error_code
DiagLoader::readRange(const serialized_diags::Location &SDStart,
                      const serialized_diags::Location &SDEnd,
                      CXSourceRange &SR) {
  CXLoadedDiagnostic::Location *Start, *End;
  Start = TopDiags->Alloc.Allocate<CXLoadedDiagnostic::Location>();
  End = TopDiags->Alloc.Allocate<CXLoadedDiagnostic::Location>();

  std::error_code EC;
  if ((EC = readLocation(SDStart, *Start)))
    return EC;
  if ((EC = readLocation(SDEnd, *End)))
    return EC;
  
  CXSourceLocation startLoc = makeLocation(Start);
  CXSourceLocation endLoc = makeLocation(End);
  SR = clang_getRange(startLoc, endLoc);
  return std::error_code();
}

std::error_code DiagLoader::visitStartOfDiagnostic() {
  CurrentDiags.push_back(llvm::make_unique<CXLoadedDiagnostic>());
  return std::error_code();
}

std::error_code DiagLoader::visitEndOfDiagnostic() {
  auto D = CurrentDiags.pop_back_val();
  if (CurrentDiags.empty())
    TopDiags->appendDiagnostic(std::move(D));
  else
    CurrentDiags.back()->getChildDiagnostics().appendDiagnostic(std::move(D));
  return std::error_code();
}

std::error_code DiagLoader::visitCategoryRecord(unsigned ID, StringRef Name) {
  // FIXME: Why do we care about long strings?
  if (Name.size() > 65536)
    return reportInvalidFile("Out-of-bounds string in category");
  TopDiags->Categories[ID] = TopDiags->copyString(Name);
  return std::error_code();
}

std::error_code DiagLoader::visitDiagFlagRecord(unsigned ID, StringRef Name) {
  // FIXME: Why do we care about long strings?
  if (Name.size() > 65536)
    return reportInvalidFile("Out-of-bounds string in warning flag");
  TopDiags->WarningFlags[ID] = TopDiags->copyString(Name);
  return std::error_code();
}

std::error_code DiagLoader::visitFilenameRecord(unsigned ID, unsigned Size,
                                                unsigned Timestamp,
                                                StringRef Name) {
  // FIXME: Why do we care about long strings?
  if (Name.size() > 65536)
    return reportInvalidFile("Out-of-bounds string in filename");
  TopDiags->FileNames[ID] = TopDiags->copyString(Name);
  TopDiags->Files[ID] =
      TopDiags->FakeFiles.getVirtualFile(Name, Size, Timestamp);
  return std::error_code();
}

std::error_code
DiagLoader::visitSourceRangeRecord(const serialized_diags::Location &Start,
                                   const serialized_diags::Location &End) {
  CXSourceRange SR;
  if (std::error_code EC = readRange(Start, End, SR))
    return EC;
  CurrentDiags.back()->Ranges.push_back(SR);
  return std::error_code();
}

std::error_code
DiagLoader::visitFixitRecord(const serialized_diags::Location &Start,
                             const serialized_diags::Location &End,
                             StringRef CodeToInsert) {
  CXSourceRange SR;
  if (std::error_code EC = readRange(Start, End, SR))
    return EC;
  // FIXME: Why do we care about long strings?
  if (CodeToInsert.size() > 65536)
    return reportInvalidFile("Out-of-bounds string in FIXIT");
  CurrentDiags.back()->FixIts.push_back(
      std::make_pair(SR, TopDiags->copyString(CodeToInsert)));
  return std::error_code();
}

std::error_code DiagLoader::visitDiagnosticRecord(
    unsigned Severity, const serialized_diags::Location &Location,
    unsigned Category, unsigned Flag, StringRef Message) {
  CXLoadedDiagnostic &D = *CurrentDiags.back();
  D.severity = Severity;
  if (std::error_code EC = readLocation(Location, D.DiagLoc))
    return EC;
  D.category = Category;
  D.DiagOption = Flag ? TopDiags->WarningFlags[Flag] : "";
  D.CategoryText = Category ? TopDiags->Categories[Category] : "";
  D.Spelling = TopDiags->copyString(Message);
  return std::error_code();
}

CXDiagnosticSet clang_loadDiagnostics(const char *file,
                                      enum CXLoadDiag_Error *error,
                                      CXString *errorString) {
  DiagLoader L(error, errorString);
  return L.load(file);
}
