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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.protocols/cpp/fidl.h>

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

namespace fidl {
namespace testing {

template <>
class TestBase<::test_protocols::WithAndWithoutRequestResponse> : public ::fidl::Server<::test_protocols::WithAndWithoutRequestResponse> {
 public:
  virtual ~TestBase<::test_protocols::WithAndWithoutRequestResponse>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
  virtual void NoRequestNoResponse(
      NoRequestNoResponseCompleter::Sync& completer) {
    NotImplemented_("NoRequestNoResponse", completer);
  }
  virtual void NoRequestEmptyResponse(
      NoRequestEmptyResponseCompleter::Sync& completer) {
    NotImplemented_("NoRequestEmptyResponse", completer);
  }
  virtual void NoRequestWithResponse(
      NoRequestWithResponseCompleter::Sync& completer) {
    NotImplemented_("NoRequestWithResponse", completer);
  }
  virtual void WithRequestNoResponse(WithRequestNoResponseRequest& request,
                                     WithRequestNoResponseCompleter::Sync& completer) {
    NotImplemented_("WithRequestNoResponse", completer);
  }
  virtual void WithRequestEmptyResponse(WithRequestEmptyResponseRequest& request,
                                        WithRequestEmptyResponseCompleter::Sync& completer) {
    NotImplemented_("WithRequestEmptyResponse", completer);
  }
  virtual void WithRequestWithResponse(WithRequestWithResponseRequest& request,
                                       WithRequestWithResponseCompleter::Sync& completer) {
    NotImplemented_("WithRequestWithResponse", completer);
  }
};

template <>
class TestBase<::test_protocols::WithErrorSyntax> : public ::fidl::Server<::test_protocols::WithErrorSyntax> {
 public:
  virtual ~TestBase<::test_protocols::WithErrorSyntax>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
  virtual void ResponseAsStruct(
      ResponseAsStructCompleter::Sync& completer) {
    NotImplemented_("ResponseAsStruct", completer);
  }
  virtual void ErrorAsPrimitive(
      ErrorAsPrimitiveCompleter::Sync& completer) {
    NotImplemented_("ErrorAsPrimitive", completer);
  }
  virtual void ErrorAsEnum(
      ErrorAsEnumCompleter::Sync& completer) {
    NotImplemented_("ErrorAsEnum", completer);
  }
  virtual void HandleInResult(
      HandleInResultCompleter::Sync& completer) {
    NotImplemented_("HandleInResult", completer);
  }
};

template <>
class TestBase<::test_protocols::ChannelProtocol> : public ::fidl::Server<::test_protocols::ChannelProtocol> {
 public:
  virtual ~TestBase<::test_protocols::ChannelProtocol>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
  virtual void MethodA(MethodARequest& request,
                       MethodACompleter::Sync& completer) {
    NotImplemented_("MethodA", completer);
  }
  virtual void MethodB(MethodBRequest& request,
                       MethodBCompleter::Sync& completer) {
    NotImplemented_("MethodB", completer);
  }
  virtual void TakeHandle(TakeHandleRequest& request,
                          TakeHandleCompleter::Sync& completer) {
    NotImplemented_("TakeHandle", completer);
  }
  virtual void MutateSocket(MutateSocketRequest& request,
                            MutateSocketCompleter::Sync& completer) {
    NotImplemented_("MutateSocket", completer);
  }
};

template <>
class TestBase<::test_protocols::DiscoverableProtocol> : public ::fidl::Server<::test_protocols::DiscoverableProtocol> {
 public:
  virtual ~TestBase<::test_protocols::DiscoverableProtocol>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
  virtual void Method(
      MethodCompleter::Sync& completer) {
    NotImplemented_("Method", completer);
  }
};

template <>
class TestBase<::test_protocols::AnotherDiscoverableProtocol> : public ::fidl::Server<::test_protocols::AnotherDiscoverableProtocol> {
 public:
  virtual ~TestBase<::test_protocols::AnotherDiscoverableProtocol>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
};

template <>
class TestBase<::test_protocols::PlatformServer> : public ::fidl::Server<::test_protocols::PlatformServer> {
 public:
  virtual ~TestBase<::test_protocols::PlatformServer>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
};

template <>
class TestBase<::test_protocols::HandleRightsProtocol> : public ::fidl::Server<::test_protocols::HandleRightsProtocol> {
 public:
  virtual ~TestBase<::test_protocols::HandleRightsProtocol>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
  virtual void NoResponseMethod(NoResponseMethodRequest& request,
                                NoResponseMethodCompleter::Sync& completer) {
    NotImplemented_("NoResponseMethod", completer);
  }
  virtual void ResponseMethod(ResponseMethodRequest& request,
                              ResponseMethodCompleter::Sync& completer) {
    NotImplemented_("ResponseMethod", completer);
  }
};

template <>
class TestBase<::test_protocols::WithProtocolEnds> : public ::fidl::Server<::test_protocols::WithProtocolEnds> {
 public:
  virtual ~TestBase<::test_protocols::WithProtocolEnds>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
  virtual void ClientEnds(ClientEndsRequest& request,
                          ClientEndsCompleter::Sync& completer) {
    NotImplemented_("ClientEnds", completer);
  }
  virtual void ServerEnds(ServerEndsRequest& request,
                          ServerEndsCompleter::Sync& completer) {
    NotImplemented_("ServerEnds", completer);
  }
  virtual void StructContainingEnds(StructContainingEndsRequest& request,
                                    StructContainingEndsCompleter::Sync& completer) {
    NotImplemented_("StructContainingEnds", completer);
  }
};

template <>
class TestBase<::test_protocols::ManyParameters> : public ::fidl::Server<::test_protocols::ManyParameters> {
 public:
  virtual ~TestBase<::test_protocols::ManyParameters>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
  virtual void Fifteen(FifteenRequest& request,
                       FifteenCompleter::Sync& completer) {
    NotImplemented_("Fifteen", completer);
  }
};

template <>
class TestBase<::test_protocols::MethodWithUnion> : public ::fidl::Server<::test_protocols::MethodWithUnion> {
 public:
  virtual ~TestBase<::test_protocols::MethodWithUnion>() = default;
  virtual void NotImplemented_(const std::string& name, ::fidl::CompleterBase& completer) = 0;
  virtual void UnionMethod(UnionMethodRequest& request,
                           UnionMethodCompleter::Sync& completer) {
    NotImplemented_("UnionMethod", completer);
  }
};
#pragma clang diagnostic pop

}  // namespace testing
}  // namespace fidl
