//===- RecordSerialization.h ------------------------------------*- 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_CODEVIEW_RECORDSERIALIZATION_H
#define LLVM_DEBUGINFO_CODEVIEW_RECORDSERIALIZATION_H

#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cinttypes>
#include <tuple>

namespace llvm {
namespace codeview {
using llvm::support::little32_t;
using llvm::support::ulittle16_t;
using llvm::support::ulittle32_t;

/// Limit on the size of all codeview symbol and type records, including the
/// RecordPrefix. MSVC does not emit any records larger than this.
enum : unsigned { MaxRecordLength = 0xFF00 };

struct RecordPrefix {
  RecordPrefix() = default;
  explicit RecordPrefix(uint16_t Kind) : RecordLen(2), RecordKind(Kind) {}

  ulittle16_t RecordLen;  // Record length, starting from &RecordKind.
  ulittle16_t RecordKind; // Record kind enum (SymRecordKind or TypeRecordKind)
};

/// Reinterpret a byte array as an array of characters. Does not interpret as
/// a C string, as StringRef has several helpers (split) that make that easy.
StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData);
StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData);

inline Error consume(BinaryStreamReader &Reader) { return Error::success(); }

/// Decodes a numeric "leaf" value. These are integer literals encountered in
/// the type stream. If the value is positive and less than LF_NUMERIC (1 <<
/// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR
/// that indicates the bitwidth and sign of the numeric data.
Error consume(BinaryStreamReader &Reader, APSInt &Num);

/// Decodes a numeric leaf value that is known to be a particular type.
Error consume_numeric(BinaryStreamReader &Reader, uint64_t &Value);

/// Decodes signed and unsigned fixed-length integers.
Error consume(BinaryStreamReader &Reader, uint32_t &Item);
Error consume(BinaryStreamReader &Reader, int32_t &Item);

/// Decodes a null terminated string.
Error consume(BinaryStreamReader &Reader, StringRef &Item);

Error consume(StringRef &Data, APSInt &Num);
Error consume(StringRef &Data, uint32_t &Item);

/// Decodes an arbitrary object whose layout matches that of the underlying
/// byte sequence, and returns a pointer to the object.
template <typename T> Error consume(BinaryStreamReader &Reader, T *&Item) {
  return Reader.readObject(Item);
}

template <typename T, typename U> struct serialize_conditional_impl {
  serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {}

  Error deserialize(BinaryStreamReader &Reader) const {
    if (!Func())
      return Error::success();
    return consume(Reader, Item);
  }

  T &Item;
  U Func;
};

template <typename T, typename U>
serialize_conditional_impl<T, U> serialize_conditional(T &Item, U Func) {
  return serialize_conditional_impl<T, U>(Item, Func);
}

template <typename T, typename U> struct serialize_array_impl {
  serialize_array_impl(ArrayRef<T> &Item, U Func) : Item(Item), Func(Func) {}

  Error deserialize(BinaryStreamReader &Reader) const {
    return Reader.readArray(Item, Func());
  }

  ArrayRef<T> &Item;
  U Func;
};

template <typename T> struct serialize_vector_tail_impl {
  serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {}

  Error deserialize(BinaryStreamReader &Reader) const {
    T Field;
    // Stop when we run out of bytes or we hit record padding bytes.
    while (!Reader.empty() && Reader.peek() < LF_PAD0) {
      if (auto EC = consume(Reader, Field))
        return EC;
      Item.push_back(Field);
    }
    return Error::success();
  }

  std::vector<T> &Item;
};

struct serialize_null_term_string_array_impl {
  serialize_null_term_string_array_impl(std::vector<StringRef> &Item)
      : Item(Item) {}

  Error deserialize(BinaryStreamReader &Reader) const {
    if (Reader.empty())
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer,
                                       "Null terminated string is empty!");

    while (Reader.peek() != 0) {
      StringRef Field;
      if (auto EC = Reader.readCString(Field))
        return EC;
      Item.push_back(Field);
    }
    return Reader.skip(1);
  }

  std::vector<StringRef> &Item;
};

template <typename T> struct serialize_arrayref_tail_impl {
  serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {}

  Error deserialize(BinaryStreamReader &Reader) const {
    uint32_t Count = Reader.bytesRemaining() / sizeof(T);
    return Reader.readArray(Item, Count);
  }

  ArrayRef<T> &Item;
};

template <typename T> struct serialize_numeric_impl {
  serialize_numeric_impl(T &Item) : Item(Item) {}

  Error deserialize(BinaryStreamReader &Reader) const {
    return consume_numeric(Reader, Item);
  }

  T &Item;
};

template <typename T, typename U>
serialize_array_impl<T, U> serialize_array(ArrayRef<T> &Item, U Func) {
  return serialize_array_impl<T, U>(Item, Func);
}

inline serialize_null_term_string_array_impl
serialize_null_term_string_array(std::vector<StringRef> &Item) {
  return serialize_null_term_string_array_impl(Item);
}

template <typename T>
serialize_vector_tail_impl<T> serialize_array_tail(std::vector<T> &Item) {
  return serialize_vector_tail_impl<T>(Item);
}

template <typename T>
serialize_arrayref_tail_impl<T> serialize_array_tail(ArrayRef<T> &Item) {
  return serialize_arrayref_tail_impl<T>(Item);
}

template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) {
  return serialize_numeric_impl<T>(Item);
}

template <typename T, typename U>
Error consume(BinaryStreamReader &Reader,
              const serialize_conditional_impl<T, U> &Item) {
  return Item.deserialize(Reader);
}

template <typename T, typename U>
Error consume(BinaryStreamReader &Reader,
              const serialize_array_impl<T, U> &Item) {
  return Item.deserialize(Reader);
}

inline Error consume(BinaryStreamReader &Reader,
                     const serialize_null_term_string_array_impl &Item) {
  return Item.deserialize(Reader);
}

template <typename T>
Error consume(BinaryStreamReader &Reader,
              const serialize_vector_tail_impl<T> &Item) {
  return Item.deserialize(Reader);
}

template <typename T>
Error consume(BinaryStreamReader &Reader,
              const serialize_arrayref_tail_impl<T> &Item) {
  return Item.deserialize(Reader);
}

template <typename T>
Error consume(BinaryStreamReader &Reader,
              const serialize_numeric_impl<T> &Item) {
  return Item.deserialize(Reader);
}

template <typename T, typename U, typename... Args>
Error consume(BinaryStreamReader &Reader, T &&X, U &&Y, Args &&... Rest) {
  if (auto EC = consume(Reader, X))
    return EC;
  return consume(Reader, Y, std::forward<Args>(Rest)...);
}

}
}

#endif
