//===--  BitcodeReader.cpp - ClangDoc Bitcode Reader ------------*- C++ -*-===//
//
// 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 "BitcodeReader.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"

namespace clang {
namespace doc {

using Record = llvm::SmallVector<uint64_t, 1024>;

llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl<char> &Field,
                         llvm::StringRef Blob) {
  Field.assign(Blob.begin(), Blob.end());
  return llvm::Error::success();
}

llvm::Error decodeRecord(Record R, SymbolID &Field, llvm::StringRef Blob) {
  if (R[0] != BitCodeConstants::USRHashSize)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "incorrect USR size");

  // First position in the record is the length of the following array, so we
  // copy the following elements to the field.
  for (int I = 0, E = R[0]; I < E; ++I)
    Field[I] = R[I + 1];
  return llvm::Error::success();
}

llvm::Error decodeRecord(Record R, bool &Field, llvm::StringRef Blob) {
  Field = R[0] != 0;
  return llvm::Error::success();
}

llvm::Error decodeRecord(Record R, int &Field, llvm::StringRef Blob) {
  if (R[0] > INT_MAX)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "integer too large to parse");
  Field = (int)R[0];
  return llvm::Error::success();
}

llvm::Error decodeRecord(Record R, AccessSpecifier &Field,
                         llvm::StringRef Blob) {
  switch (R[0]) {
  case AS_public:
  case AS_private:
  case AS_protected:
  case AS_none:
    Field = (AccessSpecifier)R[0];
    return llvm::Error::success();
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid value for AccessSpecifier");
  }
}

llvm::Error decodeRecord(Record R, TagTypeKind &Field, llvm::StringRef Blob) {
  switch (R[0]) {
  case TTK_Struct:
  case TTK_Interface:
  case TTK_Union:
  case TTK_Class:
  case TTK_Enum:
    Field = (TagTypeKind)R[0];
    return llvm::Error::success();
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid value for TagTypeKind");
  }
}

llvm::Error decodeRecord(Record R, llvm::Optional<Location> &Field,
                         llvm::StringRef Blob) {
  if (R[0] > INT_MAX)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "integer too large to parse");
  Field.emplace((int)R[0], Blob, (bool)R[1]);
  return llvm::Error::success();
}

llvm::Error decodeRecord(Record R, InfoType &Field, llvm::StringRef Blob) {
  switch (auto IT = static_cast<InfoType>(R[0])) {
  case InfoType::IT_namespace:
  case InfoType::IT_record:
  case InfoType::IT_function:
  case InfoType::IT_default:
  case InfoType::IT_enum:
    Field = IT;
    return llvm::Error::success();
  }
  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "invalid value for InfoType");
}

llvm::Error decodeRecord(Record R, FieldId &Field, llvm::StringRef Blob) {
  switch (auto F = static_cast<FieldId>(R[0])) {
  case FieldId::F_namespace:
  case FieldId::F_parent:
  case FieldId::F_vparent:
  case FieldId::F_type:
  case FieldId::F_child_namespace:
  case FieldId::F_child_record:
  case FieldId::F_default:
    Field = F;
    return llvm::Error::success();
  }
  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "invalid value for FieldId");
}

llvm::Error decodeRecord(Record R,
                         llvm::SmallVectorImpl<llvm::SmallString<16>> &Field,
                         llvm::StringRef Blob) {
  Field.push_back(Blob);
  return llvm::Error::success();
}

llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl<Location> &Field,
                         llvm::StringRef Blob) {
  if (R[0] > INT_MAX)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "integer too large to parse");
  Field.emplace_back((int)R[0], Blob, (bool)R[1]);
  return llvm::Error::success();
}

llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
                        const unsigned VersionNo) {
  if (ID == VERSION && R[0] == VersionNo)
    return llvm::Error::success();
  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "mismatched bitcode version number");
}

llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
                        NamespaceInfo *I) {
  switch (ID) {
  case NAMESPACE_USR:
    return decodeRecord(R, I->USR, Blob);
  case NAMESPACE_NAME:
    return decodeRecord(R, I->Name, Blob);
  case NAMESPACE_PATH:
    return decodeRecord(R, I->Path, Blob);
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid field for NamespaceInfo");
  }
}

llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
                        RecordInfo *I) {
  switch (ID) {
  case RECORD_USR:
    return decodeRecord(R, I->USR, Blob);
  case RECORD_NAME:
    return decodeRecord(R, I->Name, Blob);
  case RECORD_PATH:
    return decodeRecord(R, I->Path, Blob);
  case RECORD_DEFLOCATION:
    return decodeRecord(R, I->DefLoc, Blob);
  case RECORD_LOCATION:
    return decodeRecord(R, I->Loc, Blob);
  case RECORD_TAG_TYPE:
    return decodeRecord(R, I->TagType, Blob);
  case RECORD_IS_TYPE_DEF:
    return decodeRecord(R, I->IsTypeDef, Blob);
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid field for RecordInfo");
  }
}

llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
                        BaseRecordInfo *I) {
  switch (ID) {
  case BASE_RECORD_USR:
    return decodeRecord(R, I->USR, Blob);
  case BASE_RECORD_NAME:
    return decodeRecord(R, I->Name, Blob);
  case BASE_RECORD_PATH:
    return decodeRecord(R, I->Path, Blob);
  case BASE_RECORD_TAG_TYPE:
    return decodeRecord(R, I->TagType, Blob);
  case BASE_RECORD_IS_VIRTUAL:
    return decodeRecord(R, I->IsVirtual, Blob);
  case BASE_RECORD_ACCESS:
    return decodeRecord(R, I->Access, Blob);
  case BASE_RECORD_IS_PARENT:
    return decodeRecord(R, I->IsParent, Blob);
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid field for BaseRecordInfo");
  }
}

llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
                        EnumInfo *I) {
  switch (ID) {
  case ENUM_USR:
    return decodeRecord(R, I->USR, Blob);
  case ENUM_NAME:
    return decodeRecord(R, I->Name, Blob);
  case ENUM_DEFLOCATION:
    return decodeRecord(R, I->DefLoc, Blob);
  case ENUM_LOCATION:
    return decodeRecord(R, I->Loc, Blob);
  case ENUM_MEMBER:
    return decodeRecord(R, I->Members, Blob);
  case ENUM_SCOPED:
    return decodeRecord(R, I->Scoped, Blob);
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid field for EnumInfo");
  }
}

llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
                        FunctionInfo *I) {
  switch (ID) {
  case FUNCTION_USR:
    return decodeRecord(R, I->USR, Blob);
  case FUNCTION_NAME:
    return decodeRecord(R, I->Name, Blob);
  case FUNCTION_DEFLOCATION:
    return decodeRecord(R, I->DefLoc, Blob);
  case FUNCTION_LOCATION:
    return decodeRecord(R, I->Loc, Blob);
  case FUNCTION_ACCESS:
    return decodeRecord(R, I->Access, Blob);
  case FUNCTION_IS_METHOD:
    return decodeRecord(R, I->IsMethod, Blob);
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid field for FunctionInfo");
  }
}

llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
                        TypeInfo *I) {
  return llvm::Error::success();
}

llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
                        FieldTypeInfo *I) {
  switch (ID) {
  case FIELD_TYPE_NAME:
    return decodeRecord(R, I->Name, Blob);
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid field for TypeInfo");
  }
}

llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
                        MemberTypeInfo *I) {
  switch (ID) {
  case MEMBER_TYPE_NAME:
    return decodeRecord(R, I->Name, Blob);
  case MEMBER_TYPE_ACCESS:
    return decodeRecord(R, I->Access, Blob);
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid field for MemberTypeInfo");
  }
}

llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
                        CommentInfo *I) {
  switch (ID) {
  case COMMENT_KIND:
    return decodeRecord(R, I->Kind, Blob);
  case COMMENT_TEXT:
    return decodeRecord(R, I->Text, Blob);
  case COMMENT_NAME:
    return decodeRecord(R, I->Name, Blob);
  case COMMENT_DIRECTION:
    return decodeRecord(R, I->Direction, Blob);
  case COMMENT_PARAMNAME:
    return decodeRecord(R, I->ParamName, Blob);
  case COMMENT_CLOSENAME:
    return decodeRecord(R, I->CloseName, Blob);
  case COMMENT_ATTRKEY:
    return decodeRecord(R, I->AttrKeys, Blob);
  case COMMENT_ATTRVAL:
    return decodeRecord(R, I->AttrValues, Blob);
  case COMMENT_ARG:
    return decodeRecord(R, I->Args, Blob);
  case COMMENT_SELFCLOSING:
    return decodeRecord(R, I->SelfClosing, Blob);
  case COMMENT_EXPLICIT:
    return decodeRecord(R, I->Explicit, Blob);
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid field for CommentInfo");
  }
}

llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
                        Reference *I, FieldId &F) {
  switch (ID) {
  case REFERENCE_USR:
    return decodeRecord(R, I->USR, Blob);
  case REFERENCE_NAME:
    return decodeRecord(R, I->Name, Blob);
  case REFERENCE_TYPE:
    return decodeRecord(R, I->RefType, Blob);
  case REFERENCE_PATH:
    return decodeRecord(R, I->Path, Blob);
  case REFERENCE_IS_IN_GLOBAL_NAMESPACE:
    return decodeRecord(R, I->IsInGlobalNamespace, Blob);
  case REFERENCE_FIELD:
    return decodeRecord(R, F, Blob);
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid field for Reference");
  }
}

template <typename T> llvm::Expected<CommentInfo *> getCommentInfo(T I) {
  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "invalid type cannot contain CommentInfo");
}

template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
  I->Description.emplace_back();
  return &I->Description.back();
}

template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
  I->Description.emplace_back();
  return &I->Description.back();
}

template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
  I->Description.emplace_back();
  return &I->Description.back();
}

template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
  I->Description.emplace_back();
  return &I->Description.back();
}

template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) {
  I->Children.emplace_back(std::make_unique<CommentInfo>());
  return I->Children.back().get();
}

template <>
llvm::Expected<CommentInfo *> getCommentInfo(std::unique_ptr<CommentInfo> &I) {
  return getCommentInfo(I.get());
}

template <typename T, typename TTypeInfo>
llvm::Error addTypeInfo(T I, TTypeInfo &&TI) {
  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "invalid type cannot contain TypeInfo");
}

template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) {
  I->Members.emplace_back(std::move(T));
  return llvm::Error::success();
}

template <> llvm::Error addTypeInfo(BaseRecordInfo *I, MemberTypeInfo &&T) {
  I->Members.emplace_back(std::move(T));
  return llvm::Error::success();
}

template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) {
  I->ReturnType = std::move(T);
  return llvm::Error::success();
}

template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) {
  I->Params.emplace_back(std::move(T));
  return llvm::Error::success();
}

template <typename T> llvm::Error addReference(T I, Reference &&R, FieldId F) {
  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "invalid type cannot contain Reference");
}

template <> llvm::Error addReference(TypeInfo *I, Reference &&R, FieldId F) {
  switch (F) {
  case FieldId::F_type:
    I->Type = std::move(R);
    return llvm::Error::success();
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid type cannot contain Reference");
  }
}

template <>
llvm::Error addReference(FieldTypeInfo *I, Reference &&R, FieldId F) {
  switch (F) {
  case FieldId::F_type:
    I->Type = std::move(R);
    return llvm::Error::success();
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid type cannot contain Reference");
  }
}

template <>
llvm::Error addReference(MemberTypeInfo *I, Reference &&R, FieldId F) {
  switch (F) {
  case FieldId::F_type:
    I->Type = std::move(R);
    return llvm::Error::success();
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid type cannot contain Reference");
  }
}

template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) {
  switch (F) {
  case FieldId::F_namespace:
    I->Namespace.emplace_back(std::move(R));
    return llvm::Error::success();
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid type cannot contain Reference");
  }
}

template <>
llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) {
  switch (F) {
  case FieldId::F_namespace:
    I->Namespace.emplace_back(std::move(R));
    return llvm::Error::success();
  case FieldId::F_child_namespace:
    I->ChildNamespaces.emplace_back(std::move(R));
    return llvm::Error::success();
  case FieldId::F_child_record:
    I->ChildRecords.emplace_back(std::move(R));
    return llvm::Error::success();
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid type cannot contain Reference");
  }
}

template <>
llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) {
  switch (F) {
  case FieldId::F_namespace:
    I->Namespace.emplace_back(std::move(R));
    return llvm::Error::success();
  case FieldId::F_parent:
    I->Parent = std::move(R);
    return llvm::Error::success();
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid type cannot contain Reference");
  }
}

template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) {
  switch (F) {
  case FieldId::F_namespace:
    I->Namespace.emplace_back(std::move(R));
    return llvm::Error::success();
  case FieldId::F_parent:
    I->Parents.emplace_back(std::move(R));
    return llvm::Error::success();
  case FieldId::F_vparent:
    I->VirtualParents.emplace_back(std::move(R));
    return llvm::Error::success();
  case FieldId::F_child_record:
    I->ChildRecords.emplace_back(std::move(R));
    return llvm::Error::success();
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid type cannot contain Reference");
  }
}

template <typename T, typename ChildInfoType>
void addChild(T I, ChildInfoType &&R) {
  llvm::errs() << "invalid child type for info";
  exit(1);
}

template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
  I->ChildFunctions.emplace_back(std::move(R));
}

template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
  I->ChildEnums.emplace_back(std::move(R));
}

template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
  I->ChildFunctions.emplace_back(std::move(R));
}

template <> void addChild(RecordInfo *I, EnumInfo &&R) {
  I->ChildEnums.emplace_back(std::move(R));
}

template <> void addChild(RecordInfo *I, BaseRecordInfo &&R) {
  I->Bases.emplace_back(std::move(R));
}

template <> void addChild(BaseRecordInfo *I, FunctionInfo &&R) {
  I->ChildFunctions.emplace_back(std::move(R));
}

// Read records from bitcode into a given info.
template <typename T>
llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) {
  Record R;
  llvm::StringRef Blob;
  llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
  if (!MaybeRecID)
    return MaybeRecID.takeError();
  return parseRecord(R, MaybeRecID.get(), Blob, I);
}

template <>
llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
  Record R;
  llvm::StringRef Blob;
  llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
  if (!MaybeRecID)
    return MaybeRecID.takeError();
  return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField);
}

// Read a block of records into a single info.
template <typename T>
llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
  if (llvm::Error Err = Stream.EnterSubBlock(ID))
    return Err;

  while (true) {
    unsigned BlockOrCode = 0;
    Cursor Res = skipUntilRecordOrBlock(BlockOrCode);

    switch (Res) {
    case Cursor::BadBlock:
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "bad block found");
    case Cursor::BlockEnd:
      return llvm::Error::success();
    case Cursor::BlockBegin:
      if (llvm::Error Err = readSubBlock(BlockOrCode, I)) {
        if (llvm::Error Skipped = Stream.SkipBlock())
          return joinErrors(std::move(Err), std::move(Skipped));
        return Err;
      }
      continue;
    case Cursor::Record:
      break;
    }
    if (auto Err = readRecord(BlockOrCode, I))
      return Err;
  }
}

template <typename T>
llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
  switch (ID) {
  // Blocks can only have Comment, Reference, TypeInfo, FunctionInfo, or
  // EnumInfo subblocks
  case BI_COMMENT_BLOCK_ID: {
    auto Comment = getCommentInfo(I);
    if (!Comment)
      return Comment.takeError();
    if (auto Err = readBlock(ID, Comment.get()))
      return Err;
    return llvm::Error::success();
  }
  case BI_TYPE_BLOCK_ID: {
    TypeInfo TI;
    if (auto Err = readBlock(ID, &TI))
      return Err;
    if (auto Err = addTypeInfo(I, std::move(TI)))
      return Err;
    return llvm::Error::success();
  }
  case BI_FIELD_TYPE_BLOCK_ID: {
    FieldTypeInfo TI;
    if (auto Err = readBlock(ID, &TI))
      return Err;
    if (auto Err = addTypeInfo(I, std::move(TI)))
      return Err;
    return llvm::Error::success();
  }
  case BI_MEMBER_TYPE_BLOCK_ID: {
    MemberTypeInfo TI;
    if (auto Err = readBlock(ID, &TI))
      return Err;
    if (auto Err = addTypeInfo(I, std::move(TI)))
      return Err;
    return llvm::Error::success();
  }
  case BI_REFERENCE_BLOCK_ID: {
    Reference R;
    if (auto Err = readBlock(ID, &R))
      return Err;
    if (auto Err = addReference(I, std::move(R), CurrentReferenceField))
      return Err;
    return llvm::Error::success();
  }
  case BI_FUNCTION_BLOCK_ID: {
    FunctionInfo F;
    if (auto Err = readBlock(ID, &F))
      return Err;
    addChild(I, std::move(F));
    return llvm::Error::success();
  }
  case BI_BASE_RECORD_BLOCK_ID: {
    BaseRecordInfo BR;
    if (auto Err = readBlock(ID, &BR))
      return Err;
    addChild(I, std::move(BR));
    return llvm::Error::success();
  }
  case BI_ENUM_BLOCK_ID: {
    EnumInfo E;
    if (auto Err = readBlock(ID, &E))
      return Err;
    addChild(I, std::move(E));
    return llvm::Error::success();
  }
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid subblock type");
  }
}

ClangDocBitcodeReader::Cursor
ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
  BlockOrRecordID = 0;

  while (!Stream.AtEndOfStream()) {
    Expected<unsigned> MaybeCode = Stream.ReadCode();
    if (!MaybeCode) {
      // FIXME this drops the error on the floor.
      consumeError(MaybeCode.takeError());
      return Cursor::BadBlock;
    }

    unsigned Code = MaybeCode.get();
    if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
      BlockOrRecordID = Code;
      return Cursor::Record;
    }
    switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code)) {
    case llvm::bitc::ENTER_SUBBLOCK:
      if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
        BlockOrRecordID = MaybeID.get();
      else {
        // FIXME this drops the error on the floor.
        consumeError(MaybeID.takeError());
      }
      return Cursor::BlockBegin;
    case llvm::bitc::END_BLOCK:
      if (Stream.ReadBlockEnd())
        return Cursor::BadBlock;
      return Cursor::BlockEnd;
    case llvm::bitc::DEFINE_ABBREV:
      if (llvm::Error Err = Stream.ReadAbbrevRecord()) {
        // FIXME this drops the error on the floor.
        consumeError(std::move(Err));
      }
      continue;
    case llvm::bitc::UNABBREV_RECORD:
      return Cursor::BadBlock;
    case llvm::bitc::FIRST_APPLICATION_ABBREV:
      llvm_unreachable("Unexpected abbrev id.");
    }
  }
  llvm_unreachable("Premature stream end.");
}

llvm::Error ClangDocBitcodeReader::validateStream() {
  if (Stream.AtEndOfStream())
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "premature end of stream");

  // Sniff for the signature.
  for (int Idx = 0; Idx != 4; ++Idx) {
    Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8);
    if (!MaybeRead)
      return MaybeRead.takeError();
    else if (MaybeRead.get() != BitCodeConstants::Signature[Idx])
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "invalid bitcode signature");
  }
  return llvm::Error::success();
}

llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
  Expected<Optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
      Stream.ReadBlockInfoBlock();
  if (!MaybeBlockInfo)
    return MaybeBlockInfo.takeError();
  else
    BlockInfo = MaybeBlockInfo.get();
  if (!BlockInfo)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "unable to parse BlockInfoBlock");
  Stream.setBlockInfo(&*BlockInfo);
  return llvm::Error::success();
}

template <typename T>
llvm::Expected<std::unique_ptr<Info>>
ClangDocBitcodeReader::createInfo(unsigned ID) {
  std::unique_ptr<Info> I = std::make_unique<T>();
  if (auto Err = readBlock(ID, static_cast<T *>(I.get())))
    return std::move(Err);
  return std::unique_ptr<Info>{std::move(I)};
}

llvm::Expected<std::unique_ptr<Info>>
ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
  switch (ID) {
  case BI_NAMESPACE_BLOCK_ID:
    return createInfo<NamespaceInfo>(ID);
  case BI_RECORD_BLOCK_ID:
    return createInfo<RecordInfo>(ID);
  case BI_ENUM_BLOCK_ID:
    return createInfo<EnumInfo>(ID);
  case BI_FUNCTION_BLOCK_ID:
    return createInfo<FunctionInfo>(ID);
  default:
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "cannot create info");
  }
}

// Entry point
llvm::Expected<std::vector<std::unique_ptr<Info>>>
ClangDocBitcodeReader::readBitcode() {
  std::vector<std::unique_ptr<Info>> Infos;
  if (auto Err = validateStream())
    return std::move(Err);

  // Read the top level blocks.
  while (!Stream.AtEndOfStream()) {
    Expected<unsigned> MaybeCode = Stream.ReadCode();
    if (!MaybeCode)
      return MaybeCode.takeError();
    if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK)
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "no blocks in input");
    Expected<unsigned> MaybeID = Stream.ReadSubBlockID();
    if (!MaybeID)
      return MaybeID.takeError();
    unsigned ID = MaybeID.get();
    switch (ID) {
    // NamedType and Comment blocks should not appear at the top level
    case BI_TYPE_BLOCK_ID:
    case BI_FIELD_TYPE_BLOCK_ID:
    case BI_MEMBER_TYPE_BLOCK_ID:
    case BI_COMMENT_BLOCK_ID:
    case BI_REFERENCE_BLOCK_ID:
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "invalid top level block");
    case BI_NAMESPACE_BLOCK_ID:
    case BI_RECORD_BLOCK_ID:
    case BI_ENUM_BLOCK_ID:
    case BI_FUNCTION_BLOCK_ID: {
      auto InfoOrErr = readBlockToInfo(ID);
      if (!InfoOrErr)
        return InfoOrErr.takeError();
      Infos.emplace_back(std::move(InfoOrErr.get()));
      continue;
    }
    case BI_VERSION_BLOCK_ID:
      if (auto Err = readBlock(ID, VersionNumber))
        return std::move(Err);
      continue;
    case llvm::bitc::BLOCKINFO_BLOCK_ID:
      if (auto Err = readBlockInfoBlock())
        return std::move(Err);
      continue;
    default:
      if (llvm::Error Err = Stream.SkipBlock()) {
        // FIXME this drops the error on the floor.
        consumeError(std::move(Err));
      }
      continue;
    }
  }
  return std::move(Infos);
}

} // namespace doc
} // namespace clang
