/*===-- 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/Frontend/SerializedDiagnosticPrinter.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/Optional.h"
#include "clang/Basic/LLVM.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/MemoryBuffer.h"
#include <assert.h>

using namespace clang;
using namespace clang::cxstring;

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

typedef llvm::DenseMap<unsigned, llvm::StringRef> Strings;

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

  llvm::StringRef makeString(const char *blob, unsigned blobLen);
  
  llvm::BumpPtrAllocator Alloc;
  Strings Categories;
  Strings WarningFlags;
  Strings FileNames;
  
  FileSystemOptions FO;
  FileManager FakeFiles;
  llvm::DenseMap<unsigned, const FileEntry *> Files;
};
}

llvm::StringRef CXLoadedDiagnosticSetImpl::makeString(const char *blob,
                                                      unsigned bloblen) {
  char *mem = Alloc.Allocate<char>(bloblen + 1);
  memcpy(mem, blob, bloblen);
  // Add a null terminator for those clients accessing the buffer
  // like a c-string.
  mem[bloblen] = '\0';
  return llvm::StringRef(mem, bloblen);
}

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

CXLoadedDiagnostic::~CXLoadedDiagnostic() {}

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

CXDiagnosticSeverity CXLoadedDiagnostic::getSeverity() const {
  // FIXME: possibly refactor with logic in CXStoredDiagnostic.
  switch (severity) {
    case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored;
    case DiagnosticsEngine::Note:    return CXDiagnostic_Note;
    case DiagnosticsEngine::Warning: return CXDiagnostic_Warning;
    case DiagnosticsEngine::Error:   return CXDiagnostic_Error;
    case DiagnosticsEngine::Fatal:   return CXDiagnostic_Fatal;
  }
  
  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, 0 }, 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::createCXString(Spelling, false);
}

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

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

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

CXString CXLoadedDiagnostic::getCategoryText() const {
  return cxstring::createCXString(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 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.
//===----------------------------------------------------------------------===//

enum { MaxSupportedVersion = 1 };
typedef SmallVector<uint64_t, 64> RecordData;
enum LoadResult { Failure = 1, Success = 0 };
enum StreamResult { Read_EndOfStream,
                    Read_BlockBegin,
                    Read_Failure,
                    Read_Record,
                    Read_BlockEnd };

namespace {
class DiagLoader {
  enum CXLoadDiag_Error *error;
  CXString *errorString;
  
  void reportBad(enum CXLoadDiag_Error code, llvm::StringRef err) {
    if (error)
      *error = code;
    if (errorString)
      *errorString = createCXString(err);
  }
  
  void reportInvalidFile(llvm::StringRef err) {
    return reportBad(CXLoadDiag_InvalidFile, err);
  }

  LoadResult readMetaBlock(llvm::BitstreamCursor &Stream);
  
  LoadResult readDiagnosticBlock(llvm::BitstreamCursor &Stream,
                                 CXDiagnosticSetImpl &Diags,
                                 CXLoadedDiagnosticSetImpl &TopDiags);

  StreamResult readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
                                       llvm::StringRef errorContext,
                                       unsigned &BlockOrRecordID,
                                       const bool atTopLevel = false);
  
  
  LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
                        Strings &strings, llvm::StringRef errorContext,
                        RecordData &Record,
                        const char *BlobStart,
                        unsigned BlobLen,
                        bool allowEmptyString = false);

  LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
                        llvm::StringRef &RetStr,
                        llvm::StringRef errorContext,
                        RecordData &Record,
                        const char *BlobStart,
                        unsigned BlobLen,
                        bool allowEmptyString = false);

  LoadResult readRange(CXLoadedDiagnosticSetImpl &TopDiags,
                       RecordData &Record, unsigned RecStartIdx,
                       CXSourceRange &SR);
  
  LoadResult readLocation(CXLoadedDiagnosticSetImpl &TopDiags,
                          RecordData &Record, unsigned &offset,
                          CXLoadedDiagnostic::Location &Loc);
                       
public:
  DiagLoader(enum CXLoadDiag_Error *e, CXString *es)
    : error(e), errorString(es) {
      if (error)
        *error = CXLoadDiag_None;
      if (errorString)
        *errorString = createCXString("");
    }

  CXDiagnosticSet load(const char *file);
};
}

CXDiagnosticSet DiagLoader::load(const char *file) {
  // Open the diagnostics file.
  std::string ErrStr;
  FileSystemOptions FO;
  FileManager FileMgr(FO);

  OwningPtr<llvm::MemoryBuffer> Buffer;
  Buffer.reset(FileMgr.getBufferForFile(file));

  if (!Buffer) {
    reportBad(CXLoadDiag_CannotLoad, ErrStr);
    return 0;
  }

  llvm::BitstreamReader StreamFile;
  StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
                  (const unsigned char *)Buffer->getBufferEnd());

  llvm::BitstreamCursor Stream;
  Stream.init(StreamFile);

  // Sniff for the signature.
  if (Stream.Read(8) != 'D' ||
      Stream.Read(8) != 'I' ||
      Stream.Read(8) != 'A' ||
      Stream.Read(8) != 'G') {
    reportBad(CXLoadDiag_InvalidFile,
              "Bad header in diagnostics file");
    return 0;
  }

  OwningPtr<CXLoadedDiagnosticSetImpl>
    Diags(new CXLoadedDiagnosticSetImpl());

  while (true) {
    unsigned BlockID = 0;
    StreamResult Res = readToNextRecordOrBlock(Stream, "Top-level", 
                                               BlockID, true);
    switch (Res) {
      case Read_EndOfStream:
        return (CXDiagnosticSet) Diags.take();
      case Read_Failure:
        return 0;
      case Read_Record:
        llvm_unreachable("Top-level does not have records");
      case Read_BlockEnd:
        continue;
      case Read_BlockBegin:
        break;
    }
    
    switch (BlockID) {
      case serialized_diags::BLOCK_META:
        if (readMetaBlock(Stream))
          return 0;
        break;
      case serialized_diags::BLOCK_DIAG:
        if (readDiagnosticBlock(Stream, *Diags.get(), *Diags.get()))
          return 0;
        break;
      default:
        if (!Stream.SkipBlock()) {
          reportInvalidFile("Malformed block at top-level of diagnostics file");
          return 0;
        }
        break;
    }
  }
}

StreamResult DiagLoader::readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
                                                 llvm::StringRef errorContext,
                                                 unsigned &blockOrRecordID,
                                                 const bool atTopLevel) {
  
  blockOrRecordID = 0;

  while (!Stream.AtEndOfStream()) {
    unsigned Code = Stream.ReadCode();

    // Handle the top-level specially.
    if (atTopLevel) {
      if (Code == llvm::bitc::ENTER_SUBBLOCK) {
        unsigned BlockID = Stream.ReadSubBlockID();
        if (BlockID == llvm::bitc::BLOCKINFO_BLOCK_ID) {
          if (Stream.ReadBlockInfoBlock()) {
            reportInvalidFile("Malformed BlockInfoBlock in diagnostics file");
            return Read_Failure;
          }
          continue;
        }
        blockOrRecordID = BlockID;
        return Read_BlockBegin;
      }
      reportInvalidFile("Only blocks can appear at the top of a "
                        "diagnostic file");
      return Read_Failure;
    }
    
    switch ((llvm::bitc::FixedAbbrevIDs)Code) {
      case llvm::bitc::ENTER_SUBBLOCK:
        blockOrRecordID = Stream.ReadSubBlockID();
        return Read_BlockBegin;
      
      case llvm::bitc::END_BLOCK:
        if (Stream.ReadBlockEnd()) {
          reportInvalidFile("Cannot read end of block");
          return Read_Failure;
        }
        return Read_BlockEnd;
        
      case llvm::bitc::DEFINE_ABBREV:
        Stream.ReadAbbrevRecord();
        continue;
        
      case llvm::bitc::UNABBREV_RECORD:
        reportInvalidFile("Diagnostics file should have no unabbreviated "
                          "records");
        return Read_Failure;
      
      default:
        // We found a record.
        blockOrRecordID = Code;
        return Read_Record;
    }
  }
  
  if (atTopLevel)
    return Read_EndOfStream;
  
  reportInvalidFile(Twine("Premature end of diagnostics file within ").str() + 
                    errorContext.str());
  return Read_Failure;
}

LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) {
  if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_META)) {
    reportInvalidFile("Malformed metadata block");
    return Failure;
  }

  bool versionChecked = false;
  
  while (true) {
    unsigned blockOrCode = 0;
    StreamResult Res = readToNextRecordOrBlock(Stream, "Metadata Block",
                                               blockOrCode);
    
    switch(Res) {
      case Read_EndOfStream:
        llvm_unreachable("EndOfStream handled by readToNextRecordOrBlock");
      case Read_Failure:
        return Failure;
      case Read_Record:
        break;
      case Read_BlockBegin:
        if (Stream.SkipBlock()) {
          reportInvalidFile("Malformed metadata block");
          return Failure;
        }
      case Read_BlockEnd:
        if (!versionChecked) {
          reportInvalidFile("Diagnostics file does not contain version"
                            " information");
          return Failure;
        }
        return Success;
    }
    
    RecordData Record;
    const char *Blob;
    unsigned BlobLen;
    unsigned recordID = Stream.ReadRecord(blockOrCode, Record, &Blob, &BlobLen);
    
    if (recordID == serialized_diags::RECORD_VERSION) {
      if (Record.size() < 1) {
        reportInvalidFile("malformed VERSION identifier in diagnostics file");
        return Failure;
      }
      if (Record[0] > MaxSupportedVersion) {
        reportInvalidFile("diagnosics file is a newer version than the one "
                          "supported");
        return Failure;
      }
      versionChecked = true;
    }
  }
}

LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
                                  llvm::StringRef &RetStr,
                                  llvm::StringRef errorContext,
                                  RecordData &Record,
                                  const char *BlobStart,
                                  unsigned BlobLen,
                                  bool allowEmptyString) {
  
  // Basic buffer overflow check.
  if (BlobLen > 65536) {
    reportInvalidFile(std::string("Out-of-bounds string in ") +
                      std::string(errorContext));
    return Failure;
  }

  if (allowEmptyString && Record.size() >= 1 && BlobLen == 0) {
    RetStr = "";
    return Success;
  }
  
  if (Record.size() < 1 || BlobLen == 0) {
    reportInvalidFile(std::string("Corrupted ") + std::string(errorContext)
                      + std::string(" entry"));
    return Failure;
  }
  
  RetStr = TopDiags.makeString(BlobStart, BlobLen);
  return Success;
}

LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
                                  Strings &strings,
                                  llvm::StringRef errorContext,
                                  RecordData &Record,
                                  const char *BlobStart,
                                  unsigned BlobLen,
                                  bool allowEmptyString) {
  llvm::StringRef RetStr;
  if (readString(TopDiags, RetStr, errorContext, Record, BlobStart, BlobLen,
                 allowEmptyString))
    return Failure;
  strings[Record[0]] = RetStr;
  return Success;
}

LoadResult DiagLoader::readLocation(CXLoadedDiagnosticSetImpl &TopDiags,
                                    RecordData &Record, unsigned &offset,
                                    CXLoadedDiagnostic::Location &Loc) {
  if (Record.size() < offset + 3) {
    reportInvalidFile("Corrupted source location");
    return Failure;
  }
  
  unsigned fileID = Record[offset++];
  if (fileID == 0) {
    // Sentinel value.
    Loc.file = 0;
    Loc.line = 0;
    Loc.column = 0;
    Loc.offset = 0;
    return Success;
  }

  const FileEntry *FE = TopDiags.Files[fileID];
  if (!FE) {
    reportInvalidFile("Corrupted file entry in source location");
    return Failure;
  }
  Loc.file = const_cast<FileEntry *>(FE);
  Loc.line = Record[offset++];
  Loc.column = Record[offset++];
  Loc.offset = Record[offset++];
  return Success;
}

LoadResult DiagLoader::readRange(CXLoadedDiagnosticSetImpl &TopDiags,
                                 RecordData &Record,
                                 unsigned int RecStartIdx,
                                 CXSourceRange &SR) {
  CXLoadedDiagnostic::Location *Start, *End;
  Start = TopDiags.Alloc.Allocate<CXLoadedDiagnostic::Location>();
  End = TopDiags.Alloc.Allocate<CXLoadedDiagnostic::Location>();
  
  if (readLocation(TopDiags, Record, RecStartIdx, *Start))
    return Failure;
  if (readLocation(TopDiags, Record, RecStartIdx, *End))
    return Failure;
  
  CXSourceLocation startLoc = makeLocation(Start);
  CXSourceLocation endLoc = makeLocation(End);
  SR = clang_getRange(startLoc, endLoc);
  return Success;  
}

LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
                                           CXDiagnosticSetImpl &Diags,
                                           CXLoadedDiagnosticSetImpl &TopDiags){

  if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_DIAG)) {
    reportInvalidFile("malformed diagnostic block");
    return Failure;
  }
  
  OwningPtr<CXLoadedDiagnostic> D(new CXLoadedDiagnostic());
  RecordData Record;
  
  while (true) {
    unsigned blockOrCode = 0;
    StreamResult Res = readToNextRecordOrBlock(Stream, "Diagnostic Block",
                                               blockOrCode);
    switch (Res) {
      case Read_EndOfStream:
        llvm_unreachable("EndOfStream handled in readToNextRecordOrBlock");
      case Read_Failure:
        return Failure;
      case Read_BlockBegin: {
        // The only blocks we care about are subdiagnostics.
        if (blockOrCode != serialized_diags::BLOCK_DIAG) {
          if (!Stream.SkipBlock()) {
            reportInvalidFile("Invalid subblock in Diagnostics block");
            return Failure;
          }
        } else if (readDiagnosticBlock(Stream, D->getChildDiagnostics(),
                                       TopDiags)) {
          return Failure;
        }

        continue;
      }
      case Read_BlockEnd:
        Diags.appendDiagnostic(D.take());        
        return Success;
      case Read_Record:
        break;
    }
    
    // Read the record.
    Record.clear();
    const char *BlobStart = 0;
    unsigned BlobLen = 0;
    unsigned recID = Stream.ReadRecord(blockOrCode, Record,
                                       BlobStart, BlobLen);
    
    if (recID < serialized_diags::RECORD_FIRST ||
        recID > serialized_diags::RECORD_LAST)
      continue;
    
    switch ((serialized_diags::RecordIDs)recID) {  
      case serialized_diags::RECORD_VERSION:
        continue;
      case serialized_diags::RECORD_CATEGORY:
        if (readString(TopDiags, TopDiags.Categories, "category", Record,
                       BlobStart, BlobLen,
                       /* allowEmptyString */ true))
          return Failure;
        continue;
      
      case serialized_diags::RECORD_DIAG_FLAG:
        if (readString(TopDiags, TopDiags.WarningFlags, "warning flag", Record,
                       BlobStart, BlobLen))
          return Failure;
        continue;
        
      case serialized_diags::RECORD_FILENAME: {
        if (readString(TopDiags, TopDiags.FileNames, "filename", Record,
                       BlobStart, BlobLen))
          return Failure;

        if (Record.size() < 3) {
          reportInvalidFile("Invalid file entry");
          return Failure;
        }
        
        const FileEntry *FE =
          TopDiags.FakeFiles.getVirtualFile(TopDiags.FileNames[Record[0]],
                                            /* size */ Record[1],
                                            /* time */ Record[2]);
        
        TopDiags.Files[Record[0]] = FE;
        continue;
      }

      case serialized_diags::RECORD_SOURCE_RANGE: {
        CXSourceRange SR;
        if (readRange(TopDiags, Record, 0, SR))
          return Failure;
        D->Ranges.push_back(SR);
        continue;
      }
      
      case serialized_diags::RECORD_FIXIT: {
        CXSourceRange SR;
        if (readRange(TopDiags, Record, 0, SR))
          return Failure;
        llvm::StringRef RetStr;
        if (readString(TopDiags, RetStr, "FIXIT", Record, BlobStart, BlobLen,
                       /* allowEmptyString */ true))
          return Failure;
        D->FixIts.push_back(std::make_pair(SR, createCXString(RetStr, false)));
        continue;
      }
        
      case serialized_diags::RECORD_DIAG: {
        D->severity = Record[0];
        unsigned offset = 1;
        if (readLocation(TopDiags, Record, offset, D->DiagLoc))
          return Failure;
        D->category = Record[offset++];
        unsigned diagFlag = Record[offset++];
        D->DiagOption = diagFlag ? TopDiags.WarningFlags[diagFlag] : "";
        D->CategoryText = D->category ? TopDiags.Categories[D->category] : "";
        D->Spelling = TopDiags.makeString(BlobStart, BlobLen);
        continue;
      }
    }
  }
}

extern "C" {
CXDiagnosticSet clang_loadDiagnostics(const char *file,
                                      enum CXLoadDiag_Error *error,
                                      CXString *errorString) {
  DiagLoader L(error, errorString);
  return L.load(file);
}
} // end extern 'C'.
