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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.protocollayoutssamelibrary/cpp/wire.h>

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

namespace fidl {
namespace testing {

template <>
class WireTestBase<::test_protocollayoutssamelibrary::ComposedProtocol> : public ::fidl::WireServer<::test_protocollayoutssamelibrary::ComposedProtocol> {
 public:
  virtual ~WireTestBase<::test_protocollayoutssamelibrary::ComposedProtocol>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
  virtual void OneWayAnonComposed(
      ::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest* request,
      OneWayAnonComposedCompleter::Sync& completer) override {
    NotImplemented_("OneWayAnonComposed", completer);
  }
  virtual void TwoWayAnonComposed(
      ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest* request,
      TwoWayAnonComposedCompleter::Sync& completer) override {
    NotImplemented_("TwoWayAnonComposed", completer);
  }
  virtual void TwoWayAnonComposedWithError(
      ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest* request,
      TwoWayAnonComposedWithErrorCompleter::Sync& completer) override {
    NotImplemented_("TwoWayAnonComposedWithError", completer);
  }
  virtual void OneWayNamedComposed(
      ::test_protocollayoutssamelibrary::wire::TablePayload* request,
      OneWayNamedComposedCompleter::Sync& completer) override {
    NotImplemented_("OneWayNamedComposed", completer);
  }
  virtual void TwoWayNamedComposed(
      ::test_protocollayoutssamelibrary::wire::UnionPayload* request,
      TwoWayNamedComposedCompleter::Sync& completer) override {
    NotImplemented_("TwoWayNamedComposed", completer);
  }
  virtual void TwoWayNamedComposedWithError(
      ::test_protocollayoutssamelibrary::wire::TablePayload* request,
      TwoWayNamedComposedWithErrorCompleter::Sync& completer) override {
    NotImplemented_("TwoWayNamedComposedWithError", completer);
  }
};

template <>
class WireSyncEventHandlerTestBase<::test_protocollayoutssamelibrary::ComposedProtocol> : public ::fidl::WireSyncEventHandler<::test_protocollayoutssamelibrary::ComposedProtocol> {
 public:
  virtual ~WireSyncEventHandlerTestBase<::test_protocollayoutssamelibrary::ComposedProtocol>() = default;
  virtual void NotImplemented_(const std::string& name) = 0;
  void OnAnonComposed(::fidl::WireEvent<::test_protocollayoutssamelibrary::ComposedProtocol::OnAnonComposed>* event) override {
    NotImplemented_("OnAnonComposed");
  }
  void OnNamedComposed(::fidl::WireEvent<::test_protocollayoutssamelibrary::ComposedProtocol::OnNamedComposed>* event) override {
    NotImplemented_("OnNamedComposed");
  }
};

template <>
class WireTestBase<::test_protocollayoutssamelibrary::MainProtocol> : public ::fidl::WireServer<::test_protocollayoutssamelibrary::MainProtocol> {
 public:
  virtual ~WireTestBase<::test_protocollayoutssamelibrary::MainProtocol>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
  virtual void OneWayAnonComposed(
      ::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest* request,
      OneWayAnonComposedCompleter::Sync& completer) override {
    NotImplemented_("OneWayAnonComposed", completer);
  }
  virtual void TwoWayAnonComposed(
      ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest* request,
      TwoWayAnonComposedCompleter::Sync& completer) override {
    NotImplemented_("TwoWayAnonComposed", completer);
  }
  virtual void TwoWayAnonComposedWithError(
      ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest* request,
      TwoWayAnonComposedWithErrorCompleter::Sync& completer) override {
    NotImplemented_("TwoWayAnonComposedWithError", completer);
  }
  virtual void OneWayNamedComposed(
      ::test_protocollayoutssamelibrary::wire::TablePayload* request,
      OneWayNamedComposedCompleter::Sync& completer) override {
    NotImplemented_("OneWayNamedComposed", completer);
  }
  virtual void TwoWayNamedComposed(
      ::test_protocollayoutssamelibrary::wire::UnionPayload* request,
      TwoWayNamedComposedCompleter::Sync& completer) override {
    NotImplemented_("TwoWayNamedComposed", completer);
  }
  virtual void TwoWayNamedComposedWithError(
      ::test_protocollayoutssamelibrary::wire::TablePayload* request,
      TwoWayNamedComposedWithErrorCompleter::Sync& completer) override {
    NotImplemented_("TwoWayNamedComposedWithError", completer);
  }
  virtual void OneWayLocal(
      ::test_protocollayoutssamelibrary::wire::TablePayload* request,
      OneWayLocalCompleter::Sync& completer) override {
    NotImplemented_("OneWayLocal", completer);
  }
  virtual void TwoWayLocal(
      ::test_protocollayoutssamelibrary::wire::UnionPayload* request,
      TwoWayLocalCompleter::Sync& completer) override {
    NotImplemented_("TwoWayLocal", completer);
  }
  virtual void TwoWayLocalWithError(
      ::test_protocollayoutssamelibrary::wire::TablePayload* request,
      TwoWayLocalWithErrorCompleter::Sync& completer) override {
    NotImplemented_("TwoWayLocalWithError", completer);
  }
  virtual void OneWayAnon(
      ::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest* request,
      OneWayAnonCompleter::Sync& completer) override {
    NotImplemented_("OneWayAnon", completer);
  }
  virtual void TwoWayAnon(
      ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest* request,
      TwoWayAnonCompleter::Sync& completer) override {
    NotImplemented_("TwoWayAnon", completer);
  }
  virtual void TwoWayAnonWithError(
      ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest* request,
      TwoWayAnonWithErrorCompleter::Sync& completer) override {
    NotImplemented_("TwoWayAnonWithError", completer);
  }
};

template <>
class WireSyncEventHandlerTestBase<::test_protocollayoutssamelibrary::MainProtocol> : public ::fidl::WireSyncEventHandler<::test_protocollayoutssamelibrary::MainProtocol> {
 public:
  virtual ~WireSyncEventHandlerTestBase<::test_protocollayoutssamelibrary::MainProtocol>() = default;
  virtual void NotImplemented_(const std::string& name) = 0;
  void OnAnonComposed(::fidl::WireEvent<::test_protocollayoutssamelibrary::MainProtocol::OnAnonComposed>* event) override {
    NotImplemented_("OnAnonComposed");
  }
  void OnNamedComposed(::fidl::WireEvent<::test_protocollayoutssamelibrary::MainProtocol::OnNamedComposed>* event) override {
    NotImplemented_("OnNamedComposed");
  }
  void OnLocal(::fidl::WireEvent<::test_protocollayoutssamelibrary::MainProtocol::OnLocal>* event) override {
    NotImplemented_("OnLocal");
  }
  void OnAnon(::fidl::WireEvent<::test_protocollayoutssamelibrary::MainProtocol::OnAnon>* event) override {
    NotImplemented_("OnAnon");
  }
};
#pragma clang diagnostic pop

}  // namespace testing
}  // namespace fidl
