// Code generated by protoc-gen-go. DO NOT EDIT.
// source: pubsub.proto

package pubsub_bench

import (
	context "context"
	fmt "fmt"
	math "math"

	proto "github.com/golang/protobuf/proto"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

type PubsubRecv struct {
	// The subscription identifier corresponding to number of messages sent.
	SubName              string   `protobuf:"bytes,1,opt,name=sub_name,json=subName,proto3" json:"sub_name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *PubsubRecv) Reset()         { *m = PubsubRecv{} }
func (m *PubsubRecv) String() string { return proto.CompactTextString(m) }
func (*PubsubRecv) ProtoMessage()    {}
func (*PubsubRecv) Descriptor() ([]byte, []int) {
	return fileDescriptor_91df006b05e20cf7, []int{0}
}

func (m *PubsubRecv) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_PubsubRecv.Unmarshal(m, b)
}
func (m *PubsubRecv) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_PubsubRecv.Marshal(b, m, deterministic)
}
func (m *PubsubRecv) XXX_Merge(src proto.Message) {
	xxx_messageInfo_PubsubRecv.Merge(m, src)
}
func (m *PubsubRecv) XXX_Size() int {
	return xxx_messageInfo_PubsubRecv.Size(m)
}
func (m *PubsubRecv) XXX_DiscardUnknown() {
	xxx_messageInfo_PubsubRecv.DiscardUnknown(m)
}

var xxx_messageInfo_PubsubRecv proto.InternalMessageInfo

func (m *PubsubRecv) GetSubName() string {
	if m != nil {
		return m.SubName
	}
	return ""
}

// TODO(deklerk): Replace with Google's canonical Empty.
type EmptyResponse struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *EmptyResponse) Reset()         { *m = EmptyResponse{} }
func (m *EmptyResponse) String() string { return proto.CompactTextString(m) }
func (*EmptyResponse) ProtoMessage()    {}
func (*EmptyResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_91df006b05e20cf7, []int{1}
}

func (m *EmptyResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_EmptyResponse.Unmarshal(m, b)
}
func (m *EmptyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_EmptyResponse.Marshal(b, m, deterministic)
}
func (m *EmptyResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_EmptyResponse.Merge(m, src)
}
func (m *EmptyResponse) XXX_Size() int {
	return xxx_messageInfo_EmptyResponse.Size(m)
}
func (m *EmptyResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_EmptyResponse.DiscardUnknown(m)
}

var xxx_messageInfo_EmptyResponse proto.InternalMessageInfo

func init() {
	proto.RegisterType((*PubsubRecv)(nil), "pubsub_bench.PubsubRecv")
	proto.RegisterType((*EmptyResponse)(nil), "pubsub_bench.EmptyResponse")
}

func init() { proto.RegisterFile("pubsub.proto", fileDescriptor_91df006b05e20cf7) }

var fileDescriptor_91df006b05e20cf7 = []byte{
	// 147 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x28, 0x4d, 0x2a,
	0x2e, 0x4d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x82, 0xf2, 0xe2, 0x93, 0x52, 0xf3, 0x92,
	0x33, 0x94, 0xd4, 0xb9, 0xb8, 0x02, 0xc0, 0xfc, 0xa0, 0xd4, 0xe4, 0x32, 0x21, 0x49, 0x2e, 0x0e,
	0x90, 0x54, 0x5e, 0x62, 0x6e, 0xaa, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x7b, 0x71, 0x69,
	0x92, 0x5f, 0x62, 0x6e, 0xaa, 0x12, 0x3f, 0x17, 0xaf, 0x6b, 0x6e, 0x41, 0x49, 0x65, 0x50, 0x6a,
	0x71, 0x41, 0x7e, 0x5e, 0x71, 0xaa, 0x51, 0x28, 0x97, 0x10, 0x44, 0xa7, 0x13, 0xc8, 0xa0, 0xf0,
	0xa2, 0xc4, 0x82, 0x82, 0xd4, 0x22, 0x21, 0x7b, 0x2e, 0x16, 0xb0, 0x49, 0x12, 0x7a, 0xc8, 0xd6,
	0xe8, 0x21, 0xec, 0x90, 0x92, 0x46, 0x95, 0x41, 0x31, 0x54, 0x89, 0xc1, 0x89, 0x29, 0x80, 0x31,
	0x89, 0x0d, 0xec, 0x52, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe3, 0xea, 0xe3, 0xed, 0xb9,
	0x00, 0x00, 0x00,
}

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

// PubsubBenchWrapperClient is the client API for PubsubBenchWrapper service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type PubsubBenchWrapperClient interface {
	// Recv represents opening a streaming pull stream to receive messages on.
	Recv(ctx context.Context, in *PubsubRecv, opts ...grpc.CallOption) (*EmptyResponse, error)
}

type pubsubBenchWrapperClient struct {
	cc *grpc.ClientConn
}

func NewPubsubBenchWrapperClient(cc *grpc.ClientConn) PubsubBenchWrapperClient {
	return &pubsubBenchWrapperClient{cc}
}

func (c *pubsubBenchWrapperClient) Recv(ctx context.Context, in *PubsubRecv, opts ...grpc.CallOption) (*EmptyResponse, error) {
	out := new(EmptyResponse)
	err := c.cc.Invoke(ctx, "/pubsub_bench.PubsubBenchWrapper/Recv", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// PubsubBenchWrapperServer is the server API for PubsubBenchWrapper service.
type PubsubBenchWrapperServer interface {
	// Recv represents opening a streaming pull stream to receive messages on.
	Recv(context.Context, *PubsubRecv) (*EmptyResponse, error)
}

// UnimplementedPubsubBenchWrapperServer can be embedded to have forward compatible implementations.
type UnimplementedPubsubBenchWrapperServer struct {
}

func (*UnimplementedPubsubBenchWrapperServer) Recv(ctx context.Context, req *PubsubRecv) (*EmptyResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Recv not implemented")
}

func RegisterPubsubBenchWrapperServer(s *grpc.Server, srv PubsubBenchWrapperServer) {
	s.RegisterService(&_PubsubBenchWrapper_serviceDesc, srv)
}

func _PubsubBenchWrapper_Recv_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(PubsubRecv)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PubsubBenchWrapperServer).Recv(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/pubsub_bench.PubsubBenchWrapper/Recv",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PubsubBenchWrapperServer).Recv(ctx, req.(*PubsubRecv))
	}
	return interceptor(ctx, in, info, handler)
}

var _PubsubBenchWrapper_serviceDesc = grpc.ServiceDesc{
	ServiceName: "pubsub_bench.PubsubBenchWrapper",
	HandlerType: (*PubsubBenchWrapperServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Recv",
			Handler:    _PubsubBenchWrapper_Recv_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "pubsub.proto",
}
