// Code generated by protoc-gen-go.
// source: google.golang.org/cloud/bigtable/internal/service_proto/bigtable_service.proto
// DO NOT EDIT!

package google_bigtable_v1

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_bigtable_v11 "google.golang.org/cloud/bigtable/internal/data_proto"
import google_protobuf1 "github.com/golang/protobuf/ptypes/empty"

import (
	context "golang.org/x/net/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

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

// Client API for BigtableService service

type BigtableServiceClient interface {
	// Streams back the contents of all requested rows, optionally applying
	// the same Reader filter to each. Depending on their size, rows may be
	// broken up across multiple responses, but atomicity of each row will still
	// be preserved.
	ReadRows(ctx context.Context, in *ReadRowsRequest, opts ...grpc.CallOption) (BigtableService_ReadRowsClient, error)
	// Returns a sample of row keys in the table. The returned row keys will
	// delimit contiguous sections of the table of approximately equal size,
	// which can be used to break up the data for distributed tasks like
	// mapreduces.
	SampleRowKeys(ctx context.Context, in *SampleRowKeysRequest, opts ...grpc.CallOption) (BigtableService_SampleRowKeysClient, error)
	// Mutates a row atomically. Cells already present in the row are left
	// unchanged unless explicitly changed by 'mutation'.
	MutateRow(ctx context.Context, in *MutateRowRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error)
	// Mutates multiple rows in a batch. Each individual row is mutated
	// atomically as in MutateRow, but the entire batch is not executed
	// atomically.
	MutateRows(ctx context.Context, in *MutateRowsRequest, opts ...grpc.CallOption) (*MutateRowsResponse, error)
	// Mutates a row atomically based on the output of a predicate Reader filter.
	CheckAndMutateRow(ctx context.Context, in *CheckAndMutateRowRequest, opts ...grpc.CallOption) (*CheckAndMutateRowResponse, error)
	// Modifies a row atomically, reading the latest existing timestamp/value from
	// the specified columns and writing a new value at
	// max(existing timestamp, current server time) based on pre-defined
	// read/modify/write rules. Returns the new contents of all modified cells.
	ReadModifyWriteRow(ctx context.Context, in *ReadModifyWriteRowRequest, opts ...grpc.CallOption) (*google_bigtable_v11.Row, error)
}

type bigtableServiceClient struct {
	cc *grpc.ClientConn
}

func NewBigtableServiceClient(cc *grpc.ClientConn) BigtableServiceClient {
	return &bigtableServiceClient{cc}
}

func (c *bigtableServiceClient) ReadRows(ctx context.Context, in *ReadRowsRequest, opts ...grpc.CallOption) (BigtableService_ReadRowsClient, error) {
	stream, err := grpc.NewClientStream(ctx, &_BigtableService_serviceDesc.Streams[0], c.cc, "/google.bigtable.v1.BigtableService/ReadRows", opts...)
	if err != nil {
		return nil, err
	}
	x := &bigtableServiceReadRowsClient{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 BigtableService_ReadRowsClient interface {
	Recv() (*ReadRowsResponse, error)
	grpc.ClientStream
}

type bigtableServiceReadRowsClient struct {
	grpc.ClientStream
}

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

func (c *bigtableServiceClient) SampleRowKeys(ctx context.Context, in *SampleRowKeysRequest, opts ...grpc.CallOption) (BigtableService_SampleRowKeysClient, error) {
	stream, err := grpc.NewClientStream(ctx, &_BigtableService_serviceDesc.Streams[1], c.cc, "/google.bigtable.v1.BigtableService/SampleRowKeys", opts...)
	if err != nil {
		return nil, err
	}
	x := &bigtableServiceSampleRowKeysClient{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 BigtableService_SampleRowKeysClient interface {
	Recv() (*SampleRowKeysResponse, error)
	grpc.ClientStream
}

type bigtableServiceSampleRowKeysClient struct {
	grpc.ClientStream
}

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

func (c *bigtableServiceClient) MutateRow(ctx context.Context, in *MutateRowRequest, opts ...grpc.CallOption) (*google_protobuf1.Empty, error) {
	out := new(google_protobuf1.Empty)
	err := grpc.Invoke(ctx, "/google.bigtable.v1.BigtableService/MutateRow", in, out, c.cc, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *bigtableServiceClient) MutateRows(ctx context.Context, in *MutateRowsRequest, opts ...grpc.CallOption) (*MutateRowsResponse, error) {
	out := new(MutateRowsResponse)
	err := grpc.Invoke(ctx, "/google.bigtable.v1.BigtableService/MutateRows", in, out, c.cc, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *bigtableServiceClient) CheckAndMutateRow(ctx context.Context, in *CheckAndMutateRowRequest, opts ...grpc.CallOption) (*CheckAndMutateRowResponse, error) {
	out := new(CheckAndMutateRowResponse)
	err := grpc.Invoke(ctx, "/google.bigtable.v1.BigtableService/CheckAndMutateRow", in, out, c.cc, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *bigtableServiceClient) ReadModifyWriteRow(ctx context.Context, in *ReadModifyWriteRowRequest, opts ...grpc.CallOption) (*google_bigtable_v11.Row, error) {
	out := new(google_bigtable_v11.Row)
	err := grpc.Invoke(ctx, "/google.bigtable.v1.BigtableService/ReadModifyWriteRow", in, out, c.cc, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// Server API for BigtableService service

type BigtableServiceServer interface {
	// Streams back the contents of all requested rows, optionally applying
	// the same Reader filter to each. Depending on their size, rows may be
	// broken up across multiple responses, but atomicity of each row will still
	// be preserved.
	ReadRows(*ReadRowsRequest, BigtableService_ReadRowsServer) error
	// Returns a sample of row keys in the table. The returned row keys will
	// delimit contiguous sections of the table of approximately equal size,
	// which can be used to break up the data for distributed tasks like
	// mapreduces.
	SampleRowKeys(*SampleRowKeysRequest, BigtableService_SampleRowKeysServer) error
	// Mutates a row atomically. Cells already present in the row are left
	// unchanged unless explicitly changed by 'mutation'.
	MutateRow(context.Context, *MutateRowRequest) (*google_protobuf1.Empty, error)
	// Mutates multiple rows in a batch. Each individual row is mutated
	// atomically as in MutateRow, but the entire batch is not executed
	// atomically.
	MutateRows(context.Context, *MutateRowsRequest) (*MutateRowsResponse, error)
	// Mutates a row atomically based on the output of a predicate Reader filter.
	CheckAndMutateRow(context.Context, *CheckAndMutateRowRequest) (*CheckAndMutateRowResponse, error)
	// Modifies a row atomically, reading the latest existing timestamp/value from
	// the specified columns and writing a new value at
	// max(existing timestamp, current server time) based on pre-defined
	// read/modify/write rules. Returns the new contents of all modified cells.
	ReadModifyWriteRow(context.Context, *ReadModifyWriteRowRequest) (*google_bigtable_v11.Row, error)
}

func RegisterBigtableServiceServer(s *grpc.Server, srv BigtableServiceServer) {
	s.RegisterService(&_BigtableService_serviceDesc, srv)
}

func _BigtableService_ReadRows_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(ReadRowsRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(BigtableServiceServer).ReadRows(m, &bigtableServiceReadRowsServer{stream})
}

type BigtableService_ReadRowsServer interface {
	Send(*ReadRowsResponse) error
	grpc.ServerStream
}

type bigtableServiceReadRowsServer struct {
	grpc.ServerStream
}

func (x *bigtableServiceReadRowsServer) Send(m *ReadRowsResponse) error {
	return x.ServerStream.SendMsg(m)
}

func _BigtableService_SampleRowKeys_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(SampleRowKeysRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(BigtableServiceServer).SampleRowKeys(m, &bigtableServiceSampleRowKeysServer{stream})
}

type BigtableService_SampleRowKeysServer interface {
	Send(*SampleRowKeysResponse) error
	grpc.ServerStream
}

type bigtableServiceSampleRowKeysServer struct {
	grpc.ServerStream
}

func (x *bigtableServiceSampleRowKeysServer) Send(m *SampleRowKeysResponse) error {
	return x.ServerStream.SendMsg(m)
}

func _BigtableService_MutateRow_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(MutateRowRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(BigtableServiceServer).MutateRow(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.bigtable.v1.BigtableService/MutateRow",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(BigtableServiceServer).MutateRow(ctx, req.(*MutateRowRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _BigtableService_MutateRows_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(MutateRowsRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(BigtableServiceServer).MutateRows(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.bigtable.v1.BigtableService/MutateRows",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(BigtableServiceServer).MutateRows(ctx, req.(*MutateRowsRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _BigtableService_CheckAndMutateRow_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(CheckAndMutateRowRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(BigtableServiceServer).CheckAndMutateRow(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.bigtable.v1.BigtableService/CheckAndMutateRow",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(BigtableServiceServer).CheckAndMutateRow(ctx, req.(*CheckAndMutateRowRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _BigtableService_ReadModifyWriteRow_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ReadModifyWriteRowRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(BigtableServiceServer).ReadModifyWriteRow(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.bigtable.v1.BigtableService/ReadModifyWriteRow",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(BigtableServiceServer).ReadModifyWriteRow(ctx, req.(*ReadModifyWriteRowRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _BigtableService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "google.bigtable.v1.BigtableService",
	HandlerType: (*BigtableServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "MutateRow",
			Handler:    _BigtableService_MutateRow_Handler,
		},
		{
			MethodName: "MutateRows",
			Handler:    _BigtableService_MutateRows_Handler,
		},
		{
			MethodName: "CheckAndMutateRow",
			Handler:    _BigtableService_CheckAndMutateRow_Handler,
		},
		{
			MethodName: "ReadModifyWriteRow",
			Handler:    _BigtableService_ReadModifyWriteRow_Handler,
		},
	},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "ReadRows",
			Handler:       _BigtableService_ReadRows_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "SampleRowKeys",
			Handler:       _BigtableService_SampleRowKeys_Handler,
			ServerStreams: true,
		},
	},
}

var fileDescriptor1 = []byte{
	// 353 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x92, 0xcd, 0x4a, 0xc3, 0x40,
	0x14, 0x85, 0x1b, 0x10, 0xd1, 0x01, 0x11, 0x07, 0xac, 0x50, 0x77, 0xf5, 0x07, 0x05, 0x3b, 0xf1,
	0xef, 0x05, 0xac, 0x08, 0x42, 0xa9, 0x94, 0x74, 0x51, 0x5c, 0x68, 0x99, 0x24, 0xb7, 0xd3, 0x60,
	0x92, 0x1b, 0x33, 0x93, 0x96, 0xbe, 0x81, 0x4f, 0xe8, 0xf3, 0x48, 0x9a, 0x4c, 0xb4, 0x6d, 0xac,
	0x59, 0xb8, 0xec, 0x3d, 0xdf, 0x3d, 0xe7, 0xf4, 0x4e, 0xc8, 0x93, 0x40, 0x14, 0x3e, 0x30, 0x81,
	0x3e, 0x0f, 0x05, 0xc3, 0x58, 0x98, 0x8e, 0x8f, 0x89, 0x6b, 0xda, 0x9e, 0x50, 0xdc, 0xf6, 0xc1,
	0xf4, 0x42, 0x05, 0x71, 0xc8, 0x7d, 0x53, 0x42, 0x3c, 0xf1, 0x1c, 0x18, 0x46, 0x31, 0x2a, 0x2c,
	0xf4, 0x61, 0x3e, 0x66, 0xf3, 0x31, 0xa5, 0xb9, 0x9f, 0x96, 0xd9, 0xe4, 0xaa, 0xf1, 0x58, 0x3d,
	0xc3, 0xe5, 0x8a, 0x2f, 0x07, 0xa4, 0xb3, 0xcc, 0xbd, 0x31, 0xf8, 0xaf, 0xb6, 0xc3, 0x00, 0xa4,
	0xe4, 0x02, 0x64, 0x6e, 0x7c, 0x98, 0x19, 0x9b, 0xf3, 0x5f, 0x76, 0x32, 0x32, 0x21, 0x88, 0xd4,
	0x2c, 0x13, 0xaf, 0x3f, 0x37, 0xc8, 0x6e, 0x3b, 0x37, 0xe8, 0x67, 0xfb, 0xf4, 0x99, 0x6c, 0x59,
	0xc0, 0x5d, 0x0b, 0xa7, 0x92, 0x1e, 0xb1, 0xd5, 0x3f, 0xcd, 0xb4, 0x6a, 0xc1, 0x7b, 0x02, 0x52,
	0x35, 0x8e, 0xd7, 0x43, 0x32, 0xc2, 0x50, 0x42, 0xb3, 0x76, 0x69, 0xd0, 0x31, 0xd9, 0xe9, 0xf3,
	0x20, 0xf2, 0xc1, 0xc2, 0x69, 0x07, 0x66, 0x92, 0x9e, 0x95, 0xad, 0x2e, 0x20, 0x3a, 0xe4, 0xbc,
	0x02, 0xf9, 0x23, 0xa9, 0x43, 0xb6, 0xbb, 0x89, 0xe2, 0x2a, 0x15, 0x69, 0x69, 0xc1, 0x42, 0xd6,
	0x09, 0x75, 0x4d, 0xe9, 0x4b, 0xb1, 0x87, 0xf4, 0x52, 0xcd, 0x1a, 0x7d, 0x21, 0xa4, 0xa0, 0x25,
	0x3d, 0x59, 0xeb, 0x56, 0x14, 0x3e, 0xfd, 0x0b, 0xd3, 0x6d, 0x69, 0x4c, 0xf6, 0xee, 0xc7, 0xe0,
	0xbc, 0xdd, 0x85, 0xee, 0x77, 0xe7, 0x8b, 0xb2, 0xf5, 0x15, 0x4c, 0x87, 0xb5, 0x2a, 0xd2, 0x45,
	0xe6, 0x2b, 0xa1, 0xe9, 0x0b, 0x75, 0xd1, 0xf5, 0x46, 0xb3, 0x41, 0xec, 0x65, 0xa1, 0xad, 0xdf,
	0x5e, 0x72, 0x91, 0xd3, 0xa9, 0x07, 0xa5, 0x38, 0x4e, 0x9b, 0xb5, 0xf6, 0x2d, 0xa9, 0x3b, 0x18,
	0x94, 0xe8, 0xed, 0xfd, 0xa5, 0xef, 0x4d, 0xf6, 0xd2, 0x73, 0xf7, 0x8c, 0x0f, 0xc3, 0xb0, 0x37,
	0xe7, 0xa7, 0xbf, 0xf9, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x7b, 0xf2, 0x8a, 0xbb, 0x03, 0x00,
	0x00,
}
