// WARNING: This file is machine generated by fidlgen.

// fidl_experiment = output_index_json

#pragma once

#include <lib/fidl/cpp/wire/array.h>
#include <lib/fidl/cpp/wire/envelope.h>
#include <lib/fidl/cpp/wire/internal/framework_err.h>
#include <lib/fidl/cpp/wire/message.h>
#include <lib/fidl/cpp/wire/message_storage.h>
#include <lib/fidl/cpp/wire/object_view.h>
#include <lib/fidl/cpp/wire/string_view.h>
#include <lib/fidl/cpp/wire/traits.h>
#include <lib/fidl/cpp/wire/wire_types.h>
#include <lib/stdcompat/optional.h>

#include <cinttypes>
#ifdef __Fuchsia__
#include <lib/zx/channel.h>

#endif  // __Fuchsia__

#include <fidl/test.emptystruct/cpp/common_types.h>
#include <fidl/test.emptystruct/cpp/markers.h>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_emptystruct {

namespace wire {

struct Empty;

struct EmptyProtocolSendRequest;

struct EmptyProtocolReceiveRequest;

struct EmptyProtocolSendAndReceiveRequest;

struct EmptyProtocolSendAndReceiveResponse;

struct Empty {
  uint8_t __reserved = {};
};

struct EmptyProtocolSendRequest {
  ::test_emptystruct::wire::Empty e = {};
};

struct EmptyProtocolReceiveRequest {
  ::test_emptystruct::wire::Empty e = {};
};

struct EmptyProtocolSendAndReceiveRequest {
  ::test_emptystruct::wire::Empty e = {};
};

struct EmptyProtocolSendAndReceiveResponse {
  ::test_emptystruct::wire::Empty e = {};
};

}  // namespace wire
}  // namespace test_emptystruct
namespace fidl {

template <>
struct TypeTraits<::test_emptystruct::wire::Empty> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 1;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::test_emptystruct::wire::Empty> : public std::true_type {};
template <>
struct IsWire<::test_emptystruct::wire::Empty> : public std::true_type {};
template <>
struct IsStruct<::test_emptystruct::wire::Empty> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_emptystruct::wire::Empty>);
static_assert(offsetof(::test_emptystruct::wire::Empty, __reserved) == 0);
static_assert(sizeof(::test_emptystruct::wire::Empty) == TypeTraits<::test_emptystruct::wire::Empty>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_emptystruct::wire::Empty, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 1;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_emptystruct::wire::Empty, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_emptystruct::wire::Empty* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_emptystruct::wire::Empty));
    } else {
      internal::WireCodingTraits<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->__reserved, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
    if (*position.As<uint8_t>() != 0) {
      decoder->SetError(kCodingErrorInvalidPaddingBytes);
    }
  }
};

template <>
struct TypeTraits<::test_emptystruct::wire::EmptyProtocolSendRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 1;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::test_emptystruct::wire::EmptyProtocolSendRequest> : public std::true_type {};
template <>
struct IsWire<::test_emptystruct::wire::EmptyProtocolSendRequest> : public std::true_type {};
template <>
struct IsStruct<::test_emptystruct::wire::EmptyProtocolSendRequest> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_emptystruct::wire::EmptyProtocolSendRequest>);
static_assert(offsetof(::test_emptystruct::wire::EmptyProtocolSendRequest, e) == 0);
static_assert(sizeof(::test_emptystruct::wire::EmptyProtocolSendRequest) == TypeTraits<::test_emptystruct::wire::EmptyProtocolSendRequest>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_emptystruct::wire::EmptyProtocolSendRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 1;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_emptystruct::wire::EmptyProtocolSendRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_emptystruct::wire::EmptyProtocolSendRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_emptystruct::wire::EmptyProtocolSendRequest));
    } else {
      internal::WireCodingTraits<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->e, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

template <>
struct TypeTraits<::test_emptystruct::wire::EmptyProtocolReceiveRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 1;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::test_emptystruct::wire::EmptyProtocolReceiveRequest> : public std::true_type {};
template <>
struct IsWire<::test_emptystruct::wire::EmptyProtocolReceiveRequest> : public std::true_type {};
template <>
struct IsStruct<::test_emptystruct::wire::EmptyProtocolReceiveRequest> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_emptystruct::wire::EmptyProtocolReceiveRequest>);
static_assert(offsetof(::test_emptystruct::wire::EmptyProtocolReceiveRequest, e) == 0);
static_assert(sizeof(::test_emptystruct::wire::EmptyProtocolReceiveRequest) == TypeTraits<::test_emptystruct::wire::EmptyProtocolReceiveRequest>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_emptystruct::wire::EmptyProtocolReceiveRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 1;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_emptystruct::wire::EmptyProtocolReceiveRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_emptystruct::wire::EmptyProtocolReceiveRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_emptystruct::wire::EmptyProtocolReceiveRequest));
    } else {
      internal::WireCodingTraits<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->e, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

template <>
struct TypeTraits<::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 1;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest> : public std::true_type {};
template <>
struct IsWire<::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest> : public std::true_type {};
template <>
struct IsStruct<::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest>);
static_assert(offsetof(::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest, e) == 0);
static_assert(sizeof(::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest) == TypeTraits<::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 1;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_emptystruct::wire::EmptyProtocolSendAndReceiveRequest));
    } else {
      internal::WireCodingTraits<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->e, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

template <>
struct TypeTraits<::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 1;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse> : public std::true_type {};
template <>
struct IsWire<::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse> : public std::true_type {};
template <>
struct IsStruct<::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse>);
static_assert(offsetof(::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse, e) == 0);
static_assert(sizeof(::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse) == TypeTraits<::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 1;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_emptystruct::wire::EmptyProtocolSendAndReceiveResponse));
    } else {
      internal::WireCodingTraits<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->e, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::test_emptystruct::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

#pragma clang diagnostic pop

}  // namespace fidl
