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

#pragma once

#include <fidl/test.protocolrequest/cpp/markers.h>
#include <fidl/test.protocolrequest/cpp/wire_types.h>
#include <lib/fidl/llcpp/wire_messaging.h>

#ifdef __Fuchsia__

#include <lib/fidl/llcpp/client.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fidl/llcpp/service_handler_interface.h>
#include <lib/fidl/llcpp/sync_call.h>

#endif  // __Fuchsia__

namespace test_protocolrequest {
class Parent;

class Child;

__LOCAL extern "C" const fidl_type_t
    test_protocolrequest_ParentGetChildTopResponseTable;

__LOCAL extern "C" const fidl_type_t
    test_protocolrequest_ParentGetChildRequestTopResponseTable;
__LOCAL extern "C" const fidl_type_t
    test_protocolrequest_ParentTakeChildRequestTable;

__LOCAL extern "C" const fidl_type_t
    test_protocolrequest_ParentTakeChildRequestRequestTable;

}  // namespace test_protocolrequest
template <>
struct ::fidl::internal::WireOrdinal<::test_protocolrequest::Parent::GetChild>
    final {
  static constexpr uint64_t value = 881818649151440699lu;
};
template <>
struct ::fidl::internal::WireOrdinal<
    ::test_protocolrequest::Parent::GetChildRequest>
    final {
  static constexpr uint64_t value = 1096855814967598201lu;
};
template <>
struct ::fidl::internal::WireOrdinal<::test_protocolrequest::Parent::TakeChild>
    final {
  static constexpr uint64_t value = 4470101341872267920lu;
};
template <>
struct ::fidl::internal::WireOrdinal<
    ::test_protocolrequest::Parent::TakeChildRequest>
    final {
  static constexpr uint64_t value = 2333981071306416007lu;
};

namespace test_protocolrequest {}  // namespace test_protocolrequest
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::test_protocolrequest::Parent> {};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireServerDispatcher<::test_protocolrequest::Parent>
    final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireServer<::test_protocolrequest::Parent>* impl,
      ::fidl::IncomingMessage& msg,
      internal::IncomingTransportContext transport_context,
      ::fidl::Transaction* txn);
  static void Dispatch(::fidl::WireServer<::test_protocolrequest::Parent>* impl,
                       ::fidl::IncomingMessage&& msg,
                       internal::IncomingTransportContext transport_context,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
};
#endif  // __Fuchsia__

template <>
struct ::fidl::WireRequest<::test_protocolrequest::Parent::GetChild> final {
  WireRequest() = default;
  using ResponseType =
      ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>;
};

template <>
struct ::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::GetChild>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  TransactionalRequest() { _InitHeader(); }
  using ResponseType = ::fidl::internal::TransactionalResponse<
      ::test_protocolrequest::Parent::GetChild>;

 private:
  void _InitHeader();
};
#ifdef __Fuchsia__

template <>
struct ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild> final
    : public ::test_protocolrequest::wire::ParentGetChildTopResponse {
  explicit WireResponse(
      ::test_protocolrequest::wire::ParentGetChildTopResponse base)
      : ::test_protocolrequest::wire::ParentGetChildTopResponse(
            std::move(base)) {}
  explicit WireResponse(::fidl::ClientEnd<::test_protocolrequest::Child>&& c)
      : ::test_protocolrequest::wire::ParentGetChildTopResponse{
            .c = std::move(c)} {}
  WireResponse() = default;
};

template <>
struct ::fidl::internal::TransactionalResponse<
    ::test_protocolrequest::Parent::GetChild>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild> body;
  explicit TransactionalResponse(
      ::fidl::ClientEnd<::test_protocolrequest::Child>&& c)
      : body(::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>(
            std::move(c))) {
    _InitHeader();
  }
  TransactionalResponse() { _InitHeader(); }
  void _CloseHandles() { body._CloseHandles(); }

 private:
  void _InitHeader();
};
#endif  // __Fuchsia__

template <>
struct ::fidl::WireRequest<::test_protocolrequest::Parent::GetChildRequest>
    final {
  WireRequest() = default;
  using ResponseType =
      ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>;
};

template <>
struct ::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::GetChildRequest>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  TransactionalRequest() { _InitHeader(); }
  using ResponseType = ::fidl::internal::TransactionalResponse<
      ::test_protocolrequest::Parent::GetChildRequest>;

 private:
  void _InitHeader();
};
#ifdef __Fuchsia__

template <>
struct ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>
    final
    : public ::test_protocolrequest::wire::ParentGetChildRequestTopResponse {
  explicit WireResponse(
      ::test_protocolrequest::wire::ParentGetChildRequestTopResponse base)
      : ::test_protocolrequest::wire::ParentGetChildRequestTopResponse(
            std::move(base)) {}
  explicit WireResponse(::fidl::ServerEnd<::test_protocolrequest::Child>&& r)
      : ::test_protocolrequest::wire::ParentGetChildRequestTopResponse{
            .r = std::move(r)} {}
  WireResponse() = default;
};

template <>
struct ::fidl::internal::TransactionalResponse<
    ::test_protocolrequest::Parent::GetChildRequest>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest> body;
  explicit TransactionalResponse(
      ::fidl::ServerEnd<::test_protocolrequest::Child>&& r)
      : body(::fidl::WireResponse<
             ::test_protocolrequest::Parent::GetChildRequest>(std::move(r))) {
    _InitHeader();
  }
  TransactionalResponse() { _InitHeader(); }
  void _CloseHandles() { body._CloseHandles(); }

 private:
  void _InitHeader();
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChild> final
    : public ::test_protocolrequest::wire::ParentTakeChildRequest {
  explicit WireRequest(
      ::test_protocolrequest::wire::ParentTakeChildRequest base)
      : ::test_protocolrequest::wire::ParentTakeChildRequest(std::move(base)) {}
  explicit WireRequest(::fidl::ClientEnd<::test_protocolrequest::Child>&& c)
      : ::test_protocolrequest::wire::ParentTakeChildRequest{.c =
                                                                 std::move(c)} {
  }
  WireRequest() = default;
};

template <>
struct ::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::TakeChild>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChild> body;
  explicit TransactionalRequest(
      ::fidl::ClientEnd<::test_protocolrequest::Child>&& c)
      : body(::fidl::WireRequest<::test_protocolrequest::Parent::TakeChild>(
            std::move(c))) {
    _InitHeader();
  }
  TransactionalRequest() { _InitHeader(); }
  void _CloseHandles() { body._CloseHandles(); }

 private:
  void _InitHeader();
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChildRequest>
    final : public ::test_protocolrequest::wire::ParentTakeChildRequestRequest {
  explicit WireRequest(
      ::test_protocolrequest::wire::ParentTakeChildRequestRequest base)
      : ::test_protocolrequest::wire::ParentTakeChildRequestRequest(
            std::move(base)) {}
  explicit WireRequest(::fidl::ServerEnd<::test_protocolrequest::Child>&& r)
      : ::test_protocolrequest::wire::ParentTakeChildRequestRequest{
            .r = std::move(r)} {}
  WireRequest() = default;
};

template <>
struct ::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::TakeChildRequest>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChildRequest> body;
  explicit TransactionalRequest(
      ::fidl::ServerEnd<::test_protocolrequest::Child>&& r)
      : body(::fidl::WireRequest<
             ::test_protocolrequest::Parent::TakeChildRequest>(std::move(r))) {
    _InitHeader();
  }
  TransactionalRequest() { _InitHeader(); }
  void _CloseHandles() { body._CloseHandles(); }

 private:
  void _InitHeader();
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireMethodTypes<
    ::test_protocolrequest::Parent::GetChild> {
  using Completer = fidl::Completer<::fidl::internal::WireCompleterBase<
      ::test_protocolrequest::Parent::GetChild>>;

  using Thenable = ::fidl::internal::WireThenableImpl<
      ::test_protocolrequest::Parent::GetChild,
      ::fidl::unstable::OwnedEncodedMessage<
          ::fidl::internal::TransactionalRequest<
              ::test_protocolrequest::Parent::GetChild>,
          ::fidl::internal::ChannelTransport>>;

  using BufferThenable = ::fidl::internal::WireThenableImpl<
      ::test_protocolrequest::Parent::GetChild,
      ::fidl::unstable::UnownedEncodedMessage<
          ::fidl::internal::TransactionalRequest<
              ::test_protocolrequest::Parent::GetChild>,
          ::fidl::internal::ChannelTransport>>;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireMethodTypes<
    ::test_protocolrequest::Parent::GetChildRequest> {
  using Completer = fidl::Completer<::fidl::internal::WireCompleterBase<
      ::test_protocolrequest::Parent::GetChildRequest>>;

  using Thenable = ::fidl::internal::WireThenableImpl<
      ::test_protocolrequest::Parent::GetChildRequest,
      ::fidl::unstable::OwnedEncodedMessage<
          ::fidl::internal::TransactionalRequest<
              ::test_protocolrequest::Parent::GetChildRequest>,
          ::fidl::internal::ChannelTransport>>;

  using BufferThenable = ::fidl::internal::WireThenableImpl<
      ::test_protocolrequest::Parent::GetChildRequest,
      ::fidl::unstable::UnownedEncodedMessage<
          ::fidl::internal::TransactionalRequest<
              ::test_protocolrequest::Parent::GetChildRequest>,
          ::fidl::internal::ChannelTransport>>;
};

#endif  // __Fuchsia__

namespace fidl {

template <>
struct IsFidlType<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::GetChild>> : public std::true_type {};
template <>
struct IsFidlType<::fidl::WireRequest<::test_protocolrequest::Parent::GetChild>>
    : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::GetChild>> : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<
    ::fidl::WireRequest<::test_protocolrequest::Parent::GetChild>>
    : public std::false_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::GetChild>> {
  static constexpr const fidl_type_t* kType = nullptr;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize =
      FIDL_ALIGN(0 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kPrimarySizeV1 =
      FIDL_ALIGN(0 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};

static_assert(sizeof(::fidl::internal::TransactionalRequest<
                     ::test_protocolrequest::Parent::GetChild>) ==
              TypeTraits<::fidl::internal::TransactionalRequest<
                  ::test_protocolrequest::Parent::GetChild>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalRequest<
                           ::test_protocolrequest::Parent::GetChild>,
                       header) == 0);

template <>
struct TypeTraits<
    ::fidl::WireRequest<::test_protocolrequest::Parent::GetChild>> {
  static constexpr const fidl_type_t* kType = nullptr;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 0;
  static constexpr uint32_t kPrimarySizeV1 = 0;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};

template <>
struct IsFidlType<::fidl::internal::TransactionalResponse<
    ::test_protocolrequest::Parent::GetChild>> : public std::true_type {};
template <>
struct IsFidlType<
    ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>>
    : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalResponse<
    ::test_protocolrequest::Parent::GetChild>> : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<
    ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>>
    : public std::false_type {};
#ifdef __Fuchsia__
template <>
struct IsResource<::fidl::internal::TransactionalResponse<
    ::test_protocolrequest::Parent::GetChild>> : public std::true_type {};
template <>
struct IsResource<
    ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>>
    : public std::true_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalResponse<
    ::test_protocolrequest::Parent::GetChild>> {
  static constexpr const fidl_type_t* kType =
      &::test_protocolrequest::
          test_protocolrequest_ParentGetChildTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kPrimarySize =
      FIDL_ALIGN(4 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kPrimarySizeV1 =
      FIDL_ALIGN(4 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;
};

static_assert(sizeof(::fidl::internal::TransactionalResponse<
                     ::test_protocolrequest::Parent::GetChild>) ==
              TypeTraits<::fidl::internal::TransactionalResponse<
                  ::test_protocolrequest::Parent::GetChild>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalResponse<
                           ::test_protocolrequest::Parent::GetChild>,
                       header) == 0);
static_assert(offsetof(::fidl::internal::TransactionalResponse<
                           ::test_protocolrequest::Parent::GetChild>,
                       body) == sizeof(fidl_message_header_t));

template <>
struct TypeTraits<
    ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>> {
  static constexpr const fidl_type_t* kType =
      &::test_protocolrequest::
          test_protocolrequest_ParentGetChildTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kPrimarySizeV1 = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;
};
static_assert(
    sizeof(::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>) ==
    TypeTraits<::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>>::
        kPrimarySize);
static_assert(
    offsetof(::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>,
             c) == 0);
#endif  // __Fuchsia__

template <>
struct IsFidlType<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::GetChildRequest>> : public std::true_type {
};
template <>
struct IsFidlType<
    ::fidl::WireRequest<::test_protocolrequest::Parent::GetChildRequest>>
    : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::GetChildRequest>> : public std::true_type {
};
template <>
struct IsFidlTransactionalMessage<
    ::fidl::WireRequest<::test_protocolrequest::Parent::GetChildRequest>>
    : public std::false_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::GetChildRequest>> {
  static constexpr const fidl_type_t* kType = nullptr;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize =
      FIDL_ALIGN(0 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kPrimarySizeV1 =
      FIDL_ALIGN(0 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};

static_assert(
    sizeof(::fidl::internal::TransactionalRequest<
           ::test_protocolrequest::Parent::GetChildRequest>) ==
    TypeTraits<::fidl::internal::TransactionalRequest<
        ::test_protocolrequest::Parent::GetChildRequest>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalRequest<
                           ::test_protocolrequest::Parent::GetChildRequest>,
                       header) == 0);

template <>
struct TypeTraits<
    ::fidl::WireRequest<::test_protocolrequest::Parent::GetChildRequest>> {
  static constexpr const fidl_type_t* kType = nullptr;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 0;
  static constexpr uint32_t kPrimarySizeV1 = 0;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};

template <>
struct IsFidlType<::fidl::internal::TransactionalResponse<
    ::test_protocolrequest::Parent::GetChildRequest>> : public std::true_type {
};
template <>
struct IsFidlType<
    ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>>
    : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalResponse<
    ::test_protocolrequest::Parent::GetChildRequest>> : public std::true_type {
};
template <>
struct IsFidlTransactionalMessage<
    ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>>
    : public std::false_type {};
#ifdef __Fuchsia__
template <>
struct IsResource<::fidl::internal::TransactionalResponse<
    ::test_protocolrequest::Parent::GetChildRequest>> : public std::true_type {
};
template <>
struct IsResource<
    ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>>
    : public std::true_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalResponse<
    ::test_protocolrequest::Parent::GetChildRequest>> {
  static constexpr const fidl_type_t* kType =
      &::test_protocolrequest::
          test_protocolrequest_ParentGetChildRequestTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kPrimarySize =
      FIDL_ALIGN(4 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kPrimarySizeV1 =
      FIDL_ALIGN(4 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;
};

static_assert(
    sizeof(::fidl::internal::TransactionalResponse<
           ::test_protocolrequest::Parent::GetChildRequest>) ==
    TypeTraits<::fidl::internal::TransactionalResponse<
        ::test_protocolrequest::Parent::GetChildRequest>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalResponse<
                           ::test_protocolrequest::Parent::GetChildRequest>,
                       header) == 0);
static_assert(offsetof(::fidl::internal::TransactionalResponse<
                           ::test_protocolrequest::Parent::GetChildRequest>,
                       body) == sizeof(fidl_message_header_t));

template <>
struct TypeTraits<
    ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>> {
  static constexpr const fidl_type_t* kType =
      &::test_protocolrequest::
          test_protocolrequest_ParentGetChildRequestTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kPrimarySizeV1 = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;
};
static_assert(
    sizeof(::fidl::WireResponse<
           ::test_protocolrequest::Parent::GetChildRequest>) ==
    TypeTraits<::fidl::WireResponse<
        ::test_protocolrequest::Parent::GetChildRequest>>::kPrimarySize);
static_assert(
    offsetof(
        ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>,
        r) == 0);
#endif  // __Fuchsia__

template <>
struct IsFidlType<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::TakeChild>> : public std::true_type {};
template <>
struct IsFidlType<
    ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChild>>
    : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::TakeChild>> : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<
    ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChild>>
    : public std::false_type {};
#ifdef __Fuchsia__
template <>
struct IsResource<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::TakeChild>> : public std::true_type {};
template <>
struct IsResource<
    ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChild>>
    : public std::true_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::TakeChild>> {
  static constexpr const fidl_type_t* kType =
      &::test_protocolrequest::test_protocolrequest_ParentTakeChildRequestTable;
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kPrimarySize =
      FIDL_ALIGN(4 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kPrimarySizeV1 =
      FIDL_ALIGN(4 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};

static_assert(sizeof(::fidl::internal::TransactionalRequest<
                     ::test_protocolrequest::Parent::TakeChild>) ==
              TypeTraits<::fidl::internal::TransactionalRequest<
                  ::test_protocolrequest::Parent::TakeChild>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalRequest<
                           ::test_protocolrequest::Parent::TakeChild>,
                       header) == 0);
static_assert(offsetof(::fidl::internal::TransactionalRequest<
                           ::test_protocolrequest::Parent::TakeChild>,
                       body) == sizeof(fidl_message_header_t));

template <>
struct TypeTraits<
    ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChild>> {
  static constexpr const fidl_type_t* kType =
      &::test_protocolrequest::test_protocolrequest_ParentTakeChildRequestTable;
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kPrimarySizeV1 = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};
static_assert(
    sizeof(::fidl::WireRequest<::test_protocolrequest::Parent::TakeChild>) ==
    TypeTraits<::fidl::WireRequest<::test_protocolrequest::Parent::TakeChild>>::
        kPrimarySize);
static_assert(
    offsetof(::fidl::WireRequest<::test_protocolrequest::Parent::TakeChild>,
             c) == 0);
#endif  // __Fuchsia__

template <>
struct IsFidlType<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::TakeChildRequest>> : public std::true_type {
};
template <>
struct IsFidlType<
    ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChildRequest>>
    : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::TakeChildRequest>> : public std::true_type {
};
template <>
struct IsFidlTransactionalMessage<
    ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChildRequest>>
    : public std::false_type {};
#ifdef __Fuchsia__
template <>
struct IsResource<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::TakeChildRequest>> : public std::true_type {
};
template <>
struct IsResource<
    ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChildRequest>>
    : public std::true_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalRequest<
    ::test_protocolrequest::Parent::TakeChildRequest>> {
  static constexpr const fidl_type_t* kType =
      &::test_protocolrequest::
          test_protocolrequest_ParentTakeChildRequestRequestTable;
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kPrimarySize =
      FIDL_ALIGN(4 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kPrimarySizeV1 =
      FIDL_ALIGN(4 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};

static_assert(
    sizeof(::fidl::internal::TransactionalRequest<
           ::test_protocolrequest::Parent::TakeChildRequest>) ==
    TypeTraits<::fidl::internal::TransactionalRequest<
        ::test_protocolrequest::Parent::TakeChildRequest>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalRequest<
                           ::test_protocolrequest::Parent::TakeChildRequest>,
                       header) == 0);
static_assert(offsetof(::fidl::internal::TransactionalRequest<
                           ::test_protocolrequest::Parent::TakeChildRequest>,
                       body) == sizeof(fidl_message_header_t));

template <>
struct TypeTraits<
    ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChildRequest>> {
  static constexpr const fidl_type_t* kType =
      &::test_protocolrequest::
          test_protocolrequest_ParentTakeChildRequestRequestTable;
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kPrimarySizeV1 = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};
static_assert(
    sizeof(::fidl::WireRequest<
           ::test_protocolrequest::Parent::TakeChildRequest>) ==
    TypeTraits<::fidl::WireRequest<
        ::test_protocolrequest::Parent::TakeChildRequest>>::kPrimarySize);
static_assert(
    offsetof(
        ::fidl::WireRequest<::test_protocolrequest::Parent::TakeChildRequest>,
        r) == 0);
#endif  // __Fuchsia__

}  // namespace fidl
namespace test_protocolrequest {
#ifdef __Fuchsia__
}  // namespace test_protocolrequest
template <>
class [[nodiscard]] ::fidl::WireResult<::test_protocolrequest::Parent::GetChild>
    final : public ::fidl::Status {
 public:
  WireResult(::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client,
             ::fidl::internal::TransactionalRequest<
                 ::test_protocolrequest::Parent::GetChild>* request);
  WireResult(::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client,
             ::fidl::internal::TransactionalRequest<
                 ::test_protocolrequest::Parent::GetChild>* request,
             zx_time_t _deadline);
  explicit WireResult(const ::fidl::Status& result) : ::fidl::Status(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() {
    if (ok()) {
      Unwrap()->_CloseHandles();
    }
  }
  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>* Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<
        ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>* Unwrap()
      const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<
        const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>* Unwrap_NEW() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<
        ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>*
  Unwrap_NEW() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<
        const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>& value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>& value()
      const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>& value_NEW() {
    return *Unwrap_NEW();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>&
  value_NEW() const {
    return *Unwrap_NEW();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>* operator->() {
    return &value();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>& operator*() {
    return value();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<24> bytes_;
};
template <>
class [[nodiscard]] ::fidl::WireUnownedResult<
    ::test_protocolrequest::Parent::GetChild>
    final : public ::fidl::Status {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client_end,
      ::fidl::internal::AnyBufferAllocator& allocator,
      ::fidl::internal::TransactionalRequest<
          ::test_protocolrequest::Parent::GetChild>* request);
  explicit WireUnownedResult(
      ::fidl::internal::TransactionalResponse<
          ::test_protocolrequest::Parent::GetChild>* response)
      : bytes_(reinterpret_cast<uint8_t*>(response)) {}
  explicit WireUnownedResult(const ::fidl::Status& result)
      : ::fidl::Status(result) {}
  explicit WireUnownedResult(
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalResponse<
          ::test_protocolrequest::Parent::GetChild>>&& decoded,
      ::fidl::internal::IncomingTransportContext context)
      : ::fidl::Status(decoded) {
    if (decoded.ok()) {
      bytes_ = reinterpret_cast<uint8_t*>(decoded.PrimaryObject());
    } else {
      bytes_ = nullptr;
    }
    decoded.ReleasePrimaryObject();
  }
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() {
    if (ok()) {
      Unwrap()->_CloseHandles();
    }
  }
  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>* Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<::fidl::internal::TransactionalResponse<
                 ::test_protocolrequest::Parent::GetChild>*>(bytes_)
                 ->body);
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>* Unwrap()
      const {
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<const ::fidl::internal::TransactionalResponse<
                 ::test_protocolrequest::Parent::GetChild>*>(bytes_)
                 ->body);
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>* Unwrap_NEW() {
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<::fidl::internal::TransactionalResponse<
                 ::test_protocolrequest::Parent::GetChild>*>(bytes_)
                 ->body);
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>*
  Unwrap_NEW() const {
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<const ::fidl::internal::TransactionalResponse<
                 ::test_protocolrequest::Parent::GetChild>*>(bytes_)
                 ->body);
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>& value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>& value()
      const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>& value_NEW() {
    return *Unwrap_NEW();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>&
  value_NEW() const {
    return *Unwrap_NEW();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>* operator->() {
    return &value();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>& operator*() {
    return value();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChild>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};
template <>
class [[nodiscard]] ::fidl::WireResult<
    ::test_protocolrequest::Parent::GetChildRequest>
    final : public ::fidl::Status {
 public:
  WireResult(::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client,
             ::fidl::internal::TransactionalRequest<
                 ::test_protocolrequest::Parent::GetChildRequest>* request);
  WireResult(::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client,
             ::fidl::internal::TransactionalRequest<
                 ::test_protocolrequest::Parent::GetChildRequest>* request,
             zx_time_t _deadline);
  explicit WireResult(const ::fidl::Status& result) : ::fidl::Status(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() {
    if (ok()) {
      Unwrap()->_CloseHandles();
    }
  }
  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<
        ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::test_protocolrequest::Parent::GetChildRequest>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  Unwrap_NEW() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<
        ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  Unwrap_NEW() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::test_protocolrequest::Parent::GetChildRequest>*>(
        bytes_.data() + sizeof(fidl_message_header_t));
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  value_NEW() {
    return *Unwrap_NEW();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  value_NEW() const {
    return *Unwrap_NEW();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<24> bytes_;
};
template <>
class [[nodiscard]] ::fidl::WireUnownedResult<
    ::test_protocolrequest::Parent::GetChildRequest>
    final : public ::fidl::Status {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client_end,
      ::fidl::internal::AnyBufferAllocator& allocator,
      ::fidl::internal::TransactionalRequest<
          ::test_protocolrequest::Parent::GetChildRequest>* request);
  explicit WireUnownedResult(
      ::fidl::internal::TransactionalResponse<
          ::test_protocolrequest::Parent::GetChildRequest>* response)
      : bytes_(reinterpret_cast<uint8_t*>(response)) {}
  explicit WireUnownedResult(const ::fidl::Status& result)
      : ::fidl::Status(result) {}
  explicit WireUnownedResult(
      ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalResponse<
          ::test_protocolrequest::Parent::GetChildRequest>>&& decoded,
      ::fidl::internal::IncomingTransportContext context)
      : ::fidl::Status(decoded) {
    if (decoded.ok()) {
      bytes_ = reinterpret_cast<uint8_t*>(decoded.PrimaryObject());
    } else {
      bytes_ = nullptr;
    }
    decoded.ReleasePrimaryObject();
  }
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() {
    if (ok()) {
      Unwrap()->_CloseHandles();
    }
  }
  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<::fidl::internal::TransactionalResponse<
                 ::test_protocolrequest::Parent::GetChildRequest>*>(bytes_)
                 ->body);
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<const ::fidl::internal::TransactionalResponse<
                 ::test_protocolrequest::Parent::GetChildRequest>*>(bytes_)
                 ->body);
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  Unwrap_NEW() {
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<::fidl::internal::TransactionalResponse<
                 ::test_protocolrequest::Parent::GetChildRequest>*>(bytes_)
                 ->body);
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  Unwrap_NEW() const {
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<const ::fidl::internal::TransactionalResponse<
                 ::test_protocolrequest::Parent::GetChildRequest>*>(bytes_)
                 ->body);
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  value_NEW() {
    return *Unwrap_NEW();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  value_NEW() const {
    return *Unwrap_NEW();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<::test_protocolrequest::Parent::GetChildRequest>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};
template <>
class [[nodiscard]] ::fidl::WireResult<
    ::test_protocolrequest::Parent::TakeChild>
    final : public ::fidl::Status {
 public:
  WireResult(::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client,
             ::fidl::internal::TransactionalRequest<
                 ::test_protocolrequest::Parent::TakeChild>* request);
  explicit WireResult(const ::fidl::Status& result) : ::fidl::Status(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

 private:
};
template <>
class [[nodiscard]] ::fidl::WireUnownedResult<
    ::test_protocolrequest::Parent::TakeChild>
    final : public ::fidl::Status {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client_end,
      ::fidl::internal::AnyBufferAllocator& allocator,
      ::fidl::internal::TransactionalRequest<
          ::test_protocolrequest::Parent::TakeChild>* request);
  explicit WireUnownedResult(const ::fidl::Status& result)
      : ::fidl::Status(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};
template <>
class [[nodiscard]] ::fidl::WireResult<
    ::test_protocolrequest::Parent::TakeChildRequest>
    final : public ::fidl::Status {
 public:
  WireResult(::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client,
             ::fidl::internal::TransactionalRequest<
                 ::test_protocolrequest::Parent::TakeChildRequest>* request);
  explicit WireResult(const ::fidl::Status& result) : ::fidl::Status(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

 private:
};
template <>
class [[nodiscard]] ::fidl::WireUnownedResult<
    ::test_protocolrequest::Parent::TakeChildRequest>
    final : public ::fidl::Status {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client_end,
      ::fidl::internal::AnyBufferAllocator& allocator,
      ::fidl::internal::TransactionalRequest<
          ::test_protocolrequest::Parent::TakeChildRequest>* request);
  explicit WireUnownedResult(const ::fidl::Status& result)
      : ::fidl::Status(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};
template <>
class ::fidl::internal::WireEventHandlerInterface<
    ::test_protocolrequest::Parent> {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
};

template <>
class ::fidl::WireAsyncEventHandler<::test_protocolrequest::Parent>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::test_protocolrequest::Parent>,
      public ::fidl::internal::AsyncEventHandler {
 public:
  WireAsyncEventHandler() = default;
};

template <>
class ::fidl::WireSyncEventHandler<::test_protocolrequest::Parent>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::test_protocolrequest::Parent> {
 public:
  WireSyncEventHandler() = default;

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method.
  ::fidl::Status HandleOneEvent(
      ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> client_end);

 private:
  [[maybe_unused]] bool got_transitional_ = false;
};

template <>
class ::fidl::internal::WireEventDispatcher<::test_protocolrequest::Parent>
    final : public ::fidl::internal::IncomingEventDispatcher<
                ::fidl::WireAsyncEventHandler<::test_protocolrequest::Parent>> {
 public:
  explicit WireEventDispatcher(
      ::fidl::WireAsyncEventHandler<::test_protocolrequest::Parent>*
          event_handler)
      : IncomingEventDispatcher(event_handler) {}

 private:
  std::optional<::fidl::UnbindInfo> DispatchEvent(
      ::fidl::IncomingMessage& msg,
      ::fidl::internal::IncomingTransportContext transport_context) override;
};

// Methods to make a sync FIDL call directly on an unowned handle or a
// const reference to a |fidl::ClientEnd<::test_protocolrequest::Parent>|,
// avoiding setting up a client.
template <>
class ::fidl::internal::WireSyncClientImpl<::test_protocolrequest::Parent> final
    : public ::fidl::internal::SyncEndpointManagedVeneer<
          ::fidl::internal::WireSyncClientImpl<
              ::test_protocolrequest::Parent>> {
 public:
  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::test_protocolrequest::Parent::GetChild> GetChild() {
    ::fidl::internal::TransactionalRequest<
        ::test_protocolrequest::Parent::GetChild>
        _request{};
    return ::fidl::WireResult<::test_protocolrequest::Parent::GetChild>(
        _client_end(), &_request);
  }

  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::test_protocolrequest::Parent::GetChildRequest>
  GetChildRequest() {
    ::fidl::internal::TransactionalRequest<
        ::test_protocolrequest::Parent::GetChildRequest>
        _request{};
    return ::fidl::WireResult<::test_protocolrequest::Parent::GetChildRequest>(
        _client_end(), &_request);
  }

  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::test_protocolrequest::Parent::TakeChild> TakeChild(
      ::fidl::ClientEnd<::test_protocolrequest::Child>&& c) {
    ::fidl::internal::TransactionalRequest<
        ::test_protocolrequest::Parent::TakeChild>
        _request{std::move(c)};
    return ::fidl::WireResult<::test_protocolrequest::Parent::TakeChild>(
        _client_end(), &_request);
  }

  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::test_protocolrequest::Parent::TakeChildRequest>
  TakeChildRequest(::fidl::ServerEnd<::test_protocolrequest::Child>&& r) {
    ::fidl::internal::TransactionalRequest<
        ::test_protocolrequest::Parent::TakeChildRequest>
        _request{std::move(r)};
    return ::fidl::WireResult<::test_protocolrequest::Parent::TakeChildRequest>(
        _client_end(), &_request);
  }

 private:
  ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_protocolrequest::Parent>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

template <>
class ::fidl::internal::WireSyncBufferClientImpl<::test_protocolrequest::Parent>
    final : public ::fidl::internal::SyncEndpointBufferVeneer<
                ::fidl::internal::WireSyncBufferClientImpl<
                    ::test_protocolrequest::Parent>> {
 public:
  // Caller provides the backing storage for FIDL message via an argument to
  // `.buffer()`.
  ::fidl::WireUnownedResult<::test_protocolrequest::Parent::GetChild>
  GetChild() {
    ::fidl::internal::TransactionalRequest<
        ::test_protocolrequest::Parent::GetChild>
        _request{};
    return ::fidl::WireUnownedResult<::test_protocolrequest::Parent::GetChild>(
        _client_end(), _allocator(), &_request);
  }

  // Caller provides the backing storage for FIDL message via an argument to
  // `.buffer()`.
  ::fidl::WireUnownedResult<::test_protocolrequest::Parent::GetChildRequest>
  GetChildRequest() {
    ::fidl::internal::TransactionalRequest<
        ::test_protocolrequest::Parent::GetChildRequest>
        _request{};
    return ::fidl::WireUnownedResult<
        ::test_protocolrequest::Parent::GetChildRequest>(
        _client_end(), _allocator(), &_request);
  }

  // Caller provides the backing storage for FIDL message via an argument to
  // `.buffer()`.
  ::fidl::WireUnownedResult<::test_protocolrequest::Parent::TakeChild>
  TakeChild(::fidl::ClientEnd<::test_protocolrequest::Child>&& c) {
    ::fidl::internal::TransactionalRequest<
        ::test_protocolrequest::Parent::TakeChild>
        _request{std::move(c)};
    return ::fidl::WireUnownedResult<::test_protocolrequest::Parent::TakeChild>(
        _client_end(), _allocator(), &_request);
  }

  // Caller provides the backing storage for FIDL message via an argument to
  // `.buffer()`.
  ::fidl::WireUnownedResult<::test_protocolrequest::Parent::TakeChildRequest>
  TakeChildRequest(::fidl::ServerEnd<::test_protocolrequest::Child>&& r) {
    ::fidl::internal::TransactionalRequest<
        ::test_protocolrequest::Parent::TakeChildRequest>
        _request{std::move(r)};
    return ::fidl::WireUnownedResult<
        ::test_protocolrequest::Parent::TakeChildRequest>(
        _client_end(), _allocator(), &_request);
  }

 private:
  ::fidl::UnownedClientEnd<::test_protocolrequest::Parent> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_protocolrequest::Parent>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

template <>
class ::fidl::internal::WireCompleterImpl<
    ::test_protocolrequest::Parent::GetChild>
    : public ::fidl::internal::CompleterImplBase<
          ::test_protocolrequest::Parent::GetChild> {
 public:
  using CompleterImplBase::CompleterImplBase;

  void Reply(::fidl::ClientEnd<::test_protocolrequest::Child>&& c);
};

template <>
class ::fidl::internal::WireBufferCompleterImpl<
    ::test_protocolrequest::Parent::GetChild>
    : public ::fidl::internal::BufferCompleterImplBase {
 public:
  using BufferCompleterImplBase::BufferCompleterImplBase;

  void Reply(::fidl::ClientEnd<::test_protocolrequest::Child>&& c);
};

template <>
class ::fidl::internal::WireCompleterBase<
    ::test_protocolrequest::Parent::GetChild>
    : public ::fidl::CompleterBase,
      public ::fidl::internal::WireCompleterImpl<
          ::test_protocolrequest::Parent::GetChild> {
 public:
  WireCompleterBase(::fidl::Transaction* transaction, bool owned,
                    bool expects_reply)
      : CompleterBase(transaction, owned, expects_reply),
        WireCompleterImpl(this) {}
  WireCompleterBase(WireCompleterBase&& other) noexcept
      : CompleterBase(std::move(other)), WireCompleterImpl(this) {}
  WireCompleterBase& operator=(WireCompleterBase&& other) noexcept {
    CompleterBase::operator=(std::move(other));
    WireCompleterImpl::_set_core(this);
    return *this;
  }
};

template <>
class ::fidl::internal::WireCompleterImpl<
    ::test_protocolrequest::Parent::GetChildRequest>
    : public ::fidl::internal::CompleterImplBase<
          ::test_protocolrequest::Parent::GetChildRequest> {
 public:
  using CompleterImplBase::CompleterImplBase;

  void Reply(::fidl::ServerEnd<::test_protocolrequest::Child>&& r);
};

template <>
class ::fidl::internal::WireBufferCompleterImpl<
    ::test_protocolrequest::Parent::GetChildRequest>
    : public ::fidl::internal::BufferCompleterImplBase {
 public:
  using BufferCompleterImplBase::BufferCompleterImplBase;

  void Reply(::fidl::ServerEnd<::test_protocolrequest::Child>&& r);
};

template <>
class ::fidl::internal::WireCompleterBase<
    ::test_protocolrequest::Parent::GetChildRequest>
    : public ::fidl::CompleterBase,
      public ::fidl::internal::WireCompleterImpl<
          ::test_protocolrequest::Parent::GetChildRequest> {
 public:
  WireCompleterBase(::fidl::Transaction* transaction, bool owned,
                    bool expects_reply)
      : CompleterBase(transaction, owned, expects_reply),
        WireCompleterImpl(this) {}
  WireCompleterBase(WireCompleterBase&& other) noexcept
      : CompleterBase(std::move(other)), WireCompleterImpl(this) {}
  WireCompleterBase& operator=(WireCompleterBase&& other) noexcept {
    CompleterBase::operator=(std::move(other));
    WireCompleterImpl::_set_core(this);
    return *this;
  }
};

// Pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |fidl::ClientEnd<SomeProtocol>|
// and |fidl::ServerEnd<SomeProtocol>|).
template <>
class ::fidl::WireServer<::test_protocolrequest::Parent>
    : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  WireServer() = default;
  virtual ~WireServer() = default;

  // The FIDL protocol type that is implemented by this server.
  using _EnclosingProtocol = ::test_protocolrequest::Parent;

  using GetChildCompleter =
      ::fidl::internal::WireCompleter<::test_protocolrequest::Parent::GetChild>;
  using GetChildRequestView = ::fidl::internal::WireRequestView<
      ::test_protocolrequest::Parent::GetChild>;

  virtual void GetChild(GetChildRequestView request,
                        GetChildCompleter::Sync& completer) = 0;

  using GetChildRequestCompleter = ::fidl::internal::WireCompleter<
      ::test_protocolrequest::Parent::GetChildRequest>;
  using GetChildRequestRequestView = ::fidl::internal::WireRequestView<
      ::test_protocolrequest::Parent::GetChildRequest>;

  virtual void GetChildRequest(GetChildRequestRequestView request,
                               GetChildRequestCompleter::Sync& completer) = 0;

  using TakeChildCompleter = ::fidl::internal::WireCompleter<
      ::test_protocolrequest::Parent::TakeChild>;
  using TakeChildRequestView = ::fidl::internal::WireRequestView<
      ::test_protocolrequest::Parent::TakeChild>;

  virtual void TakeChild(TakeChildRequestView request,
                         TakeChildCompleter::Sync& completer) = 0;

  using TakeChildRequestCompleter = ::fidl::internal::WireCompleter<
      ::test_protocolrequest::Parent::TakeChildRequest>;
  using TakeChildRequestRequestView = ::fidl::internal::WireRequestView<
      ::test_protocolrequest::Parent::TakeChildRequest>;

  virtual void TakeChildRequest(TakeChildRequestRequestView request,
                                TakeChildRequestCompleter::Sync& completer) = 0;

 private:
  void dispatch_message(
      ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::IncomingTransportContext transport_context) final;
};
namespace test_protocolrequest {
#endif  // __Fuchsia__

}  // namespace test_protocolrequest
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::test_protocolrequest::Child> {};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireServerDispatcher<::test_protocolrequest::Child>
    final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireServer<::test_protocolrequest::Child>* impl,
      ::fidl::IncomingMessage& msg,
      internal::IncomingTransportContext transport_context,
      ::fidl::Transaction* txn);
  static void Dispatch(::fidl::WireServer<::test_protocolrequest::Child>* impl,
                       ::fidl::IncomingMessage&& msg,
                       internal::IncomingTransportContext transport_context,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
};
#endif  // __Fuchsia__

namespace fidl {}  // namespace fidl
namespace test_protocolrequest {
#ifdef __Fuchsia__
}  // namespace test_protocolrequest
template <>
class ::fidl::internal::WireEventHandlerInterface<
    ::test_protocolrequest::Child> {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
};

template <>
class ::fidl::WireAsyncEventHandler<::test_protocolrequest::Child>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::test_protocolrequest::Child>,
      public ::fidl::internal::AsyncEventHandler {
 public:
  WireAsyncEventHandler() = default;
};

template <>
class ::fidl::WireSyncEventHandler<::test_protocolrequest::Child>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::test_protocolrequest::Child> {
 public:
  WireSyncEventHandler() = default;

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method.
  ::fidl::Status HandleOneEvent(
      ::fidl::UnownedClientEnd<::test_protocolrequest::Child> client_end);

 private:
  [[maybe_unused]] bool got_transitional_ = false;
};

template <>
class ::fidl::internal::WireEventDispatcher<::test_protocolrequest::Child> final
    : public ::fidl::internal::IncomingEventDispatcher<
          ::fidl::WireAsyncEventHandler<::test_protocolrequest::Child>> {
 public:
  explicit WireEventDispatcher(
      ::fidl::WireAsyncEventHandler<::test_protocolrequest::Child>*
          event_handler)
      : IncomingEventDispatcher(event_handler) {}

 private:
  std::optional<::fidl::UnbindInfo> DispatchEvent(
      ::fidl::IncomingMessage& msg,
      ::fidl::internal::IncomingTransportContext transport_context) override;
};

// Methods to make a sync FIDL call directly on an unowned handle or a
// const reference to a |fidl::ClientEnd<::test_protocolrequest::Child>|,
// avoiding setting up a client.
template <>
class ::fidl::internal::WireSyncClientImpl<::test_protocolrequest::Child> final
    : public ::fidl::internal::SyncEndpointManagedVeneer<
          ::fidl::internal::WireSyncClientImpl<::test_protocolrequest::Child>> {
 public:
 private:
  ::fidl::UnownedClientEnd<::test_protocolrequest::Child> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_protocolrequest::Child>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

template <>
class ::fidl::internal::WireSyncBufferClientImpl<::test_protocolrequest::Child>
    final : public ::fidl::internal::SyncEndpointBufferVeneer<
                ::fidl::internal::WireSyncBufferClientImpl<
                    ::test_protocolrequest::Child>> {
 public:
 private:
  ::fidl::UnownedClientEnd<::test_protocolrequest::Child> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_protocolrequest::Child>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

// Pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |fidl::ClientEnd<SomeProtocol>|
// and |fidl::ServerEnd<SomeProtocol>|).
template <>
class ::fidl::WireServer<::test_protocolrequest::Child>
    : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  WireServer() = default;
  virtual ~WireServer() = default;

  // The FIDL protocol type that is implemented by this server.
  using _EnclosingProtocol = ::test_protocolrequest::Child;

 private:
  void dispatch_message(
      ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::IncomingTransportContext transport_context) final;
};
namespace test_protocolrequest {
#endif  // __Fuchsia__

}  // namespace test_protocolrequest
namespace fidl {

#ifdef __Fuchsia__
}  // namespace fidl
template <>
class ::fidl::internal::WireWeakOnewayClientImpl<::test_protocolrequest::Parent>
    : public ::fidl::internal::ClientImplBase {
 public:
  using ClientImplBase::ClientImplBase;

  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::Status TakeChild(
      ::fidl::ClientEnd<::test_protocolrequest::Child>&& c);

  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::Status TakeChildRequest(
      ::fidl::ServerEnd<::test_protocolrequest::Child>&& r);
};

template <>
class ::fidl::internal::WireWeakAsyncClientImpl<::test_protocolrequest::Parent>
    final : public ::fidl::internal::WireWeakOnewayClientImpl<
                ::test_protocolrequest::Parent> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
  // Allocates 16 bytes of request buffer on the stack. The callback is stored
  // on the heap.
  ::fidl::internal::WireThenable<::test_protocolrequest::Parent::GetChild>
  GetChild();
  // Allocates 16 bytes of request buffer on the stack. The callback is stored
  // on the heap.
  ::fidl::internal::WireThenable<
      ::test_protocolrequest::Parent::GetChildRequest>
  GetChildRequest();
};

template <>
class ::fidl::internal::WireWeakOnewayBufferClientImpl<
    ::test_protocolrequest::Parent>
    : public ::fidl::internal::BufferClientImplBase {
 public:
  using BufferClientImplBase::BufferClientImplBase;

  // Caller provides the backing storage for FIDL message.
  ::fidl::Status TakeChild(
      ::fidl::ClientEnd<::test_protocolrequest::Child>&& c);

  // Caller provides the backing storage for FIDL message.
  ::fidl::Status TakeChildRequest(
      ::fidl::ServerEnd<::test_protocolrequest::Child>&& r);
};

template <>
class ::fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_protocolrequest::Parent>
    final : public ::fidl::internal::WireWeakOnewayBufferClientImpl<
                ::test_protocolrequest::Parent> {
 public:
  using WireWeakOnewayBufferClientImpl::WireWeakOnewayBufferClientImpl;

  // Caller provides the backing storage for FIDL message.
  ::fidl::internal::WireBufferThenable<::test_protocolrequest::Parent::GetChild>
  GetChild();

  // Caller provides the backing storage for FIDL message.
  ::fidl::internal::WireBufferThenable<
      ::test_protocolrequest::Parent::GetChildRequest>
  GetChildRequest();
};
template <>
class ::fidl::internal::WireWeakSyncClientImpl<::test_protocolrequest::Parent>
    final : public ::fidl::internal::WireWeakOnewayClientImpl<
                ::test_protocolrequest::Parent> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;

  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::test_protocolrequest::Parent::GetChild> GetChild();

  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::test_protocolrequest::Parent::GetChildRequest>
  GetChildRequest();
};
namespace fidl {
#endif  // __Fuchsia__

}  // namespace fidl
#ifdef __Fuchsia__
template <>
class ::fidl::internal::WireWeakEventSender<::test_protocolrequest::Parent>
    : public ::fidl::internal::WeakEventSenderBase {
 public:
  using WeakEventSenderBase::WeakEventSenderBase;
};

template <>
class ::fidl::internal::WireWeakBufferEventSender<
    ::test_protocolrequest::Parent>
    : public ::fidl::internal::WeakBufferEventSenderBase {
 public:
  using WeakBufferEventSenderBase::WeakBufferEventSenderBase;
};

template <>
class ::fidl::internal::WireEventSender<::test_protocolrequest::Parent>
    : public ::fidl::internal::SyncEndpointManagedVeneer<
          ::fidl::internal::WireEventSender<::test_protocolrequest::Parent>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

template <>
class ::fidl::internal::WireBufferEventSender<::test_protocolrequest::Parent>
    : public ::fidl::internal::SyncEndpointBufferVeneer<
          ::fidl::internal::WireBufferEventSender<
              ::test_protocolrequest::Parent>> {
 public:
  using SyncEndpointBufferVeneer::SyncEndpointBufferVeneer;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireWeakOnewayClientImpl<::test_protocolrequest::Child>
    : public ::fidl::internal::ClientImplBase {
 public:
  using ClientImplBase::ClientImplBase;
};

template <>
class ::fidl::internal::WireWeakAsyncClientImpl<::test_protocolrequest::Child>
    final : public ::fidl::internal::WireWeakOnewayClientImpl<
                ::test_protocolrequest::Child> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};

template <>
class ::fidl::internal::WireWeakOnewayBufferClientImpl<
    ::test_protocolrequest::Child>
    : public ::fidl::internal::BufferClientImplBase {
 public:
  using BufferClientImplBase::BufferClientImplBase;
};

template <>
class ::fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_protocolrequest::Child>
    final : public ::fidl::internal::WireWeakOnewayBufferClientImpl<
                ::test_protocolrequest::Child> {
 public:
  using WireWeakOnewayBufferClientImpl::WireWeakOnewayBufferClientImpl;
};
template <>
class ::fidl::internal::WireWeakSyncClientImpl<::test_protocolrequest::Child>
    final : public ::fidl::internal::WireWeakOnewayClientImpl<
                ::test_protocolrequest::Child> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
class ::fidl::internal::WireWeakEventSender<::test_protocolrequest::Child>
    : public ::fidl::internal::WeakEventSenderBase {
 public:
  using WeakEventSenderBase::WeakEventSenderBase;
};

template <>
class ::fidl::internal::WireWeakBufferEventSender<::test_protocolrequest::Child>
    : public ::fidl::internal::WeakBufferEventSenderBase {
 public:
  using WeakBufferEventSenderBase::WeakBufferEventSenderBase;
};

template <>
class ::fidl::internal::WireEventSender<::test_protocolrequest::Child>
    : public ::fidl::internal::SyncEndpointManagedVeneer<
          ::fidl::internal::WireEventSender<::test_protocolrequest::Child>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

template <>
class ::fidl::internal::WireBufferEventSender<::test_protocolrequest::Child>
    : public ::fidl::internal::SyncEndpointBufferVeneer<
          ::fidl::internal::WireBufferEventSender<
              ::test_protocolrequest::Child>> {
 public:
  using SyncEndpointBufferVeneer::SyncEndpointBufferVeneer;
};
#endif  // __Fuchsia__
