//===- NamedStreamMap.cpp - PDB Named Stream Map --------------------------===//
//
// 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 "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/DebugInfo/PDB/Native/HashTable.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <tuple>

using namespace llvm;
using namespace llvm::pdb;

NamedStreamMapTraits::NamedStreamMapTraits(NamedStreamMap &NS) : NS(&NS) {}

uint16_t NamedStreamMapTraits::hashLookupKey(StringRef S) const {
  // In the reference implementation, this uses
  // HASH Hasher<ULONG*, USHORT*>::hashPbCb(PB pb, size_t cb, ULONG ulMod).
  // Here, the type HASH is a typedef of unsigned short.
  // ** It is not a bug that we truncate the result of hashStringV1, in fact
  //    it is a bug if we do not! **
  return static_cast<uint16_t>(hashStringV1(S));
}

StringRef NamedStreamMapTraits::storageKeyToLookupKey(uint32_t Offset) const {
  return NS->getString(Offset);
}

uint32_t NamedStreamMapTraits::lookupKeyToStorageKey(StringRef S) {
  return NS->appendStringData(S);
}

NamedStreamMap::NamedStreamMap()
    : HashTraits(*this), OffsetIndexMap(1, HashTraits) {}

Error NamedStreamMap::load(BinaryStreamReader &Stream) {
  uint32_t StringBufferSize;
  if (auto EC = Stream.readInteger(StringBufferSize))
    return joinErrors(std::move(EC),
                      make_error<RawError>(raw_error_code::corrupt_file,
                                           "Expected string buffer size"));

  StringRef Buffer;
  if (auto EC = Stream.readFixedString(Buffer, StringBufferSize))
    return EC;
  NamesBuffer.assign(Buffer.begin(), Buffer.end());

  return OffsetIndexMap.load(Stream);
}

Error NamedStreamMap::commit(BinaryStreamWriter &Writer) const {
  // The first field is the number of bytes of string data.
  if (auto EC = Writer.writeInteger<uint32_t>(NamesBuffer.size()))
    return EC;

  // Then the actual string data.
  StringRef Data(NamesBuffer.data(), NamesBuffer.size());
  if (auto EC = Writer.writeFixedString(Data))
    return EC;

  // And finally the Offset Index map.
  if (auto EC = OffsetIndexMap.commit(Writer))
    return EC;

  return Error::success();
}

uint32_t NamedStreamMap::calculateSerializedLength() const {
  return sizeof(uint32_t)                              // String data size
         + NamesBuffer.size()                          // String data
         + OffsetIndexMap.calculateSerializedLength(); // Offset Index Map
}

uint32_t NamedStreamMap::size() const { return OffsetIndexMap.size(); }

StringRef NamedStreamMap::getString(uint32_t Offset) const {
  assert(NamesBuffer.size() > Offset);
  return StringRef(NamesBuffer.data() + Offset);
}

uint32_t NamedStreamMap::hashString(uint32_t Offset) const {
  return hashStringV1(getString(Offset));
}

bool NamedStreamMap::get(StringRef Stream, uint32_t &StreamNo) const {
  auto Iter = OffsetIndexMap.find_as(Stream);
  if (Iter == OffsetIndexMap.end())
    return false;
  StreamNo = (*Iter).second;
  return true;
}

StringMap<uint32_t> NamedStreamMap::entries() const {
  StringMap<uint32_t> Result;
  for (const auto &Entry : OffsetIndexMap) {
    StringRef Stream(NamesBuffer.data() + Entry.first);
    Result.try_emplace(Stream, Entry.second);
  }
  return Result;
}

uint32_t NamedStreamMap::appendStringData(StringRef S) {
  uint32_t Offset = NamesBuffer.size();
  NamesBuffer.insert(NamesBuffer.end(), S.begin(), S.end());
  NamesBuffer.push_back('\0');
  return Offset;
}

void NamedStreamMap::set(StringRef Stream, uint32_t StreamNo) {
  OffsetIndexMap.set_as(Stream, support::ulittle32_t(StreamNo));
}
