#ifndef ANDROID_PDX_RPC_SERIALIZATION_H_
#define ANDROID_PDX_RPC_SERIALIZATION_H_

#include <cstdint>
#include <cstring>
#include <iterator>
#include <map>
#include <numeric>
#include <sstream>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

#include <pdx/channel_handle.h>
#include <pdx/file_handle.h>
#include <pdx/message_reader.h>
#include <pdx/message_writer.h>
#include <pdx/trace.h>
#include <pdx/utility.h>

#include "array_wrapper.h"
#include "default_initialization_allocator.h"
#include "encoding.h"
#include "pointer_wrapper.h"
#include "string_wrapper.h"
#include "variant.h"

namespace android {
namespace pdx {
namespace rpc {

// Automatic serialization/deserialization library based on MessagePack
// (http://msgpack.org). This library provides top level Serialize() and
// Deserialize() functions to encode/decode a variety of data types.
//
// The following data types are supported:
//   * Standard signed integer types: int8_t, int16_t, int32_t, and int64_t.
//   * Regular signed integer types equivalent to the standard types:
//     signed char, short, int, long, and long long.
//   * Standard unsigned integer types: uint8_t, uint16_t, uint32_t, and
//     uint64_t.
//   * Regular unsigned integer types equivalent to the standard types:
//     unsigned char, unsigned short, unsigned int, unsigned long,
//     and unsigned long long.
//   * char without signed/unsigned qualifiers.
//   * bool.
//   * std::vector with value type of any supported type, including nesting.
//   * std::string.
//   * std::tuple with elements of any supported type, including nesting.
//   * std::pair with elements of any supported type, including nesting.
//   * std::map with keys and values of any supported type, including nesting.
//   * std::unordered_map with keys and values of any supported type, including
//     nesting.
//   * std::array with values of any supported type, including nesting.
//   * ArrayWrapper of any supported basic type.
//   * BufferWrapper of any POD type.
//   * StringWrapper of any supported char type.
//   * User types with correctly defined SerializableMembers member type.
//
// Planned support for:
//   * std::basic_string with all supported char types.

// Counting template for managing template recursion.
template <std::size_t N>
struct Index {};

// Forward declaration of traits type to access types with a SerializedMembers
// member type.
template <typename T>
class SerializableTraits;

template <typename T, typename... MemberPointers>
struct SerializableMembersType;

// Utility to deduce the template type from a derived type.
template <template <typename...> class TT, typename... Ts>
std::true_type DeduceTemplateType(const TT<Ts...>*);
template <template <typename...> class TT>
std::false_type DeduceTemplateType(...);

// Utility determining whether template type TT<...> is a base of type T.
template <template <typename...> class TT, typename T>
using IsTemplateBaseOf = decltype(DeduceTemplateType<TT>(std::declval<T*>()));

// Utility type for SFINAE in HasHasSerializableMembers.
template <typename... Ts>
using TrySerializableMembersType = void;

// Determines whether type T has a member type named SerializableMembers of
// template type SerializableMembersType.
template <typename, typename = void>
struct HasSerializableMembers : std::false_type {};
template <typename T>
struct HasSerializableMembers<
    T, TrySerializableMembersType<typename T::SerializableMembers>>
    : std::integral_constant<
          bool, IsTemplateBaseOf<SerializableMembersType,
                                 typename T::SerializableMembers>::value> {};

// Utility to simplify overload enable expressions for types with correctly
// defined SerializableMembers.
template <typename T>
using EnableIfHasSerializableMembers =
    typename std::enable_if<HasSerializableMembers<T>::value>::type;

// Utility to simplify overload enable expressions for enum types.
template <typename T, typename ReturnType = void>
using EnableIfEnum =
    typename std::enable_if<std::is_enum<T>::value, ReturnType>::type;

///////////////////////////////////////////////////////////////////////////////
// Error Reporting //
///////////////////////////////////////////////////////////////////////////////

// Error codes returned by the deserialization code.
enum class ErrorCode {
  NO_ERROR = 0,
  UNEXPECTED_ENCODING,
  UNEXPECTED_TYPE_SIZE,
  INSUFFICIENT_BUFFER,
  INSUFFICIENT_DESTINATION_SIZE,
  GET_FILE_DESCRIPTOR_FAILED,
  GET_CHANNEL_HANDLE_FAILED,
  INVALID_VARIANT_ELEMENT,
};

// Type for errors returned by the deserialization code.
class ErrorType {
 public:
  ErrorType() : error_code_(ErrorCode::NO_ERROR) {}

  // ErrorType constructor for generic error codes. Explicitly not explicit,
  // implicit conversion from ErrorCode to ErrorType is desirable behavior.
  // NOLINTNEXTLINE(runtime/explicit)
  ErrorType(ErrorCode error_code) : error_code_(error_code) {}

  // ErrorType constructor for encoding type errors.
  ErrorType(ErrorCode error_code, EncodingClass encoding_class,
            EncodingType encoding_type)
      : error_code_(error_code) {
    unexpected_encoding_.encoding_class = encoding_class;
    unexpected_encoding_.encoding_type = encoding_type;
  }

  // Evaluates to true if the ErrorType represents an error.
  explicit operator bool() const { return error_code_ != ErrorCode::NO_ERROR; }

  operator ErrorCode() const { return error_code_; }
  ErrorCode error_code() const { return error_code_; }

  // Accessors for extra info about unexpected encoding errors.
  EncodingClass encoding_class() const {
    return unexpected_encoding_.encoding_class;
  }
  EncodingType encoding_type() const {
    return unexpected_encoding_.encoding_type;
  }

  operator std::string() const {
    std::ostringstream stream;

    switch (error_code_) {
      case ErrorCode::NO_ERROR:
        return "NO_ERROR";
      case ErrorCode::UNEXPECTED_ENCODING:
        stream << "UNEXPECTED_ENCODING: " << static_cast<int>(encoding_class())
               << ", " << static_cast<int>(encoding_type());
        return stream.str();
      case ErrorCode::UNEXPECTED_TYPE_SIZE:
        return "UNEXPECTED_TYPE_SIZE";
      case ErrorCode::INSUFFICIENT_BUFFER:
        return "INSUFFICIENT_BUFFER";
      case ErrorCode::INSUFFICIENT_DESTINATION_SIZE:
        return "INSUFFICIENT_DESTINATION_SIZE";
      default:
        return "[Unknown Error]";
    }
  }

 private:
  ErrorCode error_code_;

  // Union of extra information for different error code types.
  union {
    // UNEXPECTED_ENCODING.
    struct {
      EncodingClass encoding_class;
      EncodingType encoding_type;
    } unexpected_encoding_;
  };
};

///////////////////////////////////////////////////////////////////////////////
// Object Size //
///////////////////////////////////////////////////////////////////////////////

inline constexpr std::size_t GetSerializedSize(const bool& b) {
  return GetEncodingSize(EncodeType(b));
}

// Overloads of GetSerializedSize() for standard integer types.
inline constexpr std::size_t GetSerializedSize(const char& c) {
  return GetEncodingSize(EncodeType(c));
}
inline constexpr std::size_t GetSerializedSize(const std::uint8_t& i) {
  return GetEncodingSize(EncodeType(i));
}
inline constexpr std::size_t GetSerializedSize(const std::int8_t& i) {
  return GetEncodingSize(EncodeType(i));
}
inline constexpr std::size_t GetSerializedSize(const std::uint16_t& i) {
  return GetEncodingSize(EncodeType(i));
}
inline constexpr std::size_t GetSerializedSize(const std::int16_t& i) {
  return GetEncodingSize(EncodeType(i));
}
inline constexpr std::size_t GetSerializedSize(const std::uint32_t& i) {
  return GetEncodingSize(EncodeType(i));
}
inline constexpr std::size_t GetSerializedSize(const std::int32_t& i) {
  return GetEncodingSize(EncodeType(i));
}
inline constexpr std::size_t GetSerializedSize(const std::uint64_t& i) {
  return GetEncodingSize(EncodeType(i));
}
inline constexpr std::size_t GetSerializedSize(const std::int64_t& i) {
  return GetEncodingSize(EncodeType(i));
}

inline constexpr std::size_t GetSerializedSize(const float& f) {
  return GetEncodingSize(EncodeType(f));
}
inline constexpr std::size_t GetSerializedSize(const double& d) {
  return GetEncodingSize(EncodeType(d));
}

// Overload for enum types.
template <typename T>
inline EnableIfEnum<T, std::size_t> GetSerializedSize(T v) {
  return GetSerializedSize(static_cast<std::underlying_type_t<T>>(v));
}

// Forward declaration for nested definitions.
inline std::size_t GetSerializedSize(const EmptyVariant&);
template <typename... Types>
inline std::size_t GetSerializedSize(const Variant<Types...>&);
template <typename T, typename Enabled>
inline constexpr std::size_t GetSerializedSize(const T&);
template <typename T>
inline constexpr std::size_t GetSerializedSize(const PointerWrapper<T>&);
inline constexpr std::size_t GetSerializedSize(const std::string&);
template <typename T>
inline constexpr std::size_t GetSerializedSize(const StringWrapper<T>&);
template <typename T>
inline constexpr std::size_t GetSerializedSize(const BufferWrapper<T>&);
template <FileHandleMode Mode>
inline constexpr std::size_t GetSerializedSize(const FileHandle<Mode>&);
template <ChannelHandleMode Mode>
inline constexpr std::size_t GetSerializedSize(const ChannelHandle<Mode>&);
template <typename T, typename Allocator>
inline std::size_t GetSerializedSize(const std::vector<T, Allocator>& v);
template <typename Key, typename T, typename Compare, typename Allocator>
inline std::size_t GetSerializedSize(
    const std::map<Key, T, Compare, Allocator>& m);
template <typename Key, typename T, typename Hash, typename KeyEqual,
          typename Allocator>
inline std::size_t GetSerializedSize(
    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>&);
template <typename T>
inline std::size_t GetSerializedSize(const ArrayWrapper<T>&);
template <typename T, std::size_t Size>
inline std::size_t GetSerializedSize(const std::array<T, Size>& v);
template <typename T, typename U>
inline std::size_t GetSerializedSize(const std::pair<T, U>& p);
template <typename... T>
inline std::size_t GetSerializedSize(const std::tuple<T...>& tuple);

// Overload for empty variant type.
inline std::size_t GetSerializedSize(const EmptyVariant& empty) {
  return GetEncodingSize(EncodeType(empty));
}

// Overload for Variant types.
template <typename... Types>
inline std::size_t GetSerializedSize(const Variant<Types...>& variant) {
  return GetEncodingSize(EncodeType(variant)) +
         GetSerializedSize(variant.index()) +
         variant.Visit(
             [](const auto& value) { return GetSerializedSize(value); });
}

// Overload for structs/classes with SerializableMembers defined.
template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
inline constexpr std::size_t GetSerializedSize(const T& value) {
  return SerializableTraits<T>::GetSerializedSize(value);
}

// Overload for PointerWrapper.
template <typename T>
inline constexpr std::size_t GetSerializedSize(const PointerWrapper<T>& p) {
  return GetSerializedSize(p.Dereference());
}

// Overload for std::string.
inline constexpr std::size_t GetSerializedSize(const std::string& s) {
  return GetEncodingSize(EncodeType(s)) +
         s.length() * sizeof(std::string::value_type);
}

// Overload for StringWrapper.
template <typename T>
inline constexpr std::size_t GetSerializedSize(const StringWrapper<T>& s) {
  return GetEncodingSize(EncodeType(s)) +
         s.length() * sizeof(typename StringWrapper<T>::value_type);
}

// Overload for BufferWrapper types.
template <typename T>
inline constexpr std::size_t GetSerializedSize(const BufferWrapper<T>& b) {
  return GetEncodingSize(EncodeType(b)) +
         b.size() * sizeof(typename BufferWrapper<T>::value_type);
}

// Overload for FileHandle. FileHandle is encoded as a FIXEXT2, with a type code
// of "FileHandle" and a signed 16-bit offset into the pushed fd array. Empty
// FileHandles are encoded with an array index of -1.
template <FileHandleMode Mode>
inline constexpr std::size_t GetSerializedSize(const FileHandle<Mode>& fd) {
  return GetEncodingSize(EncodeType(fd)) + sizeof(std::int16_t);
}

// Overload for ChannelHandle. ChannelHandle is encoded as a FIXEXT4, with a
// type code of "ChannelHandle" and a signed 32-bit offset into the pushed
// channel array. Empty ChannelHandles are encoded with an array index of -1.
template <ChannelHandleMode Mode>
inline constexpr std::size_t GetSerializedSize(
    const ChannelHandle<Mode>& channel_handle) {
  return GetEncodingSize(EncodeType(channel_handle)) + sizeof(std::int32_t);
}

// Overload for standard vector types.
template <typename T, typename Allocator>
inline std::size_t GetSerializedSize(const std::vector<T, Allocator>& v) {
  return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
                         [](const std::size_t& sum, const T& object) {
                           return sum + GetSerializedSize(object);
                         });
}

// Overload for standard map types.
template <typename Key, typename T, typename Compare, typename Allocator>
inline std::size_t GetSerializedSize(
    const std::map<Key, T, Compare, Allocator>& v) {
  return std::accumulate(
      v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
      [](const std::size_t& sum, const std::pair<Key, T>& object) {
        return sum + GetSerializedSize(object.first) +
               GetSerializedSize(object.second);
      });
}

// Overload for standard unordered_map types.
template <typename Key, typename T, typename Hash, typename KeyEqual,
          typename Allocator>
inline std::size_t GetSerializedSize(
    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& v) {
  return std::accumulate(
      v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
      [](const std::size_t& sum, const std::pair<Key, T>& object) {
        return sum + GetSerializedSize(object.first) +
               GetSerializedSize(object.second);
      });
}

// Overload for ArrayWrapper types.
template <typename T>
inline std::size_t GetSerializedSize(const ArrayWrapper<T>& v) {
  return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
                         [](const std::size_t& sum, const T& object) {
                           return sum + GetSerializedSize(object);
                         });
}

// Overload for std::array types.
template <typename T, std::size_t Size>
inline std::size_t GetSerializedSize(const std::array<T, Size>& v) {
  return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
                         [](const std::size_t& sum, const T& object) {
                           return sum + GetSerializedSize(object);
                         });
}

// Overload for std::pair.
template <typename T, typename U>
inline std::size_t GetSerializedSize(const std::pair<T, U>& p) {
  return GetEncodingSize(EncodeType(p)) + GetSerializedSize(p.first) +
         GetSerializedSize(p.second);
}

// Stops template recursion when the last tuple element is reached.
template <typename... T>
inline std::size_t GetTupleSize(const std::tuple<T...>&, Index<0>) {
  return 0;
}

// Gets the size of each element in a tuple recursively.
template <typename... T, std::size_t index>
inline std::size_t GetTupleSize(const std::tuple<T...>& tuple, Index<index>) {
  return GetTupleSize(tuple, Index<index - 1>()) +
         GetSerializedSize(std::get<index - 1>(tuple));
}

// Overload for tuple types. Gets the size of the tuple, recursing
// through the elements.
template <typename... T>
inline std::size_t GetSerializedSize(const std::tuple<T...>& tuple) {
  return GetEncodingSize(EncodeType(tuple)) +
         GetTupleSize(tuple, Index<sizeof...(T)>());
}

// Stops template recursion when the last member of a Serializable
// type is reached.
template <typename Members, typename T>
inline std::size_t GetMemberSize(const T&, Index<0>) {
  return 0;
}

// Gets the size of each member of a Serializable type recursively.
template <typename Members, typename T, std::size_t index>
inline std::size_t GetMemberSize(const T& object, Index<index>) {
  return GetMemberSize<Members>(object, Index<index - 1>()) +
         GetSerializedSize(Members::template At<index - 1>::Resolve(object));
}

// Gets the size of a type using the given SerializableMembersType
// type.
template <typename Members, typename T>
inline std::size_t GetMembersSize(const T& object) {
  return GetMemberSize<Members>(object, Index<Members::MemberCount>());
}

///////////////////////////////////////////////////////////////////////////////
// Object Serialization //
///////////////////////////////////////////////////////////////////////////////

//
// SerializeRaw() converts a primitive array or type into a raw byte string.
// These functions are named differently from SerializeObject() expressly to
// avoid catch-all specialization of that template, which can be difficult to
// detect otherwise.
//

inline void WriteRawData(void*& dest, const void* src, size_t size) {
  memcpy(dest, src, size);
  dest = static_cast<uint8_t*>(dest) + size;
}

// Serializes a primitive array into a raw byte string.
template <typename T,
          typename = typename std::enable_if<std::is_pod<T>::value>::type>
inline void SerializeRaw(const T& value, void*& buffer) {
  WriteRawData(buffer, &value, sizeof(value));
}

inline void SerializeEncoding(EncodingType encoding, void*& buffer) {
  SerializeRaw(encoding, buffer);
}

inline void SerializeType(const bool& value, void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
}

// Serializes the type code, extended type code, and size for
// extension types.
inline void SerializeExtEncoding(EncodingType encoding,
                                 EncodingExtType ext_type, std::size_t size,
                                 void*& buffer) {
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_EXT8) {
    std::uint8_t length = size;
    SerializeRaw(length, buffer);
  } else if (encoding == ENCODING_TYPE_EXT16) {
    std::uint16_t length = size;
    SerializeRaw(length, buffer);
  } else if (encoding == ENCODING_TYPE_EXT32) {
    std::uint32_t length = size;
    SerializeRaw(length, buffer);
  } else /* if (IsFixextEncoding(encoding) */ {
    // Encoding byte contains the fixext length, nothing else to do.
  }
  SerializeRaw(ext_type, buffer);
}

// Serializes the type code for file descriptor types.
template <FileHandleMode Mode>
inline void SerializeType(const FileHandle<Mode>& value, void*& buffer) {
  SerializeExtEncoding(EncodeType(value), ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 2,
                       buffer);
}

// Serializes the type code for channel handle types.
template <ChannelHandleMode Mode>
inline void SerializeType(const ChannelHandle<Mode>& handle, void*& buffer) {
  SerializeExtEncoding(EncodeType(handle), ENCODING_EXT_TYPE_CHANNEL_HANDLE, 4,
                       buffer);
}

// Serializes type code for variant types.
template <typename... Types>
inline void SerializeType(const Variant<Types...>& value, void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
}

// Serializes the type code for string types.
template <typename StringType>
inline void SerializeStringType(const StringType& value, void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_STR8) {
    std::uint8_t length = value.length();
    SerializeRaw(length, buffer);
  } else if (encoding == ENCODING_TYPE_STR16) {
    std::uint16_t length = value.length();
    SerializeRaw(length, buffer);
  } else if (encoding == ENCODING_TYPE_STR32) {
    std::uint32_t length = value.length();
    SerializeRaw(length, buffer);
  } else /* if (IsFixstrEncoding(encoding) */ {
    // Encoding byte contains the fixstr length, nothing else to do.
  }
}

// Serializes the type code for std::string and StringWrapper. These types are
// interchangeable and must serialize to the same format.
inline void SerializeType(const std::string& value, void*& buffer) {
  SerializeStringType(value, buffer);
}
template <typename T>
inline void SerializeType(const StringWrapper<T>& value, void*& buffer) {
  SerializeStringType(value, buffer);
}

// Serializes the type code for bin types.
inline void SerializeBinEncoding(EncodingType encoding, std::size_t size,
                                 void*& buffer) {
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_BIN8) {
    std::uint8_t length = size;
    SerializeRaw(length, buffer);
  } else if (encoding == ENCODING_TYPE_BIN16) {
    std::uint16_t length = size;
    SerializeRaw(length, buffer);
  } else if (encoding == ENCODING_TYPE_BIN32) {
    std::uint32_t length = size;
    SerializeRaw(length, buffer);
  } else {
    // Invalid encoding for BIN type.
  }
}

// Serializes the type code for BufferWrapper types.
template <typename T>
inline void SerializeType(const BufferWrapper<T>& value, void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeBinEncoding(
      encoding, value.size() * sizeof(typename BufferWrapper<T>::value_type),
      buffer);
}

// Serializes the array encoding type and length.
inline void SerializeArrayEncoding(EncodingType encoding, std::size_t size,
                                   void*& buffer) {
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_ARRAY16) {
    std::uint16_t length = size;
    SerializeRaw(length, buffer);
  } else if (encoding == ENCODING_TYPE_ARRAY32) {
    std::uint32_t length = size;
    SerializeRaw(length, buffer);
  } else /* if (IsFixarrayEncoding(encoding) */ {
    // Encoding byte contains the fixarray length, nothing else to do.
  }
}

// Serializes the map encoding type and length.
inline void SerializeMapEncoding(EncodingType encoding, std::size_t size,
                                 void*& buffer) {
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_MAP16) {
    std::uint16_t length = size;
    SerializeRaw(length, buffer);
  } else if (encoding == ENCODING_TYPE_MAP32) {
    std::uint32_t length = size;
    SerializeRaw(length, buffer);
  } else /* if (IsFixmapEncoding(encoding) */ {
    // Encoding byte contains the fixmap length, nothing else to do.
  }
}

// Serializes the type code for array types.
template <typename ArrayType>
inline void SerializeArrayType(const ArrayType& value, std::size_t size,
                               void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeArrayEncoding(encoding, size, buffer);
}

// Serializes the type code for map types.
template <typename MapType>
inline void SerializeMapType(const MapType& value, std::size_t size,
                             void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeMapEncoding(encoding, size, buffer);
}

// Serializes the type code for std::vector and ArrayWrapper. These types are
// interchangeable and must serialize to the same format.
template <typename T, typename Allocator>
inline void SerializeType(const std::vector<T, Allocator>& value,
                          void*& buffer) {
  SerializeArrayType(value, value.size(), buffer);
}
template <typename T>
inline void SerializeType(const ArrayWrapper<T>& value, void*& buffer) {
  SerializeArrayType(value, value.size(), buffer);
}

// Serializes the type code for std::array. This type serializes to the same
// format as std::vector and ArrayWrapper and is interchangeable in certain
// situations.
template <typename T, std::size_t Size>
inline void SerializeType(const std::array<T, Size>& value, void*& buffer) {
  SerializeArrayType(value, Size, buffer);
}

// Serializes the type code for std::map types.
template <typename Key, typename T, typename Compare, typename Allocator>
inline void SerializeType(const std::map<Key, T, Compare, Allocator>& value,
                          void*& buffer) {
  SerializeMapType(value, value.size(), buffer);
}

// Serializes the type code for std::unordered_map types.
template <typename Key, typename T, typename Hash, typename KeyEqual,
          typename Allocator>
inline void SerializeType(
    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& value,
    void*& buffer) {
  SerializeMapType(value, value.size(), buffer);
}

// Serializes the type code for std::pair types.
template <typename T, typename U>
inline void SerializeType(const std::pair<T, U>& value, void*& buffer) {
  SerializeArrayType(value, 2, buffer);
}

// Serializes the type code for std::tuple types.
template <typename... T>
inline void SerializeType(const std::tuple<T...>& value, void*& buffer) {
  SerializeArrayType(value, sizeof...(T), buffer);
}

// Specialization of SerializeObject for boolean type.
inline void SerializeObject(const bool& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  SerializeType(value, buffer);
  // Encoding contains the boolean value, nothing else to do.
}

// Overloads of SerializeObject for float and double types.
inline void SerializeObject(const float& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  SerializeRaw(value, buffer);
}

inline void SerializeObject(const double& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  SerializeRaw(value, buffer);
}

// Overloads of SerializeObject() for standard integer types.
inline void SerializeObject(const char& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_UINT8) {
    SerializeRaw(value, buffer);
  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
    // Encoding byte contains the value, nothing else to do.
  }
}

inline void SerializeObject(const int8_t& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_INT8) {
    SerializeRaw(value, buffer);
  } else /* if (IsFixintEncoding(encoding) */ {
    // Encoding byte contains the value, nothing else to do.
  }
}

inline void SerializeObject(const uint8_t& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_UINT8) {
    SerializeRaw(value, buffer);
  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
    // Encoding byte contains the value, nothing else to do.
  }
}

inline void SerializeObject(const int16_t& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_INT8) {
    const int8_t byte = value;
    SerializeRaw(byte, buffer);
  } else if (encoding == ENCODING_TYPE_INT16) {
    SerializeRaw(value, buffer);
  } else /* if (IsFixintEncoding(encoding) */ {
    // Encoding byte contains the value, nothing else to do.
  }
}

inline void SerializeObject(const uint16_t& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_UINT8) {
    const uint8_t byte = value;
    SerializeRaw(byte, buffer);
  } else if (encoding == ENCODING_TYPE_UINT16) {
    SerializeRaw(value, buffer);
  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
    // Encoding byte contains the value, nothing else to do.
  }
}

inline void SerializeObject(const int32_t& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_INT8) {
    const int8_t byte = value;
    SerializeRaw(byte, buffer);
  } else if (encoding == ENCODING_TYPE_INT16) {
    const int16_t half = value;
    SerializeRaw(half, buffer);
  } else if (encoding == ENCODING_TYPE_INT32) {
    SerializeRaw(value, buffer);
  } else /* if (IsFixintEncoding(encoding) */ {
    // Encoding byte contains the value, nothing else to do.
  }
}

inline void SerializeObject(const uint32_t& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_UINT8) {
    const uint8_t byte = value;
    SerializeRaw(byte, buffer);
  } else if (encoding == ENCODING_TYPE_UINT16) {
    const uint16_t half = value;
    SerializeRaw(half, buffer);
  } else if (encoding == ENCODING_TYPE_UINT32) {
    SerializeRaw(value, buffer);
  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
    // Encoding byte contains the value, nothing else to do.
  }
}

inline void SerializeObject(const int64_t& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_INT8) {
    const int8_t byte = value;
    SerializeRaw(byte, buffer);
  } else if (encoding == ENCODING_TYPE_INT16) {
    const int16_t half = value;
    SerializeRaw(half, buffer);
  } else if (encoding == ENCODING_TYPE_INT32) {
    const int32_t word = value;
    SerializeRaw(word, buffer);
  } else if (encoding == ENCODING_TYPE_INT64) {
    SerializeRaw(value, buffer);
  } else /* if (IsFixintEncoding(encoding) */ {
    // Encoding byte contains the value, nothing else to do.
  }
}

inline void SerializeObject(const uint64_t& value, MessageWriter* /*writer*/,
                            void*& buffer) {
  const EncodingType encoding = EncodeType(value);
  SerializeEncoding(encoding, buffer);
  if (encoding == ENCODING_TYPE_UINT8) {
    const uint8_t byte = value;
    SerializeRaw(byte, buffer);
  } else if (encoding == ENCODING_TYPE_UINT16) {
    const uint16_t half = value;
    SerializeRaw(half, buffer);
  } else if (encoding == ENCODING_TYPE_UINT32) {
    const uint32_t word = value;
    SerializeRaw(word, buffer);
  } else if (encoding == ENCODING_TYPE_UINT64) {
    SerializeRaw(value, buffer);
  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
    // Encoding byte contains the value, nothing else to do.
  }
}

// Serialize enum types.
template <typename T>
inline EnableIfEnum<T> SerializeObject(const T& value, MessageWriter* writer,
                                       void*& buffer) {
  SerializeObject(static_cast<std::underlying_type_t<T>>(value), writer,
                  buffer);
}

// Forward declaration for nested definitions.
inline void SerializeObject(const EmptyVariant&, MessageWriter*, void*&);
template <typename... Types>
inline void SerializeObject(const Variant<Types...>&, MessageWriter*, void*&);
template <typename T, typename Enabled>
inline void SerializeObject(const T&, MessageWriter*, void*&);
template <typename T>
inline void SerializeObject(const PointerWrapper<T>&, MessageWriter*, void*&);
template <FileHandleMode Mode>
inline void SerializeObject(const FileHandle<Mode>&, MessageWriter*, void*&);
template <ChannelHandleMode Mode>
inline void SerializeObject(const ChannelHandle<Mode>&, MessageWriter*, void*&);
template <typename T, typename Allocator>
inline void SerializeObject(const BufferWrapper<std::vector<T, Allocator>>&, MessageWriter*, void*&);
template <typename T>
inline void SerializeObject(const BufferWrapper<T*>&, MessageWriter*, void*&);
inline void SerializeObject(const std::string&, MessageWriter*, void*&);
template <typename T>
inline void SerializeObject(const StringWrapper<T>&, MessageWriter*, void*&);
template <typename T, typename Allocator>
inline void SerializeObject(const std::vector<T, Allocator>&, MessageWriter*, void*&);
template <typename T>
inline void SerializeObject(const ArrayWrapper<T>&, MessageWriter*, void*&);
template <typename T, std::size_t Size>
inline void SerializeObject(const std::array<T, Size>&, MessageWriter*, void*&);
template <typename Key, typename T, typename Compare, typename Allocator>
inline void SerializeObject(const std::map<Key, T, Compare, Allocator>&, MessageWriter*, void*&);
template <typename Key, typename T, typename Hash, typename KeyEqual,
          typename Allocator>
inline void SerializeObject(
    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>&, MessageWriter*, void*&);
template <typename T, typename U>
inline void SerializeObject(const std::pair<T, U>&, MessageWriter*, void*&);
template <typename... T>
inline void SerializeObject(const std::tuple<T...>&, MessageWriter*, void*&);

// Overload for empty variant type.
inline void SerializeObject(const EmptyVariant& empty,
                            MessageWriter* /*writer*/, void*& buffer) {
  const EncodingType encoding = EncodeType(empty);
  SerializeEncoding(encoding, buffer);
}

// Overload for Variant types.
template <typename... Types>
inline void SerializeObject(const Variant<Types...>& variant,
                            MessageWriter* writer, void*& buffer) {
  SerializeType(variant, buffer);
  SerializeObject(variant.index(), writer, buffer);
  return variant.Visit([writer, &buffer](const auto& value) {
    return SerializeObject(value, writer, buffer);
  });
}

// Overload for serializable structure/class types.
template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
inline void SerializeObject(const T& value, MessageWriter* writer,
                            void*& buffer) {
  SerializableTraits<T>::SerializeObject(value, writer, buffer);
}

// Serializes the payload of a PointerWrapper.
template <typename T>
inline void SerializeObject(const PointerWrapper<T>& pointer,
                            MessageWriter* writer, void*& buffer) {
  SerializeObject(pointer.Dereference(), writer, buffer);
}

// Serializes the payload of file descriptor types.
template <FileHandleMode Mode>
inline void SerializeObject(const FileHandle<Mode>& fd, MessageWriter* writer,
                            void*& buffer) {
  SerializeType(fd, buffer);
  const FileReference value =
      writer->GetOutputResourceMapper()->PushFileHandle(fd);
  SerializeRaw(value, buffer);
}

// Serializes the payload of channel handle types.
template <ChannelHandleMode Mode>
inline void SerializeObject(const ChannelHandle<Mode>& handle,
                            MessageWriter* writer, void*& buffer) {
  SerializeType(handle, buffer);
  const ChannelReference value =
      writer->GetOutputResourceMapper()->PushChannelHandle(handle);
  SerializeRaw(value, buffer);
}

// Serializes the payload of BufferWrapper types.
template <typename T, typename Allocator>
inline void SerializeObject(const BufferWrapper<std::vector<T, Allocator>>& b,
                            MessageWriter* /*writer*/, void*& buffer) {
  const auto value_type_size =
      sizeof(typename BufferWrapper<std::vector<T, Allocator>>::value_type);
  SerializeType(b, buffer);
  WriteRawData(buffer, b.data(), b.size() * value_type_size);
}
template <typename T>
inline void SerializeObject(const BufferWrapper<T*>& b,
                            MessageWriter* /*writer*/, void*& buffer) {
  const auto value_type_size = sizeof(typename BufferWrapper<T*>::value_type);
  SerializeType(b, buffer);
  WriteRawData(buffer, b.data(), b.size() * value_type_size);
}

// Serializes the payload of string types.
template <typename StringType>
inline void SerializeString(const StringType& s, void*& buffer) {
  const auto value_type_size = sizeof(typename StringType::value_type);
  SerializeType(s, buffer);
  WriteRawData(buffer, s.data(), s.length() * value_type_size);
}

// Overload of SerializeObject() for std::string and StringWrapper. These types
// are interchangeable and must serialize to the same format.
inline void SerializeObject(const std::string& s, MessageWriter* /*writer*/,
                            void*& buffer) {
  SerializeString(s, buffer);
}
template <typename T>
inline void SerializeObject(const StringWrapper<T>& s,
                            MessageWriter* /*writer*/, void*& buffer) {
  SerializeString(s, buffer);
}

// Serializes the payload of array types.
template <typename ArrayType>
inline void SerializeArray(const ArrayType& v, MessageWriter* writer,
                           void*& buffer) {
  SerializeType(v, buffer);
  for (const auto& element : v)
    SerializeObject(element, writer, buffer);
}

// Serializes the payload for map types.
template <typename MapType>
inline void SerializeMap(const MapType& v, MessageWriter* writer,
                         void*& buffer) {
  SerializeType(v, buffer);
  for (const auto& element : v) {
    SerializeObject(element.first, writer, buffer);
    SerializeObject(element.second, writer, buffer);
  }
}

// Overload of SerializeObject() for std::vector and ArrayWrapper types. These
// types are interchangeable and must serialize to the same format.
template <typename T, typename Allocator>
inline void SerializeObject(const std::vector<T, Allocator>& v,
                            MessageWriter* writer, void*& buffer) {
  SerializeArray(v, writer, buffer);
}
template <typename T>
inline void SerializeObject(const ArrayWrapper<T>& v, MessageWriter* writer,
                            void*& buffer) {
  SerializeArray(v, writer, buffer);
}

// Overload of SerializeObject() for std::array types. These types serialize to
// the same format at std::vector and ArrayWrapper and are interchangeable in
// certain situations.
template <typename T, std::size_t Size>
inline void SerializeObject(const std::array<T, Size>& v, MessageWriter* writer,
                            void*& buffer) {
  SerializeArray(v, writer, buffer);
}

// Overload of SerializeObject() for std::map types.
template <typename Key, typename T, typename Compare, typename Allocator>
inline void SerializeObject(const std::map<Key, T, Compare, Allocator>& v,
                            MessageWriter* writer, void*& buffer) {
  SerializeMap(v, writer, buffer);
}

// Overload of SerializeObject() for std::unordered_map types.
template <typename Key, typename T, typename Hash, typename KeyEqual,
          typename Allocator>
inline void SerializeObject(
    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& v,
    MessageWriter* writer, void*& buffer) {
  SerializeMap(v, writer, buffer);
}

// Overload of SerializeObject() for std:pair types.
template <typename T, typename U>
inline void SerializeObject(const std::pair<T, U>& pair, MessageWriter* writer,
                            void*& buffer) {
  SerializeType(pair, buffer);
  SerializeObject(pair.first, writer, buffer);
  SerializeObject(pair.second, writer, buffer);
}

// Stops template recursion when the last tuple element is reached.
template <typename... T>
inline void SerializeTuple(const std::tuple<T...>&, MessageWriter*, void*&,
                           Index<0>) {}

// Serializes each element of a tuple recursively.
template <typename... T, std::size_t index>
inline void SerializeTuple(const std::tuple<T...>& tuple, MessageWriter* writer,
                           void*& buffer, Index<index>) {
  SerializeTuple(tuple, writer, buffer, Index<index - 1>());
  SerializeObject(std::get<index - 1>(tuple), writer, buffer);
}

// Overload of SerializeObject() for tuple types.
template <typename... T>
inline void SerializeObject(const std::tuple<T...>& tuple,
                            MessageWriter* writer, void*& buffer) {
  SerializeType(tuple, buffer);
  SerializeTuple(tuple, writer, buffer, Index<sizeof...(T)>());
}

// Stops template recursion when the last member pointer is reached.
template <typename Members, typename T>
inline void SerializeMember(const T&, MessageWriter*, void*&, Index<0>) {}

// Serializes each member pointer recursively.
template <typename Members, typename T, std::size_t index>
inline void SerializeMember(const T& object, MessageWriter* writer,
                            void*& buffer, Index<index>) {
  SerializeMember<Members>(object, writer, buffer, Index<index - 1>());
  SerializeObject(Members::template At<index - 1>::Resolve(object), writer,
                  buffer);
}

// Serializes the members of a type using the given SerializableMembersType
// type.
template <typename Members, typename T>
inline void SerializeMembers(const T& object, MessageWriter* writer,
                             void*& buffer) {
  SerializeMember<Members>(object, writer, buffer,
                           Index<Members::MemberCount>());
}

// Top level serialization function that replaces the buffer's contents.
template <typename T>
inline void Serialize(const T& object, MessageWriter* writer) {
  PDX_TRACE_NAME("Serialize");
  const std::size_t size = GetSerializedSize(object);

  // Reserve the space needed for the object(s).
  void* buffer = writer->GetNextWriteBufferSection(size);
  SerializeObject(object, writer, buffer);
}

///////////////////////////////////////////////////////////////////////////////
// Object Deserialization //
///////////////////////////////////////////////////////////////////////////////

inline ErrorType ReadRawDataFromNextSection(void* dest, MessageReader* reader,
                                            const void*& start,
                                            const void*& end, size_t size) {
  while (AdvancePointer(start, size) > end) {
    auto remaining_size = PointerDistance(end, start);
    if (remaining_size > 0) {
      memcpy(dest, start, remaining_size);
      dest = AdvancePointer(dest, remaining_size);
      size -= remaining_size;
    }
    reader->ConsumeReadBufferSectionData(AdvancePointer(start, remaining_size));
    std::tie(start, end) = reader->GetNextReadBufferSection();
    if (start == end)
      return ErrorCode::INSUFFICIENT_BUFFER;
  }
  memcpy(dest, start, size);
  start = AdvancePointer(start, size);
  return ErrorCode::NO_ERROR;
}

inline ErrorType ReadRawData(void* dest, MessageReader* /*reader*/,
                             const void*& start, const void*& end,
                             size_t size) {
  if (PDX_UNLIKELY(AdvancePointer(start, size) > end)) {
    // TODO(avakulenko): Enabling reading from next sections of input buffer
    // (using ReadRawDataFromNextSection) screws up clang compiler optimizations
    // (probably inefficient inlining) making the whole deserialization
    // code path about twice as slow. Investigate and enable more generic
    // deserialization code, but right now we don't really need/support this
    // scenario, so I keep this commented out for the time being...

    // return ReadRawDataFromNextSection(dest, reader, start, end, size);
    return ErrorCode::INSUFFICIENT_BUFFER;
  }
  memcpy(dest, start, size);
  start = AdvancePointer(start, size);
  return ErrorCode::NO_ERROR;
}

// Deserializes a primitive object from raw bytes.
template <typename T,
          typename = typename std::enable_if<std::is_pod<T>::value>::type>
inline ErrorType DeserializeRaw(T* value, MessageReader* reader,
                                const void*& start, const void*& end) {
  return ReadRawData(value, reader, start, end, sizeof(T));
}

// Utility to deserialize POD types when the serialized type is different
// (smaller) than the target real type. This happens when values are serialized
// into more compact encodings.
template <typename SerializedType, typename RealType>
ErrorType DeserializeValue(RealType* real_value, MessageReader* reader,
                           const void*& start, const void*& end) {
  SerializedType serialized_value;
  if (const auto error =
          DeserializeRaw(&serialized_value, reader, start, end)) {
    return error;
  } else {
    *real_value = serialized_value;
    return ErrorCode::NO_ERROR;
  }
}

inline ErrorType DeserializeEncoding(EncodingType* encoding,
                                     MessageReader* reader, const void*& start,
                                     const void*& end) {
  return DeserializeRaw(encoding, reader, start, end);
}

// Overload to deserialize bool type.
inline ErrorType DeserializeObject(bool* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsBoolEncoding(encoding)) {
    *value = (encoding == ENCODING_TYPE_TRUE);
    return ErrorCode::NO_ERROR;
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_BOOL,
                     encoding);
  }
}

// Specializations to deserialize float and double types.
inline ErrorType DeserializeObject(float* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsFloat32Encoding(encoding)) {
    return DeserializeValue<float>(value, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_FLOAT,
                     encoding);
  }
}

inline ErrorType DeserializeObject(double* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsFloat32Encoding(encoding)) {
    return DeserializeValue<float>(value, reader, start, end);
  } else if (IsFloat64Encoding(encoding)) {
    return DeserializeValue<double>(value, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_FLOAT,
                     encoding);
  }
}

// Specializations to deserialize standard integer types.
inline ErrorType DeserializeObject(char* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsUnsignedFixintEncoding(encoding)) {
    *value = static_cast<char>(encoding);
    return ErrorCode::NO_ERROR;
  } else if (IsUInt8Encoding(encoding)) {
    return DeserializeValue<char>(value, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
                     encoding);
  }
}

inline ErrorType DeserializeObject(std::int8_t* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsFixintEncoding(encoding)) {
    *value = static_cast<std::int8_t>(encoding);
    return ErrorCode::NO_ERROR;
  } else if (IsInt8Encoding(encoding)) {
    return DeserializeValue<std::int8_t>(value, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
                     encoding);
  }
}

inline ErrorType DeserializeObject(std::uint8_t* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsUnsignedFixintEncoding(encoding)) {
    *value = encoding;
    return ErrorCode::NO_ERROR;
  } else if (IsUInt8Encoding(encoding)) {
    return DeserializeValue<std::uint8_t>(value, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
                     encoding);
  }
}

inline ErrorType DeserializeObject(std::int16_t* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsFixintEncoding(encoding)) {
    *value = static_cast<std::int8_t>(encoding);
    return ErrorCode::NO_ERROR;
  } else if (IsInt8Encoding(encoding)) {
    return DeserializeValue<std::int8_t>(value, reader, start, end);
  } else if (IsInt16Encoding(encoding)) {
    return DeserializeValue<std::int16_t>(value, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
                     encoding);
  }
}

inline ErrorType DeserializeObject(std::uint16_t* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsUnsignedFixintEncoding(encoding)) {
    *value = encoding;
    return ErrorCode::NO_ERROR;
  } else if (IsUInt8Encoding(encoding)) {
    return DeserializeValue<std::uint8_t>(value, reader, start, end);
  } else if (IsUInt16Encoding(encoding)) {
    return DeserializeValue<std::uint16_t>(value, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
                     encoding);
  }
}

inline ErrorType DeserializeObject(std::int32_t* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsFixintEncoding(encoding)) {
    *value = static_cast<std::int8_t>(encoding);
    return ErrorCode::NO_ERROR;
  } else if (IsInt8Encoding(encoding)) {
    return DeserializeValue<std::int8_t>(value, reader, start, end);
  } else if (IsInt16Encoding(encoding)) {
    return DeserializeValue<std::int16_t>(value, reader, start, end);
  } else if (IsInt32Encoding(encoding)) {
    return DeserializeValue<std::int32_t>(value, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
                     encoding);
  }
}

inline ErrorType DeserializeObject(std::uint32_t* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsUnsignedFixintEncoding(encoding)) {
    *value = encoding;
    return ErrorCode::NO_ERROR;
  } else if (IsUInt8Encoding(encoding)) {
    return DeserializeValue<std::uint8_t>(value, reader, start, end);
  } else if (IsUInt16Encoding(encoding)) {
    return DeserializeValue<std::uint16_t>(value, reader, start, end);
  } else if (IsUInt32Encoding(encoding)) {
    return DeserializeValue<std::uint32_t>(value, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
                     encoding);
  }
}

inline ErrorType DeserializeObject(std::int64_t* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsFixintEncoding(encoding)) {
    *value = static_cast<std::int8_t>(encoding);
    return ErrorCode::NO_ERROR;
  } else if (IsInt8Encoding(encoding)) {
    return DeserializeValue<std::int8_t>(value, reader, start, end);
  } else if (IsInt16Encoding(encoding)) {
    return DeserializeValue<std::int16_t>(value, reader, start, end);
  } else if (IsInt32Encoding(encoding)) {
    return DeserializeValue<std::int32_t>(value, reader, start, end);
  } else if (IsInt64Encoding(encoding)) {
    return DeserializeValue<std::int64_t>(value, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
                     encoding);
  }
}

inline ErrorType DeserializeObject(std::uint64_t* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (IsUnsignedFixintEncoding(encoding)) {
    *value = encoding;
    return ErrorCode::NO_ERROR;
  } else if (IsUInt8Encoding(encoding)) {
    return DeserializeValue<std::uint8_t>(value, reader, start, end);
  } else if (IsUInt16Encoding(encoding)) {
    return DeserializeValue<std::uint16_t>(value, reader, start, end);
  } else if (IsUInt32Encoding(encoding)) {
    return DeserializeValue<std::uint32_t>(value, reader, start, end);
  } else if (IsUInt64Encoding(encoding)) {
    return DeserializeValue<std::uint64_t>(value, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
                     encoding);
  }
}

template <typename T>
inline EnableIfEnum<T, ErrorType> DeserializeObject(T* value,
                                                    MessageReader* reader,
                                                    const void*& start,
                                                    const void*& end) {
  std::underlying_type_t<T> enum_value;
  ErrorType error = DeserializeObject(&enum_value, reader, start, end);
  if (!error)
    *value = static_cast<T>(enum_value);
  return error;
}

// Forward declarations for nested definitions.
template <typename T, typename Enabled>
inline ErrorType DeserializeObject(T*, MessageReader*, const void*&,
                                   const void*&);
template <typename T>
inline ErrorType DeserializeObject(PointerWrapper<T>*, MessageReader*,
                                   const void*&, const void*&);
inline ErrorType DeserializeObject(LocalHandle*, MessageReader*, const void*&,
                                   const void*&);
inline ErrorType DeserializeObject(LocalChannelHandle*, MessageReader*,
                                   const void*&, const void*&);
template <typename T, typename Allocator>
inline ErrorType DeserializeObject(BufferWrapper<std::vector<T, Allocator>>*,
                                   MessageReader*, const void*&, const void*&);
template <typename T>
inline ErrorType DeserializeObject(BufferWrapper<T*>*, MessageReader*,
                                   const void*&, const void*&);
inline ErrorType DeserializeObject(std::string*, MessageReader*, const void*&,
                                   const void*&);
template <typename T>
inline ErrorType DeserializeObject(StringWrapper<T>*, MessageReader*,
                                   const void*&, const void*&);
template <typename T, typename U>
inline ErrorType DeserializeObject(std::pair<T, U>*, MessageReader*,
                                   const void*&, const void*&);
template <typename... T>
inline ErrorType DeserializeObject(std::tuple<T...>*, MessageReader*,
                                   const void*&, const void*&);
template <typename T, typename Allocator>
inline ErrorType DeserializeObject(std::vector<T, Allocator>*, MessageReader*,
                                   const void*&, const void*&);
template <typename Key, typename T, typename Compare, typename Allocator>
inline ErrorType DeserializeObject(std::map<Key, T, Compare, Allocator>*,
                                   MessageReader*, const void*&, const void*&);
template <typename Key, typename T, typename Hash, typename KeyEqual,
          typename Allocator>
inline ErrorType DeserializeObject(
    std::unordered_map<Key, T, Hash, KeyEqual, Allocator>*, MessageReader*,
    const void*&, const void*&);
template <typename T>
inline ErrorType DeserializeObject(ArrayWrapper<T>*, MessageReader*,
                                   const void*&, const void*&);
template <typename T, std::size_t Size>
inline ErrorType DeserializeObject(std::array<T, Size>*, MessageReader*,
                                   const void*&, const void*&);
template <typename T, typename U>
inline ErrorType DeserializeObject(std::pair<T, U>*, MessageReader*,
                                   const void*&, const void*&);
template <typename... T>
inline ErrorType DeserializeObject(std::tuple<T...>*, MessageReader*,
                                   const void*&, const void*&);
inline ErrorType DeserializeObject(EmptyVariant*,
                                   MessageReader*, const void*&,
                                   const void*&);
template <typename... Types>
inline ErrorType DeserializeObject(Variant<Types...>*,
                                   MessageReader*, const void*&,
                                   const void*&);

// Deserializes a Serializable type.
template <typename T, typename Enable = EnableIfHasSerializableMembers<T>>
inline ErrorType DeserializeObject(T* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  return SerializableTraits<T>::DeserializeObject(value, reader, start, end);
}

// Deserializes a PointerWrapper.
template <typename T>
inline ErrorType DeserializeObject(PointerWrapper<T>* pointer,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  return DeserializeObject(&pointer->Dereference(), reader, start, end);
}

// Deserializes the type code and size for extension types.
inline ErrorType DeserializeExtType(EncodingType* encoding,
                                    EncodingExtType* type, std::size_t* size,
                                    MessageReader* reader, const void*& start,
                                    const void*& end) {
  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
    return error;
  } else if (IsFixextEncoding(*encoding)) {
    *size = GetFixextSize(*encoding);
  } else if (*encoding == ENCODING_TYPE_EXT8) {
    if (const auto error =
            DeserializeValue<std::uint8_t>(size, reader, start, end))
      return error;
  } else if (*encoding == ENCODING_TYPE_EXT16) {
    if (const auto error =
            DeserializeValue<std::uint16_t>(size, reader, start, end))
      return error;
  } else if (*encoding == ENCODING_TYPE_EXT32) {
    if (const auto error =
            DeserializeValue<std::uint32_t>(size, reader, start, end))
      return error;
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
                     *encoding);
  }

  // The extension type code follows the encoding and size.
  return DeserializeRaw(type, reader, start, end);
}

// Deserializes a file handle and performs handle space translation, if
// required.
inline ErrorType DeserializeObject(LocalHandle* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  EncodingExtType type;
  std::size_t size;

  if (const auto error =
          DeserializeExtType(&encoding, &type, &size, reader, start, end)) {
    return error;
  } else if (size != 2) {
    return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_EXTENSION,
                     encoding);
  } else if (type == ENCODING_EXT_TYPE_FILE_DESCRIPTOR) {
    // Read the encoded file descriptor value.
    FileReference ref;
    if (const auto error = DeserializeRaw(&ref, reader, start, end)) {
      return error;
    }

    return reader->GetInputResourceMapper()->GetFileHandle(ref, value)
               ? ErrorCode::NO_ERROR
               : ErrorCode::GET_FILE_DESCRIPTOR_FAILED;
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
                     encoding);
  }
}

inline ErrorType DeserializeObject(LocalChannelHandle* value,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  EncodingType encoding;
  EncodingExtType type;
  std::size_t size;

  if (const auto error =
          DeserializeExtType(&encoding, &type, &size, reader, start, end)) {
    return error;
  } else if (size != 4) {
    return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_EXTENSION,
                     encoding);
  } else if (type == ENCODING_EXT_TYPE_CHANNEL_HANDLE) {
    // Read the encoded channel handle value.
    ChannelReference ref;
    if (const auto error = DeserializeRaw(&ref, reader, start, end)) {
      return error;
    }
    return reader->GetInputResourceMapper()->GetChannelHandle(ref, value)
               ? ErrorCode::NO_ERROR
               : ErrorCode::GET_CHANNEL_HANDLE_FAILED;
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
                     encoding);
  }
}

// Deserializes the type code and size for bin types.
inline ErrorType DeserializeBinType(EncodingType* encoding, std::size_t* size,
                                    MessageReader* reader, const void*& start,
                                    const void*& end) {
  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
    return error;
  } else if (*encoding == ENCODING_TYPE_BIN8) {
    return DeserializeValue<std::uint8_t>(size, reader, start, end);
  } else if (*encoding == ENCODING_TYPE_BIN16) {
    return DeserializeValue<std::uint16_t>(size, reader, start, end);
  } else if (*encoding == ENCODING_TYPE_BIN32) {
    return DeserializeValue<std::uint32_t>(size, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_BINARY,
                     *encoding);
  }
}

// Overload of DeserializeObject() for BufferWrapper types.
template <typename T, typename Allocator>
inline ErrorType DeserializeObject(
    BufferWrapper<std::vector<T, Allocator>>* value, MessageReader* reader,
    const void*& start, const void*& end) {
  const auto value_type_size =
      sizeof(typename BufferWrapper<std::vector<T, Allocator>>::value_type);
  EncodingType encoding;
  std::size_t size;

  if (const auto error =
          DeserializeBinType(&encoding, &size, reader, start, end))
    return error;

  // Try to resize the BufferWrapper to the size of the payload.
  value->resize(size / value_type_size);

  if (size > value->size() * value_type_size || size % value_type_size != 0) {
    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
  } else if (size == 0U) {
    return ErrorCode::NO_ERROR;
  } else {
    return ReadRawData(value->data(), reader, start, end, size);
  }
}
template <typename T>
inline ErrorType DeserializeObject(BufferWrapper<T*>* value,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  const auto value_type_size = sizeof(typename BufferWrapper<T*>::value_type);
  EncodingType encoding;
  std::size_t size;

  if (const auto error =
          DeserializeBinType(&encoding, &size, reader, start, end))
    return error;

  // Try to resize the BufferWrapper to the size of the payload.
  value->resize(size / value_type_size);

  if (size > value->size() * value_type_size || size % value_type_size != 0) {
    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
  } else if (size == 0U) {
    return ErrorCode::NO_ERROR;
  } else {
    return ReadRawData(value->data(), reader, start, end, size);
  }
}

// Deserializes the type code and size for string types.
inline ErrorType DeserializeStringType(EncodingType* encoding,
                                       std::size_t* size, MessageReader* reader,
                                       const void*& start, const void*& end) {
  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
    return error;
  } else if (IsFixstrEncoding(*encoding)) {
    *size = GetFixstrSize(*encoding);
    return ErrorCode::NO_ERROR;
  } else if (*encoding == ENCODING_TYPE_STR8) {
    return DeserializeValue<std::uint8_t>(size, reader, start, end);
  } else if (*encoding == ENCODING_TYPE_STR16) {
    return DeserializeValue<std::uint16_t>(size, reader, start, end);
  } else if (*encoding == ENCODING_TYPE_STR32) {
    return DeserializeValue<std::uint32_t>(size, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_STRING,
                     *encoding);
  }
}

// Overload of DeserializeObject() for std::string types.
inline ErrorType DeserializeObject(std::string* value, MessageReader* reader,
                                   const void*& start, const void*& end) {
  EncodingType encoding;
  std::size_t size;

  if (const auto error =
          DeserializeStringType(&encoding, &size, reader, start, end)) {
    return error;
  } else if (size == 0U) {
    value->clear();
    return ErrorCode::NO_ERROR;
  } else {
    value->resize(size);
    return ReadRawData(&(*value)[0], reader, start, end, size);
  }
}

// Overload of DeserializeObject() for StringWrapper types.
template <typename T>
inline ErrorType DeserializeObject(StringWrapper<T>* value,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  const auto value_type_size = sizeof(typename StringWrapper<T>::value_type);
  EncodingType encoding;
  std::size_t size;

  if (const auto error =
          DeserializeStringType(&encoding, &size, reader, start, end))
    return error;

  // Try to resize the StringWrapper to the size of the payload
  // string.
  value->resize(size / value_type_size);

  if (size > value->length() * value_type_size || size % value_type_size != 0) {
    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
  } else if (size == 0U) {
    return ErrorCode::NO_ERROR;
  } else {
    return ReadRawData(value->data(), reader, start, end, size);
  }
}

// Deserializes the type code and size of array types.
inline ErrorType DeserializeArrayType(EncodingType* encoding, std::size_t* size,
                                      MessageReader* reader, const void*& start,
                                      const void*& end) {
  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
    return error;
  } else if (IsFixarrayEncoding(*encoding)) {
    *size = GetFixarraySize(*encoding);
    return ErrorCode::NO_ERROR;
  } else if (*encoding == ENCODING_TYPE_ARRAY16) {
    return DeserializeValue<std::uint16_t>(size, reader, start, end);
  } else if (*encoding == ENCODING_TYPE_ARRAY32) {
    return DeserializeValue<std::uint32_t>(size, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_ARRAY,
                     *encoding);
  }
}

// Deserializes the type code and size of map types.
inline ErrorType DeserializeMapType(EncodingType* encoding, std::size_t* size,
                                    MessageReader* reader, const void*& start,
                                    const void*& end) {
  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
    return error;
  } else if (IsFixmapEncoding(*encoding)) {
    *size = GetFixmapSize(*encoding);
    return ErrorCode::NO_ERROR;
  } else if (*encoding == ENCODING_TYPE_MAP16) {
    return DeserializeValue<std::uint16_t>(size, reader, start, end);
  } else if (*encoding == ENCODING_TYPE_MAP32) {
    return DeserializeValue<std::uint32_t>(size, reader, start, end);
  } else {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_MAP,
                     *encoding);
  }
}

// Overload for std::vector types.
template <typename T, typename Allocator>
inline ErrorType DeserializeObject(std::vector<T, Allocator>* value,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  EncodingType encoding;
  std::size_t size;

  if (const auto error =
          DeserializeArrayType(&encoding, &size, reader, start, end))
    return error;

  std::vector<T, Allocator> result(size);
  for (std::size_t i = 0; i < size; i++) {
    if (const auto error = DeserializeObject(&result[i], reader, start, end))
      return error;
  }

  *value = std::move(result);
  return ErrorCode::NO_ERROR;

// TODO(eieio): Consider the benefits and trade offs of this alternative.
#if 0
  value->resize(size);
  for (std::size_t i = 0; i < size; i++) {
    if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
      return error;
  }
  return ErrorCode::NO_ERROR;
#endif
}

// Deserializes an EmptyVariant value.
inline ErrorType DeserializeObject(EmptyVariant* /*empty*/,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  EncodingType encoding;

  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
    return error;
  } else if (encoding != ENCODING_TYPE_NIL) {
    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_MAP,
                     encoding);
  } else {
    return ErrorCode::NO_ERROR;
  }
}

// Deserializes a Variant type.
template <typename... Types>
inline ErrorType DeserializeObject(Variant<Types...>* variant,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  EncodingType encoding;
  std::size_t size;

  if (const auto error =
          DeserializeMapType(&encoding, &size, reader, start, end)) {
    return error;
  }

  if (size != 1)
    return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_MAP,
                     encoding);

  std::int32_t type;
  if (const auto error = DeserializeObject(&type, reader, start, end)) {
    return error;
  } else if (type < Variant<Types...>::kEmptyIndex ||
             type >= static_cast<std::int32_t>(sizeof...(Types))) {
    return ErrorCode::INVALID_VARIANT_ELEMENT;
  } else {
    variant->Become(type);
    return variant->Visit([reader, &start, &end](auto&& value) {
      return DeserializeObject(&value, reader, start, end);
    });
  }
}

// Deserializes map types.
template <typename MapType>
inline ErrorType DeserializeMap(MapType* value, MessageReader* reader,
                                const void*& start, const void*& end) {
  EncodingType encoding;
  std::size_t size;

  if (const auto error =
          DeserializeMapType(&encoding, &size, reader, start, end))
    return error;

  MapType result;
  for (std::size_t i = 0; i < size; i++) {
    std::pair<typename MapType::key_type, typename MapType::mapped_type>
        element;
    if (const auto error =
            DeserializeObject(&element.first, reader, start, end))
      return error;
    if (const auto error =
            DeserializeObject(&element.second, reader, start, end))
      return error;
    result.emplace(std::move(element));
  }

  *value = std::move(result);
  return ErrorCode::NO_ERROR;
}

// Overload for std::map types.
template <typename Key, typename T, typename Compare, typename Allocator>
inline ErrorType DeserializeObject(std::map<Key, T, Compare, Allocator>* value,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  return DeserializeMap(value, reader, start, end);
}

// Overload for std::unordered_map types.
template <typename Key, typename T, typename Hash, typename KeyEqual,
          typename Allocator>
inline ErrorType DeserializeObject(
    std::unordered_map<Key, T, Hash, KeyEqual, Allocator>* value,
    MessageReader* reader, const void*& start, const void*& end) {
  return DeserializeMap(value, reader, start, end);
}

// Overload for ArrayWrapper types.
template <typename T>
inline ErrorType DeserializeObject(ArrayWrapper<T>* value,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  EncodingType encoding;
  std::size_t size;

  if (const auto error =
          DeserializeArrayType(&encoding, &size, reader, start, end)) {
    return error;
  }

  // Try to resize the wrapper.
  value->resize(size);

  // Make sure there is enough space in the ArrayWrapper for the
  // payload.
  if (size > value->capacity())
    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;

  for (std::size_t i = 0; i < size; i++) {
    if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
      return error;
  }

  return ErrorCode::NO_ERROR;
}

// Overload for std::array types.
template <typename T, std::size_t Size>
inline ErrorType DeserializeObject(std::array<T, Size>* value,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  EncodingType encoding;
  std::size_t size;

  if (const auto error =
          DeserializeArrayType(&encoding, &size, reader, start, end)) {
    return error;
  }

  if (size != Size)
    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;

  for (std::size_t i = 0; i < size; i++) {
    if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
      return error;
  }

  return ErrorCode::NO_ERROR;
}

// Deserializes std::pair types.
template <typename T, typename U>
inline ErrorType DeserializeObject(std::pair<T, U>* value,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  EncodingType encoding;
  std::size_t size;

  if (const auto error =
          DeserializeArrayType(&encoding, &size, reader, start, end)) {
    return error;
  } else if (size != 2) {
    return ErrorCode::UNEXPECTED_TYPE_SIZE;
  } else if (const auto error =
                 DeserializeObject(&value->first, reader, start, end)) {
    return error;
  } else if (const auto error =
                 DeserializeObject(&value->second, reader, start, end)) {
    return error;
  } else {
    return ErrorCode::NO_ERROR;
  }
}

// Stops template recursion when the last tuple element is reached.
template <typename... T>
inline ErrorType DeserializeTuple(std::tuple<T...>*, MessageReader*,
                                  const void*&, const void*, Index<0>) {
  return ErrorCode::NO_ERROR;
}

// Deserializes each element of a tuple recursively.
template <typename... T, std::size_t index>
inline ErrorType DeserializeTuple(std::tuple<T...>* tuple,
                                  MessageReader* reader, const void*& start,
                                  const void*& end, Index<index>) {
  if (const auto error =
          DeserializeTuple(tuple, reader, start, end, Index<index - 1>()))
    return error;
  else
    return DeserializeObject(&std::get<index - 1>(*tuple), reader, start, end);
}

// Overload for standard tuple types.
template <typename... T>
inline ErrorType DeserializeObject(std::tuple<T...>* value,
                                   MessageReader* reader, const void*& start,
                                   const void*& end) {
  EncodingType encoding;
  std::size_t size;

  if (const auto error =
          DeserializeArrayType(&encoding, &size, reader, start, end)) {
    return error;
  } else if (size != sizeof...(T)) {
    return ErrorCode::UNEXPECTED_TYPE_SIZE;
  } else {
    return DeserializeTuple(value, reader, start, end, Index<sizeof...(T)>());
  }
}

// Stops template recursion when the last member of a Serializable type is
// reached.
template <typename Members, typename T>
inline ErrorType DeserializeMember(T*, MessageReader*, const void*&,
                                   const void*, Index<0>) {
  return ErrorCode::NO_ERROR;
}

// Deserializes each member of a Serializable type recursively.
template <typename Members, typename T, std::size_t index>
inline ErrorType DeserializeMember(T* value, MessageReader* reader,
                                   const void*& start, const void*& end,
                                   Index<index>) {
  if (const auto error = DeserializeMember<Members>(value, reader, start, end,
                                                    Index<index - 1>()))
    return error;
  else
    return DeserializeObject(&Members::template At<index - 1>::Resolve(*value),
                             reader, start, end);
}

// Deserializes the members of a Serializable type using the given
// SerializableMembersType type.
template <typename Members, typename T>
inline ErrorType DeserializeMembers(T* value, MessageReader* reader,
                                    const void*& start, const void*& end) {
  return DeserializeMember<Members>(value, reader, start, end,
                                    Index<Members::MemberCount>());
}

// Top level deserialization function.
template <typename T>
inline ErrorType Deserialize(T* value, MessageReader* reader) {
  PDX_TRACE_NAME("Deserialize");
  MessageReader::BufferSection section = reader->GetNextReadBufferSection();
  if (section.first == section.second)
    return ErrorCode::INSUFFICIENT_BUFFER;
  ErrorType error =
      DeserializeObject(value, reader, section.first, section.second);
  reader->ConsumeReadBufferSectionData(section.first);
  return error;
}

}  // namespace rpc
}  // namespace pdx
}  // namespace android

#endif  // ANDROID_PDX_RPC_SERIALIZATION_H_
