// Generated by the gRPC C++ plugin.
// If you make any local change, they will be lost.
// source: dmi/hw_metrics_mgmt_service.proto
#ifndef GRPC_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto__INCLUDED
#define GRPC_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto__INCLUDED

#include "dmi/hw_metrics_mgmt_service.pb.h"

#include <functional>
#include <grpc/impl/codegen/port_platform.h>
#include <grpcpp/impl/codegen/async_generic_service.h>
#include <grpcpp/impl/codegen/async_stream.h>
#include <grpcpp/impl/codegen/async_unary_call.h>
#include <grpcpp/impl/codegen/client_callback.h>
#include <grpcpp/impl/codegen/client_context.h>
#include <grpcpp/impl/codegen/completion_queue.h>
#include <grpcpp/impl/codegen/message_allocator.h>
#include <grpcpp/impl/codegen/method_handler.h>
#include <grpcpp/impl/codegen/proto_utils.h>
#include <grpcpp/impl/codegen/rpc_method.h>
#include <grpcpp/impl/codegen/server_callback.h>
#include <grpcpp/impl/codegen/server_callback_handlers.h>
#include <grpcpp/impl/codegen/server_context.h>
#include <grpcpp/impl/codegen/service_type.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/stub_options.h>
#include <grpcpp/impl/codegen/sync_stream.h>

namespace dmi {

class NativeMetricsManagementService final {
 public:
  static constexpr char const* service_full_name() {
    return "dmi.NativeMetricsManagementService";
  }
  class StubInterface {
   public:
    virtual ~StubInterface() {}
    // List the supported metrics for the passed device.
    // This would be the first call that you make to know about the metrics that a particular device supports and
    // then use the UpdateMetricsConfiguration API to monitor only the required metrics.
    virtual ::grpc::Status ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::ListMetricsResponse* response) = 0;
    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>> AsyncListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>>(AsyncListMetricsRaw(context, request, cq));
    }
    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>> PrepareAsyncListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>>(PrepareAsyncListMetricsRaw(context, request, cq));
    }
    // Updates the configuration of the list of metrics in the request
    // Acts upon single metric configuration, collection of a single metric can be started/stopped
    // by changing its configuration.
    // 
    // This configuration is persisted across restart of the device or the device manager
    virtual ::grpc::Status UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::dmi::MetricsConfigurationResponse* response) = 0;
    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>> AsyncUpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>>(AsyncUpdateMetricsConfigurationRaw(context, request, cq));
    }
    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>> PrepareAsyncUpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>>(PrepareAsyncUpdateMetricsConfigurationRaw(context, request, cq));
    }
    // Get the instantenous value of a metric
    virtual ::grpc::Status GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::dmi::GetMetricResponse* response) = 0;
    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>> AsyncGetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>>(AsyncGetMetricRaw(context, request, cq));
    }
    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>> PrepareAsyncGetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>>(PrepareAsyncGetMetricRaw(context, request, cq));
    }
    class experimental_async_interface {
     public:
      virtual ~experimental_async_interface() {}
      // List the supported metrics for the passed device.
      // This would be the first call that you make to know about the metrics that a particular device supports and
      // then use the UpdateMetricsConfiguration API to monitor only the required metrics.
      virtual void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, std::function<void(::grpc::Status)>) = 0;
      virtual void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, std::function<void(::grpc::Status)>) = 0;
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      virtual void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
      #else
      virtual void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
      #endif
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      virtual void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
      #else
      virtual void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
      #endif
      // Updates the configuration of the list of metrics in the request
      // Acts upon single metric configuration, collection of a single metric can be started/stopped
      // by changing its configuration.
      // 
      // This configuration is persisted across restart of the device or the device manager
      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, std::function<void(::grpc::Status)>) = 0;
      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, std::function<void(::grpc::Status)>) = 0;
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
      #else
      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
      #endif
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
      #else
      virtual void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
      #endif
      // Get the instantenous value of a metric
      virtual void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, std::function<void(::grpc::Status)>) = 0;
      virtual void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, std::function<void(::grpc::Status)>) = 0;
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      virtual void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
      #else
      virtual void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
      #endif
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      virtual void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
      #else
      virtual void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
      #endif
    };
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
    typedef class experimental_async_interface async_interface;
    #endif
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
    async_interface* async() { return experimental_async(); }
    #endif
    virtual class experimental_async_interface* experimental_async() { return nullptr; }
  private:
    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>* AsyncListMetricsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ListMetricsResponse>* PrepareAsyncListMetricsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) = 0;
    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>* AsyncUpdateMetricsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) = 0;
    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::MetricsConfigurationResponse>* PrepareAsyncUpdateMetricsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) = 0;
    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>* AsyncGetMetricRaw(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) = 0;
    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetMetricResponse>* PrepareAsyncGetMetricRaw(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) = 0;
  };
  class Stub final : public StubInterface {
   public:
    Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);
    ::grpc::Status ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::dmi::ListMetricsResponse* response) override;
    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>> AsyncListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>>(AsyncListMetricsRaw(context, request, cq));
    }
    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>> PrepareAsyncListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>>(PrepareAsyncListMetricsRaw(context, request, cq));
    }
    ::grpc::Status UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::dmi::MetricsConfigurationResponse* response) override;
    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>> AsyncUpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>>(AsyncUpdateMetricsConfigurationRaw(context, request, cq));
    }
    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>> PrepareAsyncUpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>>(PrepareAsyncUpdateMetricsConfigurationRaw(context, request, cq));
    }
    ::grpc::Status GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::dmi::GetMetricResponse* response) override;
    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>> AsyncGetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>>(AsyncGetMetricRaw(context, request, cq));
    }
    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>> PrepareAsyncGetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) {
      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>>(PrepareAsyncGetMetricRaw(context, request, cq));
    }
    class experimental_async final :
      public StubInterface::experimental_async_interface {
     public:
      void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, std::function<void(::grpc::Status)>) override;
      void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, std::function<void(::grpc::Status)>) override;
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
      #else
      void ListMetrics(::grpc::ClientContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
      #endif
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
      #else
      void ListMetrics(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ListMetricsResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
      #endif
      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, std::function<void(::grpc::Status)>) override;
      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, std::function<void(::grpc::Status)>) override;
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
      #else
      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
      #endif
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
      #else
      void UpdateMetricsConfiguration(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::MetricsConfigurationResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
      #endif
      void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, std::function<void(::grpc::Status)>) override;
      void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, std::function<void(::grpc::Status)>) override;
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
      #else
      void GetMetric(::grpc::ClientContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
      #endif
      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
      #else
      void GetMetric(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetMetricResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
      #endif
     private:
      friend class Stub;
      explicit experimental_async(Stub* stub): stub_(stub) { }
      Stub* stub() { return stub_; }
      Stub* stub_;
    };
    class experimental_async_interface* experimental_async() override { return &async_stub_; }

   private:
    std::shared_ptr< ::grpc::ChannelInterface> channel_;
    class experimental_async async_stub_{this};
    ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>* AsyncListMetricsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
    ::grpc::ClientAsyncResponseReader< ::dmi::ListMetricsResponse>* PrepareAsyncListMetricsRaw(::grpc::ClientContext* context, const ::dmi::HardwareID& request, ::grpc::CompletionQueue* cq) override;
    ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>* AsyncUpdateMetricsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) override;
    ::grpc::ClientAsyncResponseReader< ::dmi::MetricsConfigurationResponse>* PrepareAsyncUpdateMetricsConfigurationRaw(::grpc::ClientContext* context, const ::dmi::MetricsConfigurationRequest& request, ::grpc::CompletionQueue* cq) override;
    ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>* AsyncGetMetricRaw(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) override;
    ::grpc::ClientAsyncResponseReader< ::dmi::GetMetricResponse>* PrepareAsyncGetMetricRaw(::grpc::ClientContext* context, const ::dmi::GetMetricRequest& request, ::grpc::CompletionQueue* cq) override;
    const ::grpc::internal::RpcMethod rpcmethod_ListMetrics_;
    const ::grpc::internal::RpcMethod rpcmethod_UpdateMetricsConfiguration_;
    const ::grpc::internal::RpcMethod rpcmethod_GetMetric_;
  };
  static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());

  class Service : public ::grpc::Service {
   public:
    Service();
    virtual ~Service();
    // List the supported metrics for the passed device.
    // This would be the first call that you make to know about the metrics that a particular device supports and
    // then use the UpdateMetricsConfiguration API to monitor only the required metrics.
    virtual ::grpc::Status ListMetrics(::grpc::ServerContext* context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response);
    // Updates the configuration of the list of metrics in the request
    // Acts upon single metric configuration, collection of a single metric can be started/stopped
    // by changing its configuration.
    // 
    // This configuration is persisted across restart of the device or the device manager
    virtual ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response);
    // Get the instantenous value of a metric
    virtual ::grpc::Status GetMetric(::grpc::ServerContext* context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response);
  };
  template <class BaseClass>
  class WithAsyncMethod_ListMetrics : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithAsyncMethod_ListMetrics() {
      ::grpc::Service::MarkMethodAsync(0);
    }
    ~WithAsyncMethod_ListMetrics() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    void RequestListMetrics(::grpc::ServerContext* context, ::dmi::HardwareID* request, ::grpc::ServerAsyncResponseWriter< ::dmi::ListMetricsResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
    }
  };
  template <class BaseClass>
  class WithAsyncMethod_UpdateMetricsConfiguration : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithAsyncMethod_UpdateMetricsConfiguration() {
      ::grpc::Service::MarkMethodAsync(1);
    }
    ~WithAsyncMethod_UpdateMetricsConfiguration() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    void RequestUpdateMetricsConfiguration(::grpc::ServerContext* context, ::dmi::MetricsConfigurationRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::MetricsConfigurationResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
      ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
    }
  };
  template <class BaseClass>
  class WithAsyncMethod_GetMetric : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithAsyncMethod_GetMetric() {
      ::grpc::Service::MarkMethodAsync(2);
    }
    ~WithAsyncMethod_GetMetric() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    void RequestGetMetric(::grpc::ServerContext* context, ::dmi::GetMetricRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::GetMetricResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
      ::grpc::Service::RequestAsyncUnary(2, context, request, response, new_call_cq, notification_cq, tag);
    }
  };
  typedef WithAsyncMethod_ListMetrics<WithAsyncMethod_UpdateMetricsConfiguration<WithAsyncMethod_GetMetric<Service > > > AsyncService;
  template <class BaseClass>
  class ExperimentalWithCallbackMethod_ListMetrics : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    ExperimentalWithCallbackMethod_ListMetrics() {
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      ::grpc::Service::
    #else
      ::grpc::Service::experimental().
    #endif
        MarkMethodCallback(0,
          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HardwareID, ::dmi::ListMetricsResponse>(
            [this](
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
                   ::grpc::CallbackServerContext*
    #else
                   ::grpc::experimental::CallbackServerContext*
    #endif
                     context, const ::dmi::HardwareID* request, ::dmi::ListMetricsResponse* response) { return this->ListMetrics(context, request, response); }));}
    void SetMessageAllocatorFor_ListMetrics(
        ::grpc::experimental::MessageAllocator< ::dmi::HardwareID, ::dmi::ListMetricsResponse>* allocator) {
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(0);
    #else
      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(0);
    #endif
      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::HardwareID, ::dmi::ListMetricsResponse>*>(handler)
              ->SetMessageAllocator(allocator);
    }
    ~ExperimentalWithCallbackMethod_ListMetrics() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
    virtual ::grpc::ServerUnaryReactor* ListMetrics(
      ::grpc::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/)
    #else
    virtual ::grpc::experimental::ServerUnaryReactor* ListMetrics(
      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/)
    #endif
      { return nullptr; }
  };
  template <class BaseClass>
  class ExperimentalWithCallbackMethod_UpdateMetricsConfiguration : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    ExperimentalWithCallbackMethod_UpdateMetricsConfiguration() {
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      ::grpc::Service::
    #else
      ::grpc::Service::experimental().
    #endif
        MarkMethodCallback(1,
          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::MetricsConfigurationRequest, ::dmi::MetricsConfigurationResponse>(
            [this](
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
                   ::grpc::CallbackServerContext*
    #else
                   ::grpc::experimental::CallbackServerContext*
    #endif
                     context, const ::dmi::MetricsConfigurationRequest* request, ::dmi::MetricsConfigurationResponse* response) { return this->UpdateMetricsConfiguration(context, request, response); }));}
    void SetMessageAllocatorFor_UpdateMetricsConfiguration(
        ::grpc::experimental::MessageAllocator< ::dmi::MetricsConfigurationRequest, ::dmi::MetricsConfigurationResponse>* allocator) {
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(1);
    #else
      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(1);
    #endif
      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::MetricsConfigurationRequest, ::dmi::MetricsConfigurationResponse>*>(handler)
              ->SetMessageAllocator(allocator);
    }
    ~ExperimentalWithCallbackMethod_UpdateMetricsConfiguration() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
    virtual ::grpc::ServerUnaryReactor* UpdateMetricsConfiguration(
      ::grpc::CallbackServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/)
    #else
    virtual ::grpc::experimental::ServerUnaryReactor* UpdateMetricsConfiguration(
      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/)
    #endif
      { return nullptr; }
  };
  template <class BaseClass>
  class ExperimentalWithCallbackMethod_GetMetric : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    ExperimentalWithCallbackMethod_GetMetric() {
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      ::grpc::Service::
    #else
      ::grpc::Service::experimental().
    #endif
        MarkMethodCallback(2,
          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::GetMetricRequest, ::dmi::GetMetricResponse>(
            [this](
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
                   ::grpc::CallbackServerContext*
    #else
                   ::grpc::experimental::CallbackServerContext*
    #endif
                     context, const ::dmi::GetMetricRequest* request, ::dmi::GetMetricResponse* response) { return this->GetMetric(context, request, response); }));}
    void SetMessageAllocatorFor_GetMetric(
        ::grpc::experimental::MessageAllocator< ::dmi::GetMetricRequest, ::dmi::GetMetricResponse>* allocator) {
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(2);
    #else
      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(2);
    #endif
      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::GetMetricRequest, ::dmi::GetMetricResponse>*>(handler)
              ->SetMessageAllocator(allocator);
    }
    ~ExperimentalWithCallbackMethod_GetMetric() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
    virtual ::grpc::ServerUnaryReactor* GetMetric(
      ::grpc::CallbackServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/)
    #else
    virtual ::grpc::experimental::ServerUnaryReactor* GetMetric(
      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/)
    #endif
      { return nullptr; }
  };
  #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
  typedef ExperimentalWithCallbackMethod_ListMetrics<ExperimentalWithCallbackMethod_UpdateMetricsConfiguration<ExperimentalWithCallbackMethod_GetMetric<Service > > > CallbackService;
  #endif

  typedef ExperimentalWithCallbackMethod_ListMetrics<ExperimentalWithCallbackMethod_UpdateMetricsConfiguration<ExperimentalWithCallbackMethod_GetMetric<Service > > > ExperimentalCallbackService;
  template <class BaseClass>
  class WithGenericMethod_ListMetrics : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithGenericMethod_ListMetrics() {
      ::grpc::Service::MarkMethodGeneric(0);
    }
    ~WithGenericMethod_ListMetrics() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
  };
  template <class BaseClass>
  class WithGenericMethod_UpdateMetricsConfiguration : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithGenericMethod_UpdateMetricsConfiguration() {
      ::grpc::Service::MarkMethodGeneric(1);
    }
    ~WithGenericMethod_UpdateMetricsConfiguration() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
  };
  template <class BaseClass>
  class WithGenericMethod_GetMetric : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithGenericMethod_GetMetric() {
      ::grpc::Service::MarkMethodGeneric(2);
    }
    ~WithGenericMethod_GetMetric() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
  };
  template <class BaseClass>
  class WithRawMethod_ListMetrics : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithRawMethod_ListMetrics() {
      ::grpc::Service::MarkMethodRaw(0);
    }
    ~WithRawMethod_ListMetrics() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    void RequestListMetrics(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
    }
  };
  template <class BaseClass>
  class WithRawMethod_UpdateMetricsConfiguration : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithRawMethod_UpdateMetricsConfiguration() {
      ::grpc::Service::MarkMethodRaw(1);
    }
    ~WithRawMethod_UpdateMetricsConfiguration() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    void RequestUpdateMetricsConfiguration(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
      ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
    }
  };
  template <class BaseClass>
  class WithRawMethod_GetMetric : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithRawMethod_GetMetric() {
      ::grpc::Service::MarkMethodRaw(2);
    }
    ~WithRawMethod_GetMetric() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    void RequestGetMetric(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
      ::grpc::Service::RequestAsyncUnary(2, context, request, response, new_call_cq, notification_cq, tag);
    }
  };
  template <class BaseClass>
  class ExperimentalWithRawCallbackMethod_ListMetrics : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    ExperimentalWithRawCallbackMethod_ListMetrics() {
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      ::grpc::Service::
    #else
      ::grpc::Service::experimental().
    #endif
        MarkMethodRawCallback(0,
          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
            [this](
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
                   ::grpc::CallbackServerContext*
    #else
                   ::grpc::experimental::CallbackServerContext*
    #endif
                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ListMetrics(context, request, response); }));
    }
    ~ExperimentalWithRawCallbackMethod_ListMetrics() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
    virtual ::grpc::ServerUnaryReactor* ListMetrics(
      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
    #else
    virtual ::grpc::experimental::ServerUnaryReactor* ListMetrics(
      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
    #endif
      { return nullptr; }
  };
  template <class BaseClass>
  class ExperimentalWithRawCallbackMethod_UpdateMetricsConfiguration : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    ExperimentalWithRawCallbackMethod_UpdateMetricsConfiguration() {
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      ::grpc::Service::
    #else
      ::grpc::Service::experimental().
    #endif
        MarkMethodRawCallback(1,
          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
            [this](
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
                   ::grpc::CallbackServerContext*
    #else
                   ::grpc::experimental::CallbackServerContext*
    #endif
                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->UpdateMetricsConfiguration(context, request, response); }));
    }
    ~ExperimentalWithRawCallbackMethod_UpdateMetricsConfiguration() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
    virtual ::grpc::ServerUnaryReactor* UpdateMetricsConfiguration(
      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
    #else
    virtual ::grpc::experimental::ServerUnaryReactor* UpdateMetricsConfiguration(
      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
    #endif
      { return nullptr; }
  };
  template <class BaseClass>
  class ExperimentalWithRawCallbackMethod_GetMetric : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    ExperimentalWithRawCallbackMethod_GetMetric() {
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
      ::grpc::Service::
    #else
      ::grpc::Service::experimental().
    #endif
        MarkMethodRawCallback(2,
          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
            [this](
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
                   ::grpc::CallbackServerContext*
    #else
                   ::grpc::experimental::CallbackServerContext*
    #endif
                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetMetric(context, request, response); }));
    }
    ~ExperimentalWithRawCallbackMethod_GetMetric() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable synchronous version of this method
    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
    virtual ::grpc::ServerUnaryReactor* GetMetric(
      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
    #else
    virtual ::grpc::experimental::ServerUnaryReactor* GetMetric(
      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
    #endif
      { return nullptr; }
  };
  template <class BaseClass>
  class WithStreamedUnaryMethod_ListMetrics : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithStreamedUnaryMethod_ListMetrics() {
      ::grpc::Service::MarkMethodStreamed(0,
        new ::grpc::internal::StreamedUnaryHandler<
          ::dmi::HardwareID, ::dmi::ListMetricsResponse>(
            [this](::grpc_impl::ServerContext* context,
                   ::grpc_impl::ServerUnaryStreamer<
                     ::dmi::HardwareID, ::dmi::ListMetricsResponse>* streamer) {
                       return this->StreamedListMetrics(context,
                         streamer);
                  }));
    }
    ~WithStreamedUnaryMethod_ListMetrics() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable regular version of this method
    ::grpc::Status ListMetrics(::grpc::ServerContext* /*context*/, const ::dmi::HardwareID* /*request*/, ::dmi::ListMetricsResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    // replace default version of method with streamed unary
    virtual ::grpc::Status StreamedListMetrics(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::HardwareID,::dmi::ListMetricsResponse>* server_unary_streamer) = 0;
  };
  template <class BaseClass>
  class WithStreamedUnaryMethod_UpdateMetricsConfiguration : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithStreamedUnaryMethod_UpdateMetricsConfiguration() {
      ::grpc::Service::MarkMethodStreamed(1,
        new ::grpc::internal::StreamedUnaryHandler<
          ::dmi::MetricsConfigurationRequest, ::dmi::MetricsConfigurationResponse>(
            [this](::grpc_impl::ServerContext* context,
                   ::grpc_impl::ServerUnaryStreamer<
                     ::dmi::MetricsConfigurationRequest, ::dmi::MetricsConfigurationResponse>* streamer) {
                       return this->StreamedUpdateMetricsConfiguration(context,
                         streamer);
                  }));
    }
    ~WithStreamedUnaryMethod_UpdateMetricsConfiguration() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable regular version of this method
    ::grpc::Status UpdateMetricsConfiguration(::grpc::ServerContext* /*context*/, const ::dmi::MetricsConfigurationRequest* /*request*/, ::dmi::MetricsConfigurationResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    // replace default version of method with streamed unary
    virtual ::grpc::Status StreamedUpdateMetricsConfiguration(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::MetricsConfigurationRequest,::dmi::MetricsConfigurationResponse>* server_unary_streamer) = 0;
  };
  template <class BaseClass>
  class WithStreamedUnaryMethod_GetMetric : public BaseClass {
   private:
    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
   public:
    WithStreamedUnaryMethod_GetMetric() {
      ::grpc::Service::MarkMethodStreamed(2,
        new ::grpc::internal::StreamedUnaryHandler<
          ::dmi::GetMetricRequest, ::dmi::GetMetricResponse>(
            [this](::grpc_impl::ServerContext* context,
                   ::grpc_impl::ServerUnaryStreamer<
                     ::dmi::GetMetricRequest, ::dmi::GetMetricResponse>* streamer) {
                       return this->StreamedGetMetric(context,
                         streamer);
                  }));
    }
    ~WithStreamedUnaryMethod_GetMetric() override {
      BaseClassMustBeDerivedFromService(this);
    }
    // disable regular version of this method
    ::grpc::Status GetMetric(::grpc::ServerContext* /*context*/, const ::dmi::GetMetricRequest* /*request*/, ::dmi::GetMetricResponse* /*response*/) override {
      abort();
      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
    }
    // replace default version of method with streamed unary
    virtual ::grpc::Status StreamedGetMetric(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::GetMetricRequest,::dmi::GetMetricResponse>* server_unary_streamer) = 0;
  };
  typedef WithStreamedUnaryMethod_ListMetrics<WithStreamedUnaryMethod_UpdateMetricsConfiguration<WithStreamedUnaryMethod_GetMetric<Service > > > StreamedUnaryService;
  typedef Service SplitStreamedService;
  typedef WithStreamedUnaryMethod_ListMetrics<WithStreamedUnaryMethod_UpdateMetricsConfiguration<WithStreamedUnaryMethod_GetMetric<Service > > > StreamedService;
};

}  // namespace dmi


#endif  // GRPC_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto__INCLUDED
