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

package grpc

import (
	context "golang.org/x/net/context"
	grpc "google.golang.org/grpc"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn

// 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.SupportPackageIsVersion4

// TestClient is the client API for Test service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type TestClient interface {
	UnaryCall(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
	// This RPC streams from the server only.
	Downstream(ctx context.Context, in *Request, opts ...grpc.CallOption) (Test_DownstreamClient, error)
	// This RPC streams from the client.
	Upstream(ctx context.Context, opts ...grpc.CallOption) (Test_UpstreamClient, error)
	// This one streams in both directions.
	Bidi(ctx context.Context, opts ...grpc.CallOption) (Test_BidiClient, error)
}

type testClient struct {
	cc *grpc.ClientConn
}

func NewTestClient(cc *grpc.ClientConn) TestClient {
	return &testClient{cc}
}

func (c *testClient) UnaryCall(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
	out := new(Response)
	err := c.cc.Invoke(ctx, "/goproto.protoc.grpc.Test/UnaryCall", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *testClient) Downstream(ctx context.Context, in *Request, opts ...grpc.CallOption) (Test_DownstreamClient, error) {
	stream, err := c.cc.NewStream(ctx, &_Test_serviceDesc.Streams[0], "/goproto.protoc.grpc.Test/Downstream", opts...)
	if err != nil {
		return nil, err
	}
	x := &testDownstreamClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type Test_DownstreamClient interface {
	Recv() (*Response, error)
	grpc.ClientStream
}

type testDownstreamClient struct {
	grpc.ClientStream
}

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

func (c *testClient) Upstream(ctx context.Context, opts ...grpc.CallOption) (Test_UpstreamClient, error) {
	stream, err := c.cc.NewStream(ctx, &_Test_serviceDesc.Streams[1], "/goproto.protoc.grpc.Test/Upstream", opts...)
	if err != nil {
		return nil, err
	}
	x := &testUpstreamClient{stream}
	return x, nil
}

type Test_UpstreamClient interface {
	Send(*Request) error
	CloseAndRecv() (*Response, error)
	grpc.ClientStream
}

type testUpstreamClient struct {
	grpc.ClientStream
}

func (x *testUpstreamClient) Send(m *Request) error {
	return x.ClientStream.SendMsg(m)
}

func (x *testUpstreamClient) CloseAndRecv() (*Response, error) {
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	m := new(Response)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

func (c *testClient) Bidi(ctx context.Context, opts ...grpc.CallOption) (Test_BidiClient, error) {
	stream, err := c.cc.NewStream(ctx, &_Test_serviceDesc.Streams[2], "/goproto.protoc.grpc.Test/Bidi", opts...)
	if err != nil {
		return nil, err
	}
	x := &testBidiClient{stream}
	return x, nil
}

type Test_BidiClient interface {
	Send(*Request) error
	Recv() (*Response, error)
	grpc.ClientStream
}

type testBidiClient struct {
	grpc.ClientStream
}

func (x *testBidiClient) Send(m *Request) error {
	return x.ClientStream.SendMsg(m)
}

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

// TestServer is the server API for Test service.
type TestServer interface {
	UnaryCall(context.Context, *Request) (*Response, error)
	// This RPC streams from the server only.
	Downstream(*Request, Test_DownstreamServer) error
	// This RPC streams from the client.
	Upstream(Test_UpstreamServer) error
	// This one streams in both directions.
	Bidi(Test_BidiServer) error
}

func RegisterTestServer(s *grpc.Server, srv TestServer) {
	s.RegisterService(&_Test_serviceDesc, srv)
}

func _Test_UnaryCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(Request)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestServer).UnaryCall(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/goproto.protoc.grpc.Test/UnaryCall",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestServer).UnaryCall(ctx, req.(*Request))
	}
	return interceptor(ctx, in, info, handler)
}

func _Test_Downstream_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(Request)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(TestServer).Downstream(m, &testDownstreamServer{stream})
}

type Test_DownstreamServer interface {
	Send(*Response) error
	grpc.ServerStream
}

type testDownstreamServer struct {
	grpc.ServerStream
}

func (x *testDownstreamServer) Send(m *Response) error {
	return x.ServerStream.SendMsg(m)
}

func _Test_Upstream_Handler(srv interface{}, stream grpc.ServerStream) error {
	return srv.(TestServer).Upstream(&testUpstreamServer{stream})
}

type Test_UpstreamServer interface {
	SendAndClose(*Response) error
	Recv() (*Request, error)
	grpc.ServerStream
}

type testUpstreamServer struct {
	grpc.ServerStream
}

func (x *testUpstreamServer) SendAndClose(m *Response) error {
	return x.ServerStream.SendMsg(m)
}

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

func _Test_Bidi_Handler(srv interface{}, stream grpc.ServerStream) error {
	return srv.(TestServer).Bidi(&testBidiServer{stream})
}

type Test_BidiServer interface {
	Send(*Response) error
	Recv() (*Request, error)
	grpc.ServerStream
}

type testBidiServer struct {
	grpc.ServerStream
}

func (x *testBidiServer) Send(m *Response) error {
	return x.ServerStream.SendMsg(m)
}

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

var _Test_serviceDesc = grpc.ServiceDesc{
	ServiceName: "goproto.protoc.grpc.Test",
	HandlerType: (*TestServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "UnaryCall",
			Handler:    _Test_UnaryCall_Handler,
		},
	},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "Downstream",
			Handler:       _Test_Downstream_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "Upstream",
			Handler:       _Test_Upstream_Handler,
			ClientStreams: true,
		},
		{
			StreamName:    "Bidi",
			Handler:       _Test_Bidi_Handler,
			ServerStreams: true,
			ClientStreams: true,
		},
	},
	Metadata: "grpc/grpc.proto",
}
