// Code generated by protoc-gen-go-grpc. DO NOT EDIT.

package grpc_testing

import (
	context "context"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion7

// BenchmarkServiceClient is the client API for BenchmarkService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type BenchmarkServiceClient interface {
	// One request followed by one response.
	// The server returns the client payload as-is.
	UnaryCall(ctx context.Context, in *SimpleRequest, opts ...grpc.CallOption) (*SimpleResponse, error)
	// One request followed by one response.
	// The server returns the client payload as-is.
	StreamingCall(ctx context.Context, opts ...grpc.CallOption) (BenchmarkService_StreamingCallClient, error)
	// Unconstrainted streaming.
	// Both server and client keep sending & receiving simultaneously.
	UnconstrainedStreamingCall(ctx context.Context, opts ...grpc.CallOption) (BenchmarkService_UnconstrainedStreamingCallClient, error)
}

type benchmarkServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewBenchmarkServiceClient(cc grpc.ClientConnInterface) BenchmarkServiceClient {
	return &benchmarkServiceClient{cc}
}

var benchmarkServiceUnaryCallStreamDesc = &grpc.StreamDesc{
	StreamName: "UnaryCall",
}

func (c *benchmarkServiceClient) UnaryCall(ctx context.Context, in *SimpleRequest, opts ...grpc.CallOption) (*SimpleResponse, error) {
	out := new(SimpleResponse)
	err := c.cc.Invoke(ctx, "/grpc.testing.BenchmarkService/UnaryCall", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

var benchmarkServiceStreamingCallStreamDesc = &grpc.StreamDesc{
	StreamName:    "StreamingCall",
	ServerStreams: true,
	ClientStreams: true,
}

func (c *benchmarkServiceClient) StreamingCall(ctx context.Context, opts ...grpc.CallOption) (BenchmarkService_StreamingCallClient, error) {
	stream, err := c.cc.NewStream(ctx, benchmarkServiceStreamingCallStreamDesc, "/grpc.testing.BenchmarkService/StreamingCall", opts...)
	if err != nil {
		return nil, err
	}
	x := &benchmarkServiceStreamingCallClient{stream}
	return x, nil
}

type BenchmarkService_StreamingCallClient interface {
	Send(*SimpleRequest) error
	Recv() (*SimpleResponse, error)
	grpc.ClientStream
}

type benchmarkServiceStreamingCallClient struct {
	grpc.ClientStream
}

func (x *benchmarkServiceStreamingCallClient) Send(m *SimpleRequest) error {
	return x.ClientStream.SendMsg(m)
}

func (x *benchmarkServiceStreamingCallClient) Recv() (*SimpleResponse, error) {
	m := new(SimpleResponse)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

var benchmarkServiceUnconstrainedStreamingCallStreamDesc = &grpc.StreamDesc{
	StreamName:    "UnconstrainedStreamingCall",
	ServerStreams: true,
	ClientStreams: true,
}

func (c *benchmarkServiceClient) UnconstrainedStreamingCall(ctx context.Context, opts ...grpc.CallOption) (BenchmarkService_UnconstrainedStreamingCallClient, error) {
	stream, err := c.cc.NewStream(ctx, benchmarkServiceUnconstrainedStreamingCallStreamDesc, "/grpc.testing.BenchmarkService/UnconstrainedStreamingCall", opts...)
	if err != nil {
		return nil, err
	}
	x := &benchmarkServiceUnconstrainedStreamingCallClient{stream}
	return x, nil
}

type BenchmarkService_UnconstrainedStreamingCallClient interface {
	Send(*SimpleRequest) error
	Recv() (*SimpleResponse, error)
	grpc.ClientStream
}

type benchmarkServiceUnconstrainedStreamingCallClient struct {
	grpc.ClientStream
}

func (x *benchmarkServiceUnconstrainedStreamingCallClient) Send(m *SimpleRequest) error {
	return x.ClientStream.SendMsg(m)
}

func (x *benchmarkServiceUnconstrainedStreamingCallClient) Recv() (*SimpleResponse, error) {
	m := new(SimpleResponse)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

// BenchmarkServiceService is the service API for BenchmarkService service.
// Fields should be assigned to their respective handler implementations only before
// RegisterBenchmarkServiceService is called.  Any unassigned fields will result in the
// handler for that method returning an Unimplemented error.
type BenchmarkServiceService struct {
	// One request followed by one response.
	// The server returns the client payload as-is.
	UnaryCall func(context.Context, *SimpleRequest) (*SimpleResponse, error)
	// One request followed by one response.
	// The server returns the client payload as-is.
	StreamingCall func(BenchmarkService_StreamingCallServer) error
	// Unconstrainted streaming.
	// Both server and client keep sending & receiving simultaneously.
	UnconstrainedStreamingCall func(BenchmarkService_UnconstrainedStreamingCallServer) error
}

func (s *BenchmarkServiceService) unaryCall(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SimpleRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return s.UnaryCall(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     s,
		FullMethod: "/grpc.testing.BenchmarkService/UnaryCall",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return s.UnaryCall(ctx, req.(*SimpleRequest))
	}
	return interceptor(ctx, in, info, handler)
}
func (s *BenchmarkServiceService) streamingCall(_ interface{}, stream grpc.ServerStream) error {
	return s.StreamingCall(&benchmarkServiceStreamingCallServer{stream})
}
func (s *BenchmarkServiceService) unconstrainedStreamingCall(_ interface{}, stream grpc.ServerStream) error {
	return s.UnconstrainedStreamingCall(&benchmarkServiceUnconstrainedStreamingCallServer{stream})
}

type BenchmarkService_StreamingCallServer interface {
	Send(*SimpleResponse) error
	Recv() (*SimpleRequest, error)
	grpc.ServerStream
}

type benchmarkServiceStreamingCallServer struct {
	grpc.ServerStream
}

func (x *benchmarkServiceStreamingCallServer) Send(m *SimpleResponse) error {
	return x.ServerStream.SendMsg(m)
}

func (x *benchmarkServiceStreamingCallServer) Recv() (*SimpleRequest, error) {
	m := new(SimpleRequest)
	if err := x.ServerStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

type BenchmarkService_UnconstrainedStreamingCallServer interface {
	Send(*SimpleResponse) error
	Recv() (*SimpleRequest, error)
	grpc.ServerStream
}

type benchmarkServiceUnconstrainedStreamingCallServer struct {
	grpc.ServerStream
}

func (x *benchmarkServiceUnconstrainedStreamingCallServer) Send(m *SimpleResponse) error {
	return x.ServerStream.SendMsg(m)
}

func (x *benchmarkServiceUnconstrainedStreamingCallServer) Recv() (*SimpleRequest, error) {
	m := new(SimpleRequest)
	if err := x.ServerStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

// RegisterBenchmarkServiceService registers a service implementation with a gRPC server.
func RegisterBenchmarkServiceService(s grpc.ServiceRegistrar, srv *BenchmarkServiceService) {
	srvCopy := *srv
	if srvCopy.UnaryCall == nil {
		srvCopy.UnaryCall = func(context.Context, *SimpleRequest) (*SimpleResponse, error) {
			return nil, status.Errorf(codes.Unimplemented, "method UnaryCall not implemented")
		}
	}
	if srvCopy.StreamingCall == nil {
		srvCopy.StreamingCall = func(BenchmarkService_StreamingCallServer) error {
			return status.Errorf(codes.Unimplemented, "method StreamingCall not implemented")
		}
	}
	if srvCopy.UnconstrainedStreamingCall == nil {
		srvCopy.UnconstrainedStreamingCall = func(BenchmarkService_UnconstrainedStreamingCallServer) error {
			return status.Errorf(codes.Unimplemented, "method UnconstrainedStreamingCall not implemented")
		}
	}
	sd := grpc.ServiceDesc{
		ServiceName: "grpc.testing.BenchmarkService",
		Methods: []grpc.MethodDesc{
			{
				MethodName: "UnaryCall",
				Handler:    srvCopy.unaryCall,
			},
		},
		Streams: []grpc.StreamDesc{
			{
				StreamName:    "StreamingCall",
				Handler:       srvCopy.streamingCall,
				ServerStreams: true,
				ClientStreams: true,
			},
			{
				StreamName:    "UnconstrainedStreamingCall",
				Handler:       srvCopy.unconstrainedStreamingCall,
				ServerStreams: true,
				ClientStreams: true,
			},
		},
		Metadata: "benchmark/grpc_testing/services.proto",
	}

	s.RegisterService(&sd, nil)
}

// WorkerServiceClient is the client API for WorkerService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type WorkerServiceClient interface {
	// Start server with specified workload.
	// First request sent specifies the ServerConfig followed by ServerStatus
	// response. After that, a "Mark" can be sent anytime to request the latest
	// stats. Closing the stream will initiate shutdown of the test server
	// and once the shutdown has finished, the OK status is sent to terminate
	// this RPC.
	RunServer(ctx context.Context, opts ...grpc.CallOption) (WorkerService_RunServerClient, error)
	// Start client with specified workload.
	// First request sent specifies the ClientConfig followed by ClientStatus
	// response. After that, a "Mark" can be sent anytime to request the latest
	// stats. Closing the stream will initiate shutdown of the test client
	// and once the shutdown has finished, the OK status is sent to terminate
	// this RPC.
	RunClient(ctx context.Context, opts ...grpc.CallOption) (WorkerService_RunClientClient, error)
	// Just return the core count - unary call
	CoreCount(ctx context.Context, in *CoreRequest, opts ...grpc.CallOption) (*CoreResponse, error)
	// Quit this worker
	QuitWorker(ctx context.Context, in *Void, opts ...grpc.CallOption) (*Void, error)
}

type workerServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewWorkerServiceClient(cc grpc.ClientConnInterface) WorkerServiceClient {
	return &workerServiceClient{cc}
}

var workerServiceRunServerStreamDesc = &grpc.StreamDesc{
	StreamName:    "RunServer",
	ServerStreams: true,
	ClientStreams: true,
}

func (c *workerServiceClient) RunServer(ctx context.Context, opts ...grpc.CallOption) (WorkerService_RunServerClient, error) {
	stream, err := c.cc.NewStream(ctx, workerServiceRunServerStreamDesc, "/grpc.testing.WorkerService/RunServer", opts...)
	if err != nil {
		return nil, err
	}
	x := &workerServiceRunServerClient{stream}
	return x, nil
}

type WorkerService_RunServerClient interface {
	Send(*ServerArgs) error
	Recv() (*ServerStatus, error)
	grpc.ClientStream
}

type workerServiceRunServerClient struct {
	grpc.ClientStream
}

func (x *workerServiceRunServerClient) Send(m *ServerArgs) error {
	return x.ClientStream.SendMsg(m)
}

func (x *workerServiceRunServerClient) Recv() (*ServerStatus, error) {
	m := new(ServerStatus)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

var workerServiceRunClientStreamDesc = &grpc.StreamDesc{
	StreamName:    "RunClient",
	ServerStreams: true,
	ClientStreams: true,
}

func (c *workerServiceClient) RunClient(ctx context.Context, opts ...grpc.CallOption) (WorkerService_RunClientClient, error) {
	stream, err := c.cc.NewStream(ctx, workerServiceRunClientStreamDesc, "/grpc.testing.WorkerService/RunClient", opts...)
	if err != nil {
		return nil, err
	}
	x := &workerServiceRunClientClient{stream}
	return x, nil
}

type WorkerService_RunClientClient interface {
	Send(*ClientArgs) error
	Recv() (*ClientStatus, error)
	grpc.ClientStream
}

type workerServiceRunClientClient struct {
	grpc.ClientStream
}

func (x *workerServiceRunClientClient) Send(m *ClientArgs) error {
	return x.ClientStream.SendMsg(m)
}

func (x *workerServiceRunClientClient) Recv() (*ClientStatus, error) {
	m := new(ClientStatus)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

var workerServiceCoreCountStreamDesc = &grpc.StreamDesc{
	StreamName: "CoreCount",
}

func (c *workerServiceClient) CoreCount(ctx context.Context, in *CoreRequest, opts ...grpc.CallOption) (*CoreResponse, error) {
	out := new(CoreResponse)
	err := c.cc.Invoke(ctx, "/grpc.testing.WorkerService/CoreCount", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

var workerServiceQuitWorkerStreamDesc = &grpc.StreamDesc{
	StreamName: "QuitWorker",
}

func (c *workerServiceClient) QuitWorker(ctx context.Context, in *Void, opts ...grpc.CallOption) (*Void, error) {
	out := new(Void)
	err := c.cc.Invoke(ctx, "/grpc.testing.WorkerService/QuitWorker", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// WorkerServiceService is the service API for WorkerService service.
// Fields should be assigned to their respective handler implementations only before
// RegisterWorkerServiceService is called.  Any unassigned fields will result in the
// handler for that method returning an Unimplemented error.
type WorkerServiceService struct {
	// Start server with specified workload.
	// First request sent specifies the ServerConfig followed by ServerStatus
	// response. After that, a "Mark" can be sent anytime to request the latest
	// stats. Closing the stream will initiate shutdown of the test server
	// and once the shutdown has finished, the OK status is sent to terminate
	// this RPC.
	RunServer func(WorkerService_RunServerServer) error
	// Start client with specified workload.
	// First request sent specifies the ClientConfig followed by ClientStatus
	// response. After that, a "Mark" can be sent anytime to request the latest
	// stats. Closing the stream will initiate shutdown of the test client
	// and once the shutdown has finished, the OK status is sent to terminate
	// this RPC.
	RunClient func(WorkerService_RunClientServer) error
	// Just return the core count - unary call
	CoreCount func(context.Context, *CoreRequest) (*CoreResponse, error)
	// Quit this worker
	QuitWorker func(context.Context, *Void) (*Void, error)
}

func (s *WorkerServiceService) runServer(_ interface{}, stream grpc.ServerStream) error {
	return s.RunServer(&workerServiceRunServerServer{stream})
}
func (s *WorkerServiceService) runClient(_ interface{}, stream grpc.ServerStream) error {
	return s.RunClient(&workerServiceRunClientServer{stream})
}
func (s *WorkerServiceService) coreCount(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(CoreRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return s.CoreCount(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     s,
		FullMethod: "/grpc.testing.WorkerService/CoreCount",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return s.CoreCount(ctx, req.(*CoreRequest))
	}
	return interceptor(ctx, in, info, handler)
}
func (s *WorkerServiceService) quitWorker(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(Void)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return s.QuitWorker(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     s,
		FullMethod: "/grpc.testing.WorkerService/QuitWorker",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return s.QuitWorker(ctx, req.(*Void))
	}
	return interceptor(ctx, in, info, handler)
}

type WorkerService_RunServerServer interface {
	Send(*ServerStatus) error
	Recv() (*ServerArgs, error)
	grpc.ServerStream
}

type workerServiceRunServerServer struct {
	grpc.ServerStream
}

func (x *workerServiceRunServerServer) Send(m *ServerStatus) error {
	return x.ServerStream.SendMsg(m)
}

func (x *workerServiceRunServerServer) Recv() (*ServerArgs, error) {
	m := new(ServerArgs)
	if err := x.ServerStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

type WorkerService_RunClientServer interface {
	Send(*ClientStatus) error
	Recv() (*ClientArgs, error)
	grpc.ServerStream
}

type workerServiceRunClientServer struct {
	grpc.ServerStream
}

func (x *workerServiceRunClientServer) Send(m *ClientStatus) error {
	return x.ServerStream.SendMsg(m)
}

func (x *workerServiceRunClientServer) Recv() (*ClientArgs, error) {
	m := new(ClientArgs)
	if err := x.ServerStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

// RegisterWorkerServiceService registers a service implementation with a gRPC server.
func RegisterWorkerServiceService(s grpc.ServiceRegistrar, srv *WorkerServiceService) {
	srvCopy := *srv
	if srvCopy.RunServer == nil {
		srvCopy.RunServer = func(WorkerService_RunServerServer) error {
			return status.Errorf(codes.Unimplemented, "method RunServer not implemented")
		}
	}
	if srvCopy.RunClient == nil {
		srvCopy.RunClient = func(WorkerService_RunClientServer) error {
			return status.Errorf(codes.Unimplemented, "method RunClient not implemented")
		}
	}
	if srvCopy.CoreCount == nil {
		srvCopy.CoreCount = func(context.Context, *CoreRequest) (*CoreResponse, error) {
			return nil, status.Errorf(codes.Unimplemented, "method CoreCount not implemented")
		}
	}
	if srvCopy.QuitWorker == nil {
		srvCopy.QuitWorker = func(context.Context, *Void) (*Void, error) {
			return nil, status.Errorf(codes.Unimplemented, "method QuitWorker not implemented")
		}
	}
	sd := grpc.ServiceDesc{
		ServiceName: "grpc.testing.WorkerService",
		Methods: []grpc.MethodDesc{
			{
				MethodName: "CoreCount",
				Handler:    srvCopy.coreCount,
			},
			{
				MethodName: "QuitWorker",
				Handler:    srvCopy.quitWorker,
			},
		},
		Streams: []grpc.StreamDesc{
			{
				StreamName:    "RunServer",
				Handler:       srvCopy.runServer,
				ServerStreams: true,
				ClientStreams: true,
			},
			{
				StreamName:    "RunClient",
				Handler:       srvCopy.runClient,
				ServerStreams: true,
				ClientStreams: true,
			},
		},
		Metadata: "benchmark/grpc_testing/services.proto",
	}

	s.RegisterService(&sd, nil)
}
