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

/*
Package intstore is a generated protocol buffer package.

It is generated from these files:
	intstore.proto

It has these top-level messages:
	Item
	SetResponse
	GetRequest
	Summary
	ListItemsRequest
*/
package intstore

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"

import (
	"context"

	grpc "google.golang.org/grpc"
)

// 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.ProtoPackageIsVersion2 // please upgrade the proto package

type Item struct {
	Name  string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
	Value int32  `protobuf:"varint,2,opt,name=value" json:"value,omitempty"`
}

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

func (m *Item) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *Item) GetValue() int32 {
	if m != nil {
		return m.Value
	}
	return 0
}

type SetResponse struct {
	PrevValue int32 `protobuf:"varint,1,opt,name=prev_value,json=prevValue" json:"prev_value,omitempty"`
}

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

func (m *SetResponse) GetPrevValue() int32 {
	if m != nil {
		return m.PrevValue
	}
	return 0
}

type GetRequest struct {
	Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
}

func (m *GetRequest) Reset()                    { *m = GetRequest{} }
func (m *GetRequest) String() string            { return proto.CompactTextString(m) }
func (*GetRequest) ProtoMessage()               {}
func (*GetRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }

func (m *GetRequest) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

type Summary struct {
	Count int32 `protobuf:"varint,1,opt,name=count" json:"count,omitempty"`
}

func (m *Summary) Reset()                    { *m = Summary{} }
func (m *Summary) String() string            { return proto.CompactTextString(m) }
func (*Summary) ProtoMessage()               {}
func (*Summary) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }

func (m *Summary) GetCount() int32 {
	if m != nil {
		return m.Count
	}
	return 0
}

type ListItemsRequest struct {
}

func (m *ListItemsRequest) Reset()                    { *m = ListItemsRequest{} }
func (m *ListItemsRequest) String() string            { return proto.CompactTextString(m) }
func (*ListItemsRequest) ProtoMessage()               {}
func (*ListItemsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }

func init() {
	proto.RegisterType((*Item)(nil), "intstore.Item")
	proto.RegisterType((*SetResponse)(nil), "intstore.SetResponse")
	proto.RegisterType((*GetRequest)(nil), "intstore.GetRequest")
	proto.RegisterType((*Summary)(nil), "intstore.Summary")
	proto.RegisterType((*ListItemsRequest)(nil), "intstore.ListItemsRequest")
}

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

// Client API for IntStore service

type IntStoreClient interface {
	Set(ctx context.Context, in *Item, opts ...grpc.CallOption) (*SetResponse, error)
	Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*Item, error)
	// A server-to-client streaming RPC.
	ListItems(ctx context.Context, in *ListItemsRequest, opts ...grpc.CallOption) (IntStore_ListItemsClient, error)
	// A client-to-server streaming RPC.
	SetStream(ctx context.Context, opts ...grpc.CallOption) (IntStore_SetStreamClient, error)
	// A Bidirectional streaming RPC.
	StreamChat(ctx context.Context, opts ...grpc.CallOption) (IntStore_StreamChatClient, error)
}

type intStoreClient struct {
	cc *grpc.ClientConn
}

func NewIntStoreClient(cc *grpc.ClientConn) IntStoreClient {
	return &intStoreClient{cc}
}

func (c *intStoreClient) Set(ctx context.Context, in *Item, opts ...grpc.CallOption) (*SetResponse, error) {
	out := new(SetResponse)
	err := grpc.Invoke(ctx, "/intstore.IntStore/Set", in, out, c.cc, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *intStoreClient) Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*Item, error) {
	out := new(Item)
	err := grpc.Invoke(ctx, "/intstore.IntStore/Get", in, out, c.cc, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *intStoreClient) ListItems(ctx context.Context, in *ListItemsRequest, opts ...grpc.CallOption) (IntStore_ListItemsClient, error) {
	stream, err := grpc.NewClientStream(ctx, &_IntStore_serviceDesc.Streams[0], c.cc, "/intstore.IntStore/ListItems", opts...)
	if err != nil {
		return nil, err
	}
	x := &intStoreListItemsClient{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 IntStore_ListItemsClient interface {
	Recv() (*Item, error)
	grpc.ClientStream
}

type intStoreListItemsClient struct {
	grpc.ClientStream
}

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

func (c *intStoreClient) SetStream(ctx context.Context, opts ...grpc.CallOption) (IntStore_SetStreamClient, error) {
	stream, err := grpc.NewClientStream(ctx, &_IntStore_serviceDesc.Streams[1], c.cc, "/intstore.IntStore/SetStream", opts...)
	if err != nil {
		return nil, err
	}
	x := &intStoreSetStreamClient{stream}
	return x, nil
}

type IntStore_SetStreamClient interface {
	Send(*Item) error
	CloseAndRecv() (*Summary, error)
	grpc.ClientStream
}

type intStoreSetStreamClient struct {
	grpc.ClientStream
}

func (x *intStoreSetStreamClient) Send(m *Item) error {
	return x.ClientStream.SendMsg(m)
}

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

func (c *intStoreClient) StreamChat(ctx context.Context, opts ...grpc.CallOption) (IntStore_StreamChatClient, error) {
	stream, err := grpc.NewClientStream(ctx, &_IntStore_serviceDesc.Streams[2], c.cc, "/intstore.IntStore/StreamChat", opts...)
	if err != nil {
		return nil, err
	}
	x := &intStoreStreamChatClient{stream}
	return x, nil
}

type IntStore_StreamChatClient interface {
	Send(*Item) error
	Recv() (*Item, error)
	grpc.ClientStream
}

type intStoreStreamChatClient struct {
	grpc.ClientStream
}

func (x *intStoreStreamChatClient) Send(m *Item) error {
	return x.ClientStream.SendMsg(m)
}

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

// Server API for IntStore service

type IntStoreServer interface {
	Set(context.Context, *Item) (*SetResponse, error)
	Get(context.Context, *GetRequest) (*Item, error)
	// A server-to-client streaming RPC.
	ListItems(*ListItemsRequest, IntStore_ListItemsServer) error
	// A client-to-server streaming RPC.
	SetStream(IntStore_SetStreamServer) error
	// A Bidirectional streaming RPC.
	StreamChat(IntStore_StreamChatServer) error
}

func RegisterIntStoreServer(s *grpc.Server, srv IntStoreServer) {
	s.RegisterService(&_IntStore_serviceDesc, srv)
}

func _IntStore_Set_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(Item)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(IntStoreServer).Set(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/intstore.IntStore/Set",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(IntStoreServer).Set(ctx, req.(*Item))
	}
	return interceptor(ctx, in, info, handler)
}

func _IntStore_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(IntStoreServer).Get(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/intstore.IntStore/Get",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(IntStoreServer).Get(ctx, req.(*GetRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _IntStore_ListItems_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(ListItemsRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(IntStoreServer).ListItems(m, &intStoreListItemsServer{stream})
}

type IntStore_ListItemsServer interface {
	Send(*Item) error
	grpc.ServerStream
}

type intStoreListItemsServer struct {
	grpc.ServerStream
}

func (x *intStoreListItemsServer) Send(m *Item) error {
	return x.ServerStream.SendMsg(m)
}

func _IntStore_SetStream_Handler(srv interface{}, stream grpc.ServerStream) error {
	return srv.(IntStoreServer).SetStream(&intStoreSetStreamServer{stream})
}

type IntStore_SetStreamServer interface {
	SendAndClose(*Summary) error
	Recv() (*Item, error)
	grpc.ServerStream
}

type intStoreSetStreamServer struct {
	grpc.ServerStream
}

func (x *intStoreSetStreamServer) SendAndClose(m *Summary) error {
	return x.ServerStream.SendMsg(m)
}

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

func _IntStore_StreamChat_Handler(srv interface{}, stream grpc.ServerStream) error {
	return srv.(IntStoreServer).StreamChat(&intStoreStreamChatServer{stream})
}

type IntStore_StreamChatServer interface {
	Send(*Item) error
	Recv() (*Item, error)
	grpc.ServerStream
}

type intStoreStreamChatServer struct {
	grpc.ServerStream
}

func (x *intStoreStreamChatServer) Send(m *Item) error {
	return x.ServerStream.SendMsg(m)
}

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

var _IntStore_serviceDesc = grpc.ServiceDesc{
	ServiceName: "intstore.IntStore",
	HandlerType: (*IntStoreServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Set",
			Handler:    _IntStore_Set_Handler,
		},
		{
			MethodName: "Get",
			Handler:    _IntStore_Get_Handler,
		},
	},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "ListItems",
			Handler:       _IntStore_ListItems_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "SetStream",
			Handler:       _IntStore_SetStream_Handler,
			ClientStreams: true,
		},
		{
			StreamName:    "StreamChat",
			Handler:       _IntStore_StreamChat_Handler,
			ServerStreams: true,
			ClientStreams: true,
		},
	},
	Metadata: "intstore.proto",
}

func init() { proto.RegisterFile("intstore.proto", fileDescriptor0) }

var fileDescriptor0 = []byte{
	// 273 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x91, 0x4f, 0x4b, 0xc3, 0x40,
	0x10, 0xc5, 0xb3, 0xfd, 0xa3, 0xcd, 0x08, 0x45, 0x87, 0x0a, 0x25, 0x20, 0x86, 0x3d, 0xe5, 0xa0,
	0x21, 0xd4, 0xa3, 0x47, 0x0f, 0xa5, 0xe0, 0x29, 0x0b, 0x5e, 0x25, 0xca, 0x80, 0x05, 0xb3, 0x1b,
	0x77, 0x27, 0x05, 0xbf, 0x84, 0x9f, 0x59, 0x36, 0x5b, 0x9b, 0xd2, 0x78, 0xdb, 0xb7, 0xf3, 0x66,
	0xde, 0x6f, 0x76, 0x61, 0xbe, 0xd5, 0xec, 0xd8, 0x58, 0xca, 0x1b, 0x6b, 0xd8, 0xe0, 0xec, 0x4f,
	0xcb, 0x02, 0x26, 0x1b, 0xa6, 0x1a, 0x11, 0x26, 0xba, 0xaa, 0x69, 0x29, 0x52, 0x91, 0xc5, 0x65,
	0x77, 0xc6, 0x05, 0x4c, 0x77, 0xd5, 0x67, 0x4b, 0xcb, 0x51, 0x2a, 0xb2, 0x69, 0x19, 0x84, 0xbc,
	0x83, 0x0b, 0x45, 0x5c, 0x92, 0x6b, 0x8c, 0x76, 0x84, 0x37, 0x00, 0x8d, 0xa5, 0xdd, 0x6b, 0x70,
	0x8a, 0xce, 0x19, 0xfb, 0x9b, 0x97, 0xce, 0x9d, 0x02, 0xac, 0xbd, 0xfb, 0xab, 0x25, 0xc7, 0xff,
	0xa5, 0xc8, 0x5b, 0x38, 0x57, 0x6d, 0x5d, 0x57, 0xf6, 0xdb, 0x07, 0xbe, 0x9b, 0x56, 0xf3, 0x7e,
	0x4c, 0x10, 0x12, 0xe1, 0xf2, 0x79, 0xeb, 0xd8, 0x63, 0xba, 0xfd, 0xa0, 0xd5, 0xcf, 0x08, 0x66,
	0x1b, 0xcd, 0xca, 0xef, 0x80, 0x39, 0x8c, 0x15, 0x31, 0xce, 0xf3, 0xc3, 0x96, 0xde, 0x9b, 0x5c,
	0xf7, 0xfa, 0x08, 0x58, 0x46, 0x78, 0x0f, 0xe3, 0x35, 0x31, 0x2e, 0xfa, 0x7a, 0x8f, 0x98, 0x9c,
	0x4c, 0x91, 0x11, 0x3e, 0x42, 0x7c, 0xc8, 0xc7, 0xa4, 0x2f, 0x9f, 0x42, 0x0d, 0x5b, 0x0b, 0x81,
	0x2b, 0x88, 0x15, 0xb1, 0x62, 0x4b, 0x55, 0x3d, 0x20, 0xbc, 0x3a, 0x22, 0x0c, 0x4f, 0x20, 0xa3,
	0xcc, 0xf7, 0x40, 0x68, 0x78, 0xfa, 0xa8, 0x86, 0x6b, 0x0d, 0x52, 0x32, 0x51, 0x88, 0xb7, 0xb3,
	0xee, 0x63, 0x1f, 0x7e, 0x03, 0x00, 0x00, 0xff, 0xff, 0x22, 0x28, 0xa0, 0x49, 0xea, 0x01, 0x00,
	0x00,
}
