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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.service/cpp/markers.h>
#include <fidl/test.service/cpp/wire_types.h>
#include <lib/fidl/cpp/wire/wire_messaging.h>

#ifdef __Fuchsia__

#include <lib/fidl/cpp/wire/client.h>
#include <lib/fidl/cpp/wire/connect_service.h>
#include <lib/fidl/cpp/wire/server.h>
#include <lib/fidl/cpp/wire/service_handler.h>
#include <lib/fidl/cpp/wire/sync_call.h>
#include <lib/fidl/cpp/wire/unknown_interaction_handler.h>

#endif  // __Fuchsia__

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

namespace test_service {

class FirstProtocol;

class SecondProtocol;

class EmptyService;

class SingleMemberService;

class MultiHeterogeneousMemberService;

class MultiHomogeneousMemberService;

}  // namespace test_service

template <>
struct ::fidl::internal::WireOrdinal<::test_service::FirstProtocol::MethodOnFirst> final {
  static constexpr uint64_t value = 6352548393671797041lu;
};

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireMethodTypes<::test_service::FirstProtocol::MethodOnFirst> {
  static constexpr bool HasRequestPayload = false;

  using Completer = fidl::Completer<>;
};

#endif  // __Fuchsia__

namespace test_service {

}  // namespace test_service

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::test_service::FirstProtocol> {
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireServerDispatcher<::test_service::FirstProtocol> final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(::fidl::WireServer<::test_service::FirstProtocol>* impl, ::fidl::IncomingHeaderAndMessage& msg,
                                            internal::MessageStorageViewBase* storage_view,
                                            ::fidl::Transaction* txn);
  static void Dispatch(::fidl::WireServer<::test_service::FirstProtocol>* impl, ::fidl::IncomingHeaderAndMessage&& msg,
                       internal::MessageStorageViewBase* storage_view,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
  static constexpr const ::fidl::internal::UnknownMethodHandlerEntry& unknown_method_handler_entry_ =
      ::fidl::internal::UnknownMethodHandlerEntry::kClosedProtocolHandlerEntry;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
struct ::fidl::internal::TransactionalRequest<::test_service::FirstProtocol::MethodOnFirst> final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  TransactionalRequest() {
    _InitHeader();
  }

 private:
  void _InitHeader();
};

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::fidl::internal::TransactionalRequest<::test_service::FirstProtocol::MethodOnFirst>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : public WireStructCodingTraitsBase<::fidl::internal::TransactionalRequest<::test_service::FirstProtocol::MethodOnFirst>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 0 + sizeof(fidl_message_header_t);

  static void Encode(internal::WireEncoder* encoder, ::fidl::internal::TransactionalRequest<::test_service::FirstProtocol::MethodOnFirst>* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    *position.As<fidl_message_header_t>() = value->header;
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
  }
};

#endif  // __Fuchsia__

namespace fidl {

#ifdef __Fuchsia__
template <>
struct IsFidlType<::fidl::internal::TransactionalRequest<::test_service::FirstProtocol::MethodOnFirst>> : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalRequest<::test_service::FirstProtocol::MethodOnFirst>> : public std::true_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalRequest<::test_service::FirstProtocol::MethodOnFirst>> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = FIDL_ALIGN(0 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 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_service::FirstProtocol::MethodOnFirst>) == TypeTraits<::fidl::internal::TransactionalRequest<::test_service::FirstProtocol::MethodOnFirst>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalRequest<::test_service::FirstProtocol::MethodOnFirst>, header) == 0);

#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl

template <>
struct ::fidl::internal::IncomingEventsHandleStorage<::test_service::FirstProtocol> final : public ::fidl::internal::ChannelHandleStorageBase<::fidl::internal::IncomingEventsHandleStorage<::test_service::FirstProtocol>> {
 public:
  static constexpr uint32_t kNumHandles = 0;

  ::std::array<zx_handle_t, kNumHandles> handles_;
  ::std::array<fidl_channel_handle_metadata_t, kNumHandles> handle_metadata_;
};

template <>
struct ::fidl::internal::IncomingEventsStorage<::test_service::FirstProtocol> final : public ::fidl::internal::ChannelMessageStorageBase<::fidl::internal::IncomingEventsStorage<::test_service::FirstProtocol>> {
 public:
  ::fidl::internal::InlineMessageBuffer<24> bytes_;
  ::fidl::internal::IncomingEventsHandleStorage<::test_service::FirstProtocol> handles_storage_;
};

template <>
class [[nodiscard]] ::fidl::WireResult<::test_service::FirstProtocol::MethodOnFirst> final : public ::fidl::BaseWireResult<::test_service::FirstProtocol::MethodOnFirst> {
 public:
  WireResult(
      ::fidl::UnownedClientEnd<::test_service::FirstProtocol> client,
      ::fidl::internal::TransactionalRequest<::test_service::FirstProtocol::MethodOnFirst>* request);

  explicit WireResult(const ::fidl::Status& result) : ::fidl::BaseWireResult<::test_service::FirstProtocol::MethodOnFirst>(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult& operator=(WireResult&&) = delete;
  WireResult& operator=(const WireResult&) = delete;
  ~WireResult() = default;
};

template <>
class [[nodiscard]] ::fidl::WireUnownedResult<::test_service::FirstProtocol::MethodOnFirst> final : public ::fidl::BaseWireResult<::test_service::FirstProtocol::MethodOnFirst> {
 public:
  explicit WireUnownedResult(::fidl::UnownedClientEnd<::test_service::FirstProtocol> client_end, ::fidl::internal::AnyBufferAllocator& allocator, ::fidl::internal::TransactionalRequest<::test_service::FirstProtocol::MethodOnFirst>* request);
  explicit WireUnownedResult(
      ::fit::result<::fidl::Error>&& decoded,
      ::fidl::internal::MessageStorageViewBase* storage_view) : ::fidl::BaseWireResult<::test_service::FirstProtocol::MethodOnFirst>(::fidl::internal::StatusFromResult(decoded)) {}

  explicit WireUnownedResult(const ::fidl::Status& result) : ::fidl::BaseWireResult<::test_service::FirstProtocol::MethodOnFirst>(result) {}
  WireUnownedResult(WireUnownedResult&&) = default;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult& operator=(WireUnownedResult&&) = default;
  WireUnownedResult& operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};

template <>
class ::fidl::internal::WireEventHandlerInterface<::test_service::FirstProtocol> : public ::fidl::internal::BaseEventHandlerInterface {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
};

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

template <>
class ::fidl::WireSyncEventHandler<::test_service::FirstProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<::test_service::FirstProtocol>, public ::fidl::internal::SyncEventHandler {
 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_service::FirstProtocol> client_end);
};

template <>
class ::fidl::internal::WireEventDispatcher<::test_service::FirstProtocol> final : public ::fidl::internal::IncomingEventDispatcher<::fidl::internal::WireEventHandlerInterface<::test_service::FirstProtocol>> {
 public:
  explicit WireEventDispatcher(::fidl::internal::WireEventHandlerInterface<::test_service::FirstProtocol>* event_handler)
      : IncomingEventDispatcher(event_handler) {}
};

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

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

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

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

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

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

  using Handler = fidl::ProtocolHandler<::test_service::FirstProtocol>;

  using MethodOnFirstCompleter = ::fidl::internal::WireCompleter<::test_service::FirstProtocol::MethodOnFirst>;

  virtual void MethodOnFirst(
      MethodOnFirstCompleter::Sync& completer) = 0;

  // |bind_handler| returns a handler that binds incoming connections to this
  // server implementation.
  //
  // The returned handler borrows the server instance.
  // The server must outlive the provided |dispatcher|. Only after
  // the dispatcher is shutdown will it be safe to destroy the servers.
  // The server should not be moved.
  Handler bind_handler(async_dispatcher_t* dispatcher) {
    return [impl = this, dispatcher = dispatcher](::fidl::ServerEnd<::test_service::FirstProtocol> request) {
      (void)::fidl::BindServer(dispatcher, std::move(request), impl);
    };
  }

 private:
  void dispatch_message(
      ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::MessageStorageViewBase* storage_view) final;
};
namespace fidl {

#endif  // __Fuchsia__

}  // namespace fidl

template <>
struct ::fidl::internal::WireOrdinal<::test_service::SecondProtocol::MethodOnSecond> final {
  static constexpr uint64_t value = 8121179205110225988lu;
};

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireMethodTypes<::test_service::SecondProtocol::MethodOnSecond> {
  static constexpr bool HasRequestPayload = false;

  using Completer = fidl::Completer<>;
};

#endif  // __Fuchsia__

namespace test_service {

}  // namespace test_service

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::test_service::SecondProtocol> {
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireServerDispatcher<::test_service::SecondProtocol> final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(::fidl::WireServer<::test_service::SecondProtocol>* impl, ::fidl::IncomingHeaderAndMessage& msg,
                                            internal::MessageStorageViewBase* storage_view,
                                            ::fidl::Transaction* txn);
  static void Dispatch(::fidl::WireServer<::test_service::SecondProtocol>* impl, ::fidl::IncomingHeaderAndMessage&& msg,
                       internal::MessageStorageViewBase* storage_view,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
  static constexpr const ::fidl::internal::UnknownMethodHandlerEntry& unknown_method_handler_entry_ =
      ::fidl::internal::UnknownMethodHandlerEntry::kClosedProtocolHandlerEntry;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
struct ::fidl::internal::TransactionalRequest<::test_service::SecondProtocol::MethodOnSecond> final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  TransactionalRequest() {
    _InitHeader();
  }

 private:
  void _InitHeader();
};

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::fidl::internal::TransactionalRequest<::test_service::SecondProtocol::MethodOnSecond>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : public WireStructCodingTraitsBase<::fidl::internal::TransactionalRequest<::test_service::SecondProtocol::MethodOnSecond>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 0 + sizeof(fidl_message_header_t);

  static void Encode(internal::WireEncoder* encoder, ::fidl::internal::TransactionalRequest<::test_service::SecondProtocol::MethodOnSecond>* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    *position.As<fidl_message_header_t>() = value->header;
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
  }
};

#endif  // __Fuchsia__

namespace fidl {

#ifdef __Fuchsia__
template <>
struct IsFidlType<::fidl::internal::TransactionalRequest<::test_service::SecondProtocol::MethodOnSecond>> : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalRequest<::test_service::SecondProtocol::MethodOnSecond>> : public std::true_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalRequest<::test_service::SecondProtocol::MethodOnSecond>> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = FIDL_ALIGN(0 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 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_service::SecondProtocol::MethodOnSecond>) == TypeTraits<::fidl::internal::TransactionalRequest<::test_service::SecondProtocol::MethodOnSecond>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalRequest<::test_service::SecondProtocol::MethodOnSecond>, header) == 0);

#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl

template <>
struct ::fidl::internal::IncomingEventsHandleStorage<::test_service::SecondProtocol> final : public ::fidl::internal::ChannelHandleStorageBase<::fidl::internal::IncomingEventsHandleStorage<::test_service::SecondProtocol>> {
 public:
  static constexpr uint32_t kNumHandles = 0;

  ::std::array<zx_handle_t, kNumHandles> handles_;
  ::std::array<fidl_channel_handle_metadata_t, kNumHandles> handle_metadata_;
};

template <>
struct ::fidl::internal::IncomingEventsStorage<::test_service::SecondProtocol> final : public ::fidl::internal::ChannelMessageStorageBase<::fidl::internal::IncomingEventsStorage<::test_service::SecondProtocol>> {
 public:
  ::fidl::internal::InlineMessageBuffer<24> bytes_;
  ::fidl::internal::IncomingEventsHandleStorage<::test_service::SecondProtocol> handles_storage_;
};

template <>
class [[nodiscard]] ::fidl::WireResult<::test_service::SecondProtocol::MethodOnSecond> final : public ::fidl::BaseWireResult<::test_service::SecondProtocol::MethodOnSecond> {
 public:
  WireResult(
      ::fidl::UnownedClientEnd<::test_service::SecondProtocol> client,
      ::fidl::internal::TransactionalRequest<::test_service::SecondProtocol::MethodOnSecond>* request);

  explicit WireResult(const ::fidl::Status& result) : ::fidl::BaseWireResult<::test_service::SecondProtocol::MethodOnSecond>(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult& operator=(WireResult&&) = delete;
  WireResult& operator=(const WireResult&) = delete;
  ~WireResult() = default;
};

template <>
class [[nodiscard]] ::fidl::WireUnownedResult<::test_service::SecondProtocol::MethodOnSecond> final : public ::fidl::BaseWireResult<::test_service::SecondProtocol::MethodOnSecond> {
 public:
  explicit WireUnownedResult(::fidl::UnownedClientEnd<::test_service::SecondProtocol> client_end, ::fidl::internal::AnyBufferAllocator& allocator, ::fidl::internal::TransactionalRequest<::test_service::SecondProtocol::MethodOnSecond>* request);
  explicit WireUnownedResult(
      ::fit::result<::fidl::Error>&& decoded,
      ::fidl::internal::MessageStorageViewBase* storage_view) : ::fidl::BaseWireResult<::test_service::SecondProtocol::MethodOnSecond>(::fidl::internal::StatusFromResult(decoded)) {}

  explicit WireUnownedResult(const ::fidl::Status& result) : ::fidl::BaseWireResult<::test_service::SecondProtocol::MethodOnSecond>(result) {}
  WireUnownedResult(WireUnownedResult&&) = default;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult& operator=(WireUnownedResult&&) = default;
  WireUnownedResult& operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};

template <>
class ::fidl::internal::WireEventHandlerInterface<::test_service::SecondProtocol> : public ::fidl::internal::BaseEventHandlerInterface {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
};

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

template <>
class ::fidl::WireSyncEventHandler<::test_service::SecondProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<::test_service::SecondProtocol>, public ::fidl::internal::SyncEventHandler {
 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_service::SecondProtocol> client_end);
};

template <>
class ::fidl::internal::WireEventDispatcher<::test_service::SecondProtocol> final : public ::fidl::internal::IncomingEventDispatcher<::fidl::internal::WireEventHandlerInterface<::test_service::SecondProtocol>> {
 public:
  explicit WireEventDispatcher(::fidl::internal::WireEventHandlerInterface<::test_service::SecondProtocol>* event_handler)
      : IncomingEventDispatcher(event_handler) {}
};

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

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

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

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

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

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

  using Handler = fidl::ProtocolHandler<::test_service::SecondProtocol>;

  using MethodOnSecondCompleter = ::fidl::internal::WireCompleter<::test_service::SecondProtocol::MethodOnSecond>;

  virtual void MethodOnSecond(
      MethodOnSecondCompleter::Sync& completer) = 0;

  // |bind_handler| returns a handler that binds incoming connections to this
  // server implementation.
  //
  // The returned handler borrows the server instance.
  // The server must outlive the provided |dispatcher|. Only after
  // the dispatcher is shutdown will it be safe to destroy the servers.
  // The server should not be moved.
  Handler bind_handler(async_dispatcher_t* dispatcher) {
    return [impl = this, dispatcher = dispatcher](::fidl::ServerEnd<::test_service::SecondProtocol> request) {
      (void)::fidl::BindServer(dispatcher, std::move(request), impl);
    };
  }

 private:
  void dispatch_message(
      ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::MessageStorageViewBase* storage_view) final;
};
namespace fidl {

#endif  // __Fuchsia__

}  // namespace fidl
namespace test_service {

class EmptyService final {
  EmptyService() = default;

 public:
  static constexpr bool kIsService = true;
  static constexpr char Name[] = "test.service.EmptyService";
  using Transport = ::fidl::internal::ChannelTransport;
#ifdef __Fuchsia__
  using ServiceInstanceHandler = fidl::ServiceInstanceHandler<::fidl::internal::ChannelTransport>;

#endif  // __Fuchsia__

  // Client protocol for connecting to member protocols of a service instance.
  class ServiceClient final {
    ServiceClient() = delete;
#ifdef __Fuchsia__
   public:
    ServiceClient(::zx::channel dir, ::fidl::internal::ConnectMemberFunc connect_func) {
      (void)dir;
      (void)connect_func;
    }

   private:
#endif  // __Fuchsia__
  };
#ifdef __Fuchsia__
  // Facilitates member protocol registration for servers.
  class InstanceHandler final : public fidl::ServiceInstanceHandler<::fidl::internal::ChannelTransport> {
   public:
    struct Members {
    };

    InstanceHandler() = default;

    // Construct an instance handler for a FIDL service. It is expected that every member
    // contained in |members| is initialized with a handler.
    InstanceHandler(Members members) {
      // This should always be ZX_OK. That's because the only possible
      // error is ZX_ERR_ALREADY_EXISTS which is impossible to occur as fidlc
      // won't allow service declarations with duplicated names.
    }
  };

#endif  // __Fuchsia__
};

class SingleMemberService final {
  SingleMemberService() = default;

 public:
  static constexpr bool kIsService = true;
  static constexpr char Name[] = "test.service.SingleMemberService";
  using Transport = ::fidl::internal::ChannelTransport;
#ifdef __Fuchsia__
  using ServiceInstanceHandler = fidl::ServiceInstanceHandler<::fidl::internal::ChannelTransport>;

#endif  // __Fuchsia__

  class SingleMember final {
   public:
    static constexpr bool kIsServiceMember = true;
    static constexpr char Name[] = "single_member";
    static constexpr char ServiceName[] = "test.service.SingleMemberService";
    using ProtocolType = ::test_service::FirstProtocol;
  };

  // Client protocol for connecting to member protocols of a service instance.
  class ServiceClient final {
    ServiceClient() = delete;
#ifdef __Fuchsia__
   public:
    ServiceClient(::zx::channel dir, ::fidl::internal::ConnectMemberFunc connect_func)
        : dir_(std::move(dir)), connect_func_(connect_func) {}

    // Connects |server_end| to the member protocol "single_member".
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if there was an issue making a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end will not
    // result in a failure of this method. Any errors sent by the remote will appear on
    // the reciprocal |ClientEnd| for the |ServerEnd| passed into this method.
    ::zx::result<> connect_single_member(::fidl::ServerEnd<::test_service::FirstProtocol> server_end) {
      return connect_func_(
          ::zx::unowned_channel(dir_),
          ::fidl::StringView("single_member"),
          ::fidl::internal::MakeAnyTransport(server_end.TakeChannel()));
    }

    // Connects to the member protocol "single_member".
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if channel creation failed, or if there was an issue making
    // a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end will not
    // result in a failure of this method. Any errors sent by the remote will appear on
    // the |ClientEnd| returned from this method.
    ::zx::result<::fidl::ClientEnd<::test_service::FirstProtocol>> connect_single_member() {
      ::zx::result endpoints = ::fidl::CreateEndpoints<::test_service::FirstProtocol>();
      if (endpoints.is_error()) {
        return endpoints.take_error();
      }
      ::zx::result connection = connect_single_member(std::move(endpoints->server));
      if (connection.is_error()) {
        return connection.take_error();
      }
      return ::zx::ok(std::move(endpoints->client));
    }

   private:
    ::zx::channel dir_;
    ::fidl::internal::ConnectMemberFunc connect_func_;

#endif  // __Fuchsia__
  };
#ifdef __Fuchsia__
  // Facilitates member protocol registration for servers.
  class InstanceHandler final : public fidl::ServiceInstanceHandler<::fidl::internal::ChannelTransport> {
   public:
    struct Members {
      MemberHandler<::test_service::FirstProtocol> single_member;
    };

    InstanceHandler() = default;

    // Construct an instance handler for a FIDL service. It is expected that every member
    // contained in |members| is initialized with a handler.
    InstanceHandler(Members members) {
      // This should always be ZX_OK. That's because the only possible
      // error is ZX_ERR_ALREADY_EXISTS which is impossible to occur as fidlc
      // won't allow service declarations with duplicated names.
      ZX_ASSERT(add_single_member(std::move(members.single_member)).status_value() == ZX_OK);
    }

    // Adds member "single_member" to the service instance. |handler| will be
    // invoked on connection attempts.
    //
    // # Errors
    //
    // Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
    ::zx::result<> add_single_member(
        MemberHandler<::test_service::FirstProtocol> handler) {
      return this->AddMember<::test_service::FirstProtocol>(std::move(handler), "single_member");
    }
  };

#endif  // __Fuchsia__
};

class MultiHeterogeneousMemberService final {
  MultiHeterogeneousMemberService() = default;

 public:
  static constexpr bool kIsService = true;
  static constexpr char Name[] = "test.service.MultiHeterogeneousMemberService";
  using Transport = ::fidl::internal::ChannelTransport;
#ifdef __Fuchsia__
  using ServiceInstanceHandler = fidl::ServiceInstanceHandler<::fidl::internal::ChannelTransport>;

#endif  // __Fuchsia__

  class FirstMember final {
   public:
    static constexpr bool kIsServiceMember = true;
    static constexpr char Name[] = "first_member";
    static constexpr char ServiceName[] = "test.service.MultiHeterogeneousMemberService";
    using ProtocolType = ::test_service::FirstProtocol;
  };

  class SecondMember final {
   public:
    static constexpr bool kIsServiceMember = true;
    static constexpr char Name[] = "second_member";
    static constexpr char ServiceName[] = "test.service.MultiHeterogeneousMemberService";
    using ProtocolType = ::test_service::SecondProtocol;
  };

  // Client protocol for connecting to member protocols of a service instance.
  class ServiceClient final {
    ServiceClient() = delete;
#ifdef __Fuchsia__
   public:
    ServiceClient(::zx::channel dir, ::fidl::internal::ConnectMemberFunc connect_func)
        : dir_(std::move(dir)), connect_func_(connect_func) {}

    // Connects |server_end| to the member protocol "first_member".
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if there was an issue making a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end will not
    // result in a failure of this method. Any errors sent by the remote will appear on
    // the reciprocal |ClientEnd| for the |ServerEnd| passed into this method.
    ::zx::result<> connect_first_member(::fidl::ServerEnd<::test_service::FirstProtocol> server_end) {
      return connect_func_(
          ::zx::unowned_channel(dir_),
          ::fidl::StringView("first_member"),
          ::fidl::internal::MakeAnyTransport(server_end.TakeChannel()));
    }

    // Connects to the member protocol "first_member".
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if channel creation failed, or if there was an issue making
    // a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end will not
    // result in a failure of this method. Any errors sent by the remote will appear on
    // the |ClientEnd| returned from this method.
    ::zx::result<::fidl::ClientEnd<::test_service::FirstProtocol>> connect_first_member() {
      ::zx::result endpoints = ::fidl::CreateEndpoints<::test_service::FirstProtocol>();
      if (endpoints.is_error()) {
        return endpoints.take_error();
      }
      ::zx::result connection = connect_first_member(std::move(endpoints->server));
      if (connection.is_error()) {
        return connection.take_error();
      }
      return ::zx::ok(std::move(endpoints->client));
    }

    // Connects |server_end| to the member protocol "second_member".
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if there was an issue making a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end will not
    // result in a failure of this method. Any errors sent by the remote will appear on
    // the reciprocal |ClientEnd| for the |ServerEnd| passed into this method.
    ::zx::result<> connect_second_member(::fidl::ServerEnd<::test_service::SecondProtocol> server_end) {
      return connect_func_(
          ::zx::unowned_channel(dir_),
          ::fidl::StringView("second_member"),
          ::fidl::internal::MakeAnyTransport(server_end.TakeChannel()));
    }

    // Connects to the member protocol "second_member".
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if channel creation failed, or if there was an issue making
    // a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end will not
    // result in a failure of this method. Any errors sent by the remote will appear on
    // the |ClientEnd| returned from this method.
    ::zx::result<::fidl::ClientEnd<::test_service::SecondProtocol>> connect_second_member() {
      ::zx::result endpoints = ::fidl::CreateEndpoints<::test_service::SecondProtocol>();
      if (endpoints.is_error()) {
        return endpoints.take_error();
      }
      ::zx::result connection = connect_second_member(std::move(endpoints->server));
      if (connection.is_error()) {
        return connection.take_error();
      }
      return ::zx::ok(std::move(endpoints->client));
    }

   private:
    ::zx::channel dir_;
    ::fidl::internal::ConnectMemberFunc connect_func_;

#endif  // __Fuchsia__
  };
#ifdef __Fuchsia__
  // Facilitates member protocol registration for servers.
  class InstanceHandler final : public fidl::ServiceInstanceHandler<::fidl::internal::ChannelTransport> {
   public:
    struct Members {
      MemberHandler<::test_service::FirstProtocol> first_member;
      MemberHandler<::test_service::SecondProtocol> second_member;
    };

    InstanceHandler() = default;

    // Construct an instance handler for a FIDL service. It is expected that every member
    // contained in |members| is initialized with a handler.
    InstanceHandler(Members members) {
      // This should always be ZX_OK. That's because the only possible
      // error is ZX_ERR_ALREADY_EXISTS which is impossible to occur as fidlc
      // won't allow service declarations with duplicated names.
      ZX_ASSERT(add_first_member(std::move(members.first_member)).status_value() == ZX_OK);
      ZX_ASSERT(add_second_member(std::move(members.second_member)).status_value() == ZX_OK);
    }

    // Adds member "first_member" to the service instance. |handler| will be
    // invoked on connection attempts.
    //
    // # Errors
    //
    // Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
    ::zx::result<> add_first_member(
        MemberHandler<::test_service::FirstProtocol> handler) {
      return this->AddMember<::test_service::FirstProtocol>(std::move(handler), "first_member");
    }

    // Adds member "second_member" to the service instance. |handler| will be
    // invoked on connection attempts.
    //
    // # Errors
    //
    // Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
    ::zx::result<> add_second_member(
        MemberHandler<::test_service::SecondProtocol> handler) {
      return this->AddMember<::test_service::SecondProtocol>(std::move(handler), "second_member");
    }
  };

#endif  // __Fuchsia__
};

class MultiHomogeneousMemberService final {
  MultiHomogeneousMemberService() = default;

 public:
  static constexpr bool kIsService = true;
  static constexpr char Name[] = "test.service.MultiHomogeneousMemberService";
  using Transport = ::fidl::internal::ChannelTransport;
#ifdef __Fuchsia__
  using ServiceInstanceHandler = fidl::ServiceInstanceHandler<::fidl::internal::ChannelTransport>;

#endif  // __Fuchsia__

  class FirstMember final {
   public:
    static constexpr bool kIsServiceMember = true;
    static constexpr char Name[] = "first_member";
    static constexpr char ServiceName[] = "test.service.MultiHomogeneousMemberService";
    using ProtocolType = ::test_service::FirstProtocol;
  };

  class SecondMember final {
   public:
    static constexpr bool kIsServiceMember = true;
    static constexpr char Name[] = "second_member";
    static constexpr char ServiceName[] = "test.service.MultiHomogeneousMemberService";
    using ProtocolType = ::test_service::FirstProtocol;
  };

  // Client protocol for connecting to member protocols of a service instance.
  class ServiceClient final {
    ServiceClient() = delete;
#ifdef __Fuchsia__
   public:
    ServiceClient(::zx::channel dir, ::fidl::internal::ConnectMemberFunc connect_func)
        : dir_(std::move(dir)), connect_func_(connect_func) {}

    // Connects |server_end| to the member protocol "first_member".
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if there was an issue making a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end will not
    // result in a failure of this method. Any errors sent by the remote will appear on
    // the reciprocal |ClientEnd| for the |ServerEnd| passed into this method.
    ::zx::result<> connect_first_member(::fidl::ServerEnd<::test_service::FirstProtocol> server_end) {
      return connect_func_(
          ::zx::unowned_channel(dir_),
          ::fidl::StringView("first_member"),
          ::fidl::internal::MakeAnyTransport(server_end.TakeChannel()));
    }

    // Connects to the member protocol "first_member".
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if channel creation failed, or if there was an issue making
    // a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end will not
    // result in a failure of this method. Any errors sent by the remote will appear on
    // the |ClientEnd| returned from this method.
    ::zx::result<::fidl::ClientEnd<::test_service::FirstProtocol>> connect_first_member() {
      ::zx::result endpoints = ::fidl::CreateEndpoints<::test_service::FirstProtocol>();
      if (endpoints.is_error()) {
        return endpoints.take_error();
      }
      ::zx::result connection = connect_first_member(std::move(endpoints->server));
      if (connection.is_error()) {
        return connection.take_error();
      }
      return ::zx::ok(std::move(endpoints->client));
    }

    // Connects |server_end| to the member protocol "second_member".
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if there was an issue making a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end will not
    // result in a failure of this method. Any errors sent by the remote will appear on
    // the reciprocal |ClientEnd| for the |ServerEnd| passed into this method.
    ::zx::result<> connect_second_member(::fidl::ServerEnd<::test_service::FirstProtocol> server_end) {
      return connect_func_(
          ::zx::unowned_channel(dir_),
          ::fidl::StringView("second_member"),
          ::fidl::internal::MakeAnyTransport(server_end.TakeChannel()));
    }

    // Connects to the member protocol "second_member".
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if channel creation failed, or if there was an issue making
    // a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end will not
    // result in a failure of this method. Any errors sent by the remote will appear on
    // the |ClientEnd| returned from this method.
    ::zx::result<::fidl::ClientEnd<::test_service::FirstProtocol>> connect_second_member() {
      ::zx::result endpoints = ::fidl::CreateEndpoints<::test_service::FirstProtocol>();
      if (endpoints.is_error()) {
        return endpoints.take_error();
      }
      ::zx::result connection = connect_second_member(std::move(endpoints->server));
      if (connection.is_error()) {
        return connection.take_error();
      }
      return ::zx::ok(std::move(endpoints->client));
    }

   private:
    ::zx::channel dir_;
    ::fidl::internal::ConnectMemberFunc connect_func_;

#endif  // __Fuchsia__
  };
#ifdef __Fuchsia__
  // Facilitates member protocol registration for servers.
  class InstanceHandler final : public fidl::ServiceInstanceHandler<::fidl::internal::ChannelTransport> {
   public:
    struct Members {
      MemberHandler<::test_service::FirstProtocol> first_member;
      MemberHandler<::test_service::FirstProtocol> second_member;
    };

    InstanceHandler() = default;

    // Construct an instance handler for a FIDL service. It is expected that every member
    // contained in |members| is initialized with a handler.
    InstanceHandler(Members members) {
      // This should always be ZX_OK. That's because the only possible
      // error is ZX_ERR_ALREADY_EXISTS which is impossible to occur as fidlc
      // won't allow service declarations with duplicated names.
      ZX_ASSERT(add_first_member(std::move(members.first_member)).status_value() == ZX_OK);
      ZX_ASSERT(add_second_member(std::move(members.second_member)).status_value() == ZX_OK);
    }

    // Adds member "first_member" to the service instance. |handler| will be
    // invoked on connection attempts.
    //
    // # Errors
    //
    // Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
    ::zx::result<> add_first_member(
        MemberHandler<::test_service::FirstProtocol> handler) {
      return this->AddMember<::test_service::FirstProtocol>(std::move(handler), "first_member");
    }

    // Adds member "second_member" to the service instance. |handler| will be
    // invoked on connection attempts.
    //
    // # Errors
    //
    // Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
    ::zx::result<> add_second_member(
        MemberHandler<::test_service::FirstProtocol> handler) {
      return this->AddMember<::test_service::FirstProtocol>(std::move(handler), "second_member");
    }
  };

#endif  // __Fuchsia__
};

}  // namespace test_service
namespace fidl {

#ifdef __Fuchsia__
}  // namespace fidl

template <>
class ::fidl::internal::WireWeakOnewayClientImpl<::test_service::FirstProtocol> : public ::fidl::internal::ClientImplBase {
 public:
  using ClientImplBase::ClientImplBase;

  // Allocates 32 bytes of message buffer on the stack. No heap allocation necessary.
  ::fidl::OneWayStatus MethodOnFirst();
};

template <>
class ::fidl::internal::WireWeakAsyncClientImpl<::test_service::FirstProtocol> final : public ::fidl::internal::WireWeakOnewayClientImpl<::test_service::FirstProtocol> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};

template <>
class ::fidl::internal::WireWeakOnewayBufferClientImpl<::test_service::FirstProtocol> : public ::fidl::internal::BufferClientImplBase {
 public:
  using BufferClientImplBase::BufferClientImplBase;

  // Caller provides the backing storage for FIDL message.
  ::fidl::OneWayStatus MethodOnFirst();
};

template <>
class ::fidl::internal::WireWeakAsyncBufferClientImpl<::test_service::FirstProtocol> final : public ::fidl::internal::WireWeakOnewayBufferClientImpl<::test_service::FirstProtocol> {
 public:
  using WireWeakOnewayBufferClientImpl::WireWeakOnewayBufferClientImpl;
};
template <>
class ::fidl::internal::WireWeakSyncClientImpl<::test_service::FirstProtocol> final : public ::fidl::internal::WireWeakOnewayClientImpl<::test_service::FirstProtocol> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};
namespace fidl {

#endif  // __Fuchsia__

}  // namespace fidl

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

template <>
class ::fidl::internal::WireWeakBufferEventSender<::test_service::FirstProtocol> : public ::fidl::internal::WeakBufferEventSenderBase {
 public:
  using WeakBufferEventSenderBase::WeakBufferEventSenderBase;
};

template <>
class ::fidl::internal::WireEventSender<::test_service::FirstProtocol>
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::WireEventSender<::test_service::FirstProtocol>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

template <>
class ::fidl::internal::WireBufferEventSender<::test_service::FirstProtocol>
    : public ::fidl::internal::SyncEndpointBufferVeneer<::fidl::internal::WireBufferEventSender<::test_service::FirstProtocol>> {
 public:
  using SyncEndpointBufferVeneer::SyncEndpointBufferVeneer;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireWeakOnewayClientImpl<::test_service::SecondProtocol> : public ::fidl::internal::ClientImplBase {
 public:
  using ClientImplBase::ClientImplBase;

  // Allocates 32 bytes of message buffer on the stack. No heap allocation necessary.
  ::fidl::OneWayStatus MethodOnSecond();
};

template <>
class ::fidl::internal::WireWeakAsyncClientImpl<::test_service::SecondProtocol> final : public ::fidl::internal::WireWeakOnewayClientImpl<::test_service::SecondProtocol> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};

template <>
class ::fidl::internal::WireWeakOnewayBufferClientImpl<::test_service::SecondProtocol> : public ::fidl::internal::BufferClientImplBase {
 public:
  using BufferClientImplBase::BufferClientImplBase;

  // Caller provides the backing storage for FIDL message.
  ::fidl::OneWayStatus MethodOnSecond();
};

template <>
class ::fidl::internal::WireWeakAsyncBufferClientImpl<::test_service::SecondProtocol> final : public ::fidl::internal::WireWeakOnewayBufferClientImpl<::test_service::SecondProtocol> {
 public:
  using WireWeakOnewayBufferClientImpl::WireWeakOnewayBufferClientImpl;
};
template <>
class ::fidl::internal::WireWeakSyncClientImpl<::test_service::SecondProtocol> final : public ::fidl::internal::WireWeakOnewayClientImpl<::test_service::SecondProtocol> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};

#endif  // __Fuchsia__

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

template <>
class ::fidl::internal::WireWeakBufferEventSender<::test_service::SecondProtocol> : public ::fidl::internal::WeakBufferEventSenderBase {
 public:
  using WeakBufferEventSenderBase::WeakBufferEventSenderBase;
};

template <>
class ::fidl::internal::WireEventSender<::test_service::SecondProtocol>
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::WireEventSender<::test_service::SecondProtocol>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

template <>
class ::fidl::internal::WireBufferEventSender<::test_service::SecondProtocol>
    : public ::fidl::internal::SyncEndpointBufferVeneer<::fidl::internal::WireBufferEventSender<::test_service::SecondProtocol>> {
 public:
  using SyncEndpointBufferVeneer::SyncEndpointBufferVeneer;
};

#endif  // __Fuchsia__

#pragma clang diagnostic pop
