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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.versions/cpp/markers.h>
#include <fidl/test.versions/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_versions {

class OtherProtocol;

class Protocol;

class Service;

}  // namespace test_versions

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::test_versions::OtherProtocol> {
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireServerDispatcher<::test_versions::OtherProtocol> final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(::fidl::WireServer<::test_versions::OtherProtocol>* impl, ::fidl::IncomingHeaderAndMessage& msg,
                                            internal::MessageStorageViewBase* storage_view,
                                            ::fidl::Transaction* txn);
  static void Dispatch(::fidl::WireServer<::test_versions::OtherProtocol>* 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__

namespace fidl {

#ifdef __Fuchsia__
}  // namespace fidl

template <>
struct ::fidl::internal::IncomingEventsHandleStorage<::test_versions::OtherProtocol> final : public ::fidl::internal::ChannelHandleStorageBase<::fidl::internal::IncomingEventsHandleStorage<::test_versions::OtherProtocol>> {
 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_versions::OtherProtocol> final : public ::fidl::internal::ChannelMessageStorageBase<::fidl::internal::IncomingEventsStorage<::test_versions::OtherProtocol>> {
 public:
  ::fidl::internal::InlineMessageBuffer<24> bytes_;
  ::fidl::internal::IncomingEventsHandleStorage<::test_versions::OtherProtocol> handles_storage_;
};

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

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

template <>
class ::fidl::WireSyncEventHandler<::test_versions::OtherProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<::test_versions::OtherProtocol>, 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_versions::OtherProtocol> client_end);
};

template <>
class ::fidl::internal::WireEventDispatcher<::test_versions::OtherProtocol> final : public ::fidl::internal::IncomingEventDispatcher<::fidl::internal::WireEventHandlerInterface<::test_versions::OtherProtocol>> {
 public:
  explicit WireEventDispatcher(::fidl::internal::WireEventHandlerInterface<::test_versions::OtherProtocol>* 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_versions::OtherProtocol>|,
// avoiding setting up a client.
template <>
class ::fidl::internal::WireSyncClientImpl<::test_versions::OtherProtocol> final : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::WireSyncClientImpl<::test_versions::OtherProtocol>> {
 public:
 private:
  ::fidl::UnownedClientEnd<::test_versions::OtherProtocol> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_versions::OtherProtocol>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

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

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

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

  using Handler = fidl::ProtocolHandler<::test_versions::OtherProtocol>;

  // |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_versions::OtherProtocol> 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_versions::Protocol::Foo> final {
  static constexpr uint64_t value = 6231434419097198905lu;
};

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireMethodTypes<::test_versions::Protocol::Foo> {
  static constexpr bool HasRequestPayload = false;

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

#endif  // __Fuchsia__

namespace test_versions {

}  // namespace test_versions

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::test_versions::Protocol> {
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireServerDispatcher<::test_versions::Protocol> final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(::fidl::WireServer<::test_versions::Protocol>* impl, ::fidl::IncomingHeaderAndMessage& msg,
                                            internal::MessageStorageViewBase* storage_view,
                                            ::fidl::Transaction* txn);
  static void Dispatch(::fidl::WireServer<::test_versions::Protocol>* 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_versions::Protocol::Foo> final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  TransactionalRequest() {
    _InitHeader();
  }

 private:
  void _InitHeader();
};

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : public WireStructCodingTraitsBase<::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>, ::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_versions::Protocol::Foo>* 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_versions::Protocol::Foo>> : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>> : public std::true_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>> {
  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_versions::Protocol::Foo>) == TypeTraits<::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>, header) == 0);

#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl

template <>
struct ::fidl::internal::IncomingEventsHandleStorage<::test_versions::Protocol> final : public ::fidl::internal::ChannelHandleStorageBase<::fidl::internal::IncomingEventsHandleStorage<::test_versions::Protocol>> {
 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_versions::Protocol> final : public ::fidl::internal::ChannelMessageStorageBase<::fidl::internal::IncomingEventsStorage<::test_versions::Protocol>> {
 public:
  ::fidl::internal::InlineMessageBuffer<24> bytes_;
  ::fidl::internal::IncomingEventsHandleStorage<::test_versions::Protocol> handles_storage_;
};

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

  explicit WireResult(const ::fidl::Status& result) : ::fidl::BaseWireResult<::test_versions::Protocol::Foo>(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_versions::Protocol::Foo> final : public ::fidl::BaseWireResult<::test_versions::Protocol::Foo> {
 public:
  explicit WireUnownedResult(::fidl::UnownedClientEnd<::test_versions::Protocol> client_end, ::fidl::internal::AnyBufferAllocator& allocator, ::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo>* request);
  explicit WireUnownedResult(
      ::fit::result<::fidl::Error>&& decoded,
      ::fidl::internal::MessageStorageViewBase* storage_view) : ::fidl::BaseWireResult<::test_versions::Protocol::Foo>(::fidl::internal::StatusFromResult(decoded)) {}

  explicit WireUnownedResult(const ::fidl::Status& result) : ::fidl::BaseWireResult<::test_versions::Protocol::Foo>(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_versions::Protocol> : public ::fidl::internal::BaseEventHandlerInterface {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
};

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

template <>
class ::fidl::WireSyncEventHandler<::test_versions::Protocol>
    : public ::fidl::internal::WireEventHandlerInterface<::test_versions::Protocol>, 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_versions::Protocol> client_end);
};

template <>
class ::fidl::internal::WireEventDispatcher<::test_versions::Protocol> final : public ::fidl::internal::IncomingEventDispatcher<::fidl::internal::WireEventHandlerInterface<::test_versions::Protocol>> {
 public:
  explicit WireEventDispatcher(::fidl::internal::WireEventHandlerInterface<::test_versions::Protocol>* 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_versions::Protocol>|,
// avoiding setting up a client.
template <>
class ::fidl::internal::WireSyncClientImpl<::test_versions::Protocol> final : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::WireSyncClientImpl<::test_versions::Protocol>> {
 public:
  // Allocates 32 bytes of message buffer on the stack. No heap allocation necessary.
  ::fidl::OneWayStatus
  Foo() {
    ::fidl::internal::TransactionalRequest<::test_versions::Protocol::Foo> _request{};
    return ::fidl::WireResult<::test_versions::Protocol::Foo>(_client_end(), &_request);
  }

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

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

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

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

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

  using Handler = fidl::ProtocolHandler<::test_versions::Protocol>;

  using FooCompleter = ::fidl::internal::WireCompleter<::test_versions::Protocol::Foo>;

  virtual void Foo(
      FooCompleter::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_versions::Protocol> 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_versions {

class Service final {
  Service() = default;

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

#endif  // __Fuchsia__

  class P final {
   public:
    static constexpr bool kIsServiceMember = true;
    static constexpr char Name[] = "p";
    static constexpr char ServiceName[] = "test.versions.Service";
    using ProtocolType = ::test_versions::Protocol;
  };

  // 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 "p".
    //
    // # 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_p(::fidl::ServerEnd<::test_versions::Protocol> server_end) {
      return connect_func_(
          ::zx::unowned_channel(dir_),
          ::fidl::StringView("p"),
          ::fidl::internal::MakeAnyTransport(server_end.TakeChannel()));
    }

    // Connects to the member protocol "p".
    //
    // # 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_versions::Protocol>> connect_p() {
      ::zx::result endpoints = ::fidl::CreateEndpoints<::test_versions::Protocol>();
      if (endpoints.is_error()) {
        return endpoints.take_error();
      }
      ::zx::result connection = connect_p(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_versions::Protocol> p;
    };

    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_p(std::move(members.p)).status_value() == ZX_OK);
    }

    // Adds member "p" 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_p(
        MemberHandler<::test_versions::Protocol> handler) {
      return this->AddMember<::test_versions::Protocol>(std::move(handler), "p");
    }
  };

#endif  // __Fuchsia__
};

}  // namespace test_versions
namespace fidl {

#ifdef __Fuchsia__
}  // namespace fidl

template <>
class ::fidl::internal::WireWeakOnewayClientImpl<::test_versions::OtherProtocol> : public ::fidl::internal::ClientImplBase {
 public:
  using ClientImplBase::ClientImplBase;
};

template <>
class ::fidl::internal::WireWeakAsyncClientImpl<::test_versions::OtherProtocol> final : public ::fidl::internal::WireWeakOnewayClientImpl<::test_versions::OtherProtocol> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};

template <>
class ::fidl::internal::WireWeakOnewayBufferClientImpl<::test_versions::OtherProtocol> : public ::fidl::internal::BufferClientImplBase {
 public:
  using BufferClientImplBase::BufferClientImplBase;
};

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

#endif  // __Fuchsia__

}  // namespace fidl

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

template <>
class ::fidl::internal::WireWeakBufferEventSender<::test_versions::OtherProtocol> : public ::fidl::internal::WeakBufferEventSenderBase {
 public:
  using WeakBufferEventSenderBase::WeakBufferEventSenderBase;
};

template <>
class ::fidl::internal::WireEventSender<::test_versions::OtherProtocol>
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::WireEventSender<::test_versions::OtherProtocol>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

template <>
class ::fidl::internal::WireBufferEventSender<::test_versions::OtherProtocol>
    : public ::fidl::internal::SyncEndpointBufferVeneer<::fidl::internal::WireBufferEventSender<::test_versions::OtherProtocol>> {
 public:
  using SyncEndpointBufferVeneer::SyncEndpointBufferVeneer;
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireWeakOnewayClientImpl<::test_versions::Protocol> : public ::fidl::internal::ClientImplBase {
 public:
  using ClientImplBase::ClientImplBase;

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

template <>
class ::fidl::internal::WireWeakAsyncClientImpl<::test_versions::Protocol> final : public ::fidl::internal::WireWeakOnewayClientImpl<::test_versions::Protocol> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};

template <>
class ::fidl::internal::WireWeakOnewayBufferClientImpl<::test_versions::Protocol> : public ::fidl::internal::BufferClientImplBase {
 public:
  using BufferClientImplBase::BufferClientImplBase;

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

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

#endif  // __Fuchsia__

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

template <>
class ::fidl::internal::WireWeakBufferEventSender<::test_versions::Protocol> : public ::fidl::internal::WeakBufferEventSenderBase {
 public:
  using WeakBufferEventSenderBase::WeakBufferEventSenderBase;
};

template <>
class ::fidl::internal::WireEventSender<::test_versions::Protocol>
    : public ::fidl::internal::SyncEndpointManagedVeneer<::fidl::internal::WireEventSender<::test_versions::Protocol>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;
};

template <>
class ::fidl::internal::WireBufferEventSender<::test_versions::Protocol>
    : public ::fidl::internal::SyncEndpointBufferVeneer<::fidl::internal::WireBufferEventSender<::test_versions::Protocol>> {
 public:
  using SyncEndpointBufferVeneer::SyncEndpointBufferVeneer;
};

#endif  // __Fuchsia__

#pragma clang diagnostic pop
