// Code generated by protoc-gen-go. DO NOT EDIT.
// source: go.chromium.org/luci/grpc/prpc/helloworld_test.proto

package prpc

import (
	context "context"
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	field_mask "google.golang.org/genproto/protobuf/field_mask"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
	math "math"
)

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

// The request message containing the user's name.
type HelloRequest struct {
	Name                 string                `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Fields               *field_mask.FieldMask `protobuf:"bytes,2,opt,name=fields,proto3" json:"fields,omitempty"`
	XXX_NoUnkeyedLiteral struct{}              `json:"-"`
	XXX_unrecognized     []byte                `json:"-"`
	XXX_sizecache        int32                 `json:"-"`
}

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

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

var xxx_messageInfo_HelloRequest proto.InternalMessageInfo

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

func (m *HelloRequest) GetFields() *field_mask.FieldMask {
	if m != nil {
		return m.Fields
	}
	return nil
}

// The response message containing the greetings
type HelloReply struct {
	Message              string   `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_HelloReply proto.InternalMessageInfo

func (m *HelloReply) GetMessage() string {
	if m != nil {
		return m.Message
	}
	return ""
}

type MultiplyRequest struct {
	X                    int32    `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"`
	Y                    int32    `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_MultiplyRequest proto.InternalMessageInfo

func (m *MultiplyRequest) GetX() int32 {
	if m != nil {
		return m.X
	}
	return 0
}

func (m *MultiplyRequest) GetY() int32 {
	if m != nil {
		return m.Y
	}
	return 0
}

type MultiplyResponse struct {
	Z                    int32    `protobuf:"varint,1,opt,name=z,proto3" json:"z,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_MultiplyResponse proto.InternalMessageInfo

func (m *MultiplyResponse) GetZ() int32 {
	if m != nil {
		return m.Z
	}
	return 0
}

func init() {
	proto.RegisterType((*HelloRequest)(nil), "prpc.HelloRequest")
	proto.RegisterType((*HelloReply)(nil), "prpc.HelloReply")
	proto.RegisterType((*MultiplyRequest)(nil), "prpc.MultiplyRequest")
	proto.RegisterType((*MultiplyResponse)(nil), "prpc.MultiplyResponse")
}

func init() {
	proto.RegisterFile("go.chromium.org/luci/grpc/prpc/helloworld_test.proto", fileDescriptor_a601d72b9fd9e561)
}

var fileDescriptor_a601d72b9fd9e561 = []byte{
	// 298 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xbf, 0x6b, 0xfb, 0x30,
	0x10, 0xc5, 0xe3, 0x2f, 0xf9, 0xf5, 0xbd, 0x06, 0x1a, 0x04, 0x2d, 0xc1, 0x93, 0xf1, 0x50, 0xb2,
	0x54, 0x06, 0xb7, 0x5b, 0xe9, 0x14, 0x68, 0xbb, 0x64, 0x71, 0xa1, 0x6b, 0x70, 0x9c, 0x8b, 0x62,
	0x22, 0x47, 0xaa, 0x24, 0xd3, 0x28, 0x7f, 0x7d, 0x91, 0x1c, 0xd1, 0x36, 0x8b, 0xd0, 0xbd, 0xfb,
	0xe8, 0xdd, 0xd3, 0xc1, 0x23, 0x13, 0xb4, 0xda, 0x29, 0xd1, 0xd4, 0x6d, 0x43, 0x85, 0x62, 0x19,
	0x6f, 0xab, 0x3a, 0x63, 0x4a, 0x56, 0x99, 0x74, 0xc7, 0x0e, 0x39, 0x17, 0x5f, 0x42, 0xf1, 0xcd,
	0xca, 0xa0, 0x36, 0x54, 0x2a, 0x61, 0x04, 0xe9, 0xbb, 0x5e, 0x9c, 0x30, 0x21, 0x18, 0xc7, 0xcc,
	0x6b, 0xeb, 0x76, 0x9b, 0x6d, 0x6b, 0xe4, 0x9b, 0x55, 0x53, 0xea, 0x7d, 0xc7, 0xa5, 0x1f, 0x30,
	0x79, 0x73, 0x06, 0x05, 0x7e, 0xb6, 0xa8, 0x0d, 0x21, 0xd0, 0x3f, 0x94, 0x0d, 0xce, 0xa2, 0x24,
	0x9a, 0xff, 0x2f, 0xfc, 0x9d, 0xe4, 0x30, 0xf4, 0xef, 0xf4, 0xec, 0x5f, 0x12, 0xcd, 0xaf, 0xf2,
	0x98, 0x76, 0xb6, 0x34, 0xd8, 0xd2, 0x17, 0xd7, 0x5e, 0x96, 0x7a, 0x5f, 0x9c, 0xc9, 0xf4, 0x0e,
	0xe0, 0xec, 0x2b, 0xb9, 0x25, 0x33, 0x18, 0x35, 0xa8, 0x75, 0xc9, 0x82, 0x71, 0x28, 0xd3, 0x7b,
	0xb8, 0x5e, 0xb6, 0xdc, 0xd4, 0x92, 0xdb, 0x10, 0x61, 0x02, 0xd1, 0xd1, 0x63, 0x83, 0x22, 0x3a,
	0xba, 0xca, 0xfa, 0xb9, 0x83, 0x22, 0xb2, 0x69, 0x02, 0xd3, 0x1f, 0x5c, 0x4b, 0x71, 0xd0, 0xe8,
	0x88, 0x53, 0xe0, 0x4f, 0xf9, 0x33, 0x8c, 0x5e, 0x15, 0xa2, 0x41, 0x45, 0x72, 0x18, 0xbf, 0x97,
	0xd6, 0xc7, 0x20, 0x84, 0xba, 0x85, 0xd0, 0xdf, 0x7f, 0x8d, 0xa7, 0x7f, 0x34, 0xc9, 0x6d, 0xda,
	0xcb, 0x17, 0xd0, 0x5f, 0x94, 0xbc, 0x22, 0x4f, 0x30, 0x0e, 0x83, 0xc8, 0x4d, 0xc7, 0x5d, 0xe4,
	0x8c, 0x6f, 0x2f, 0xe5, 0x2e, 0x4f, 0xda, 0x5b, 0x0f, 0xfd, 0x62, 0x1e, 0xbe, 0x03, 0x00, 0x00,
	0xff, 0xff, 0x79, 0xd2, 0x7b, 0xe3, 0xbb, 0x01, 0x00, 0x00,
}

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

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

// GreeterClient is the client API for Greeter service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type GreeterClient interface {
	// Sends a greeting
	SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}
type greeterPRPCClient struct {
	client *Client
}

func NewGreeterPRPCClient(client *Client) GreeterClient {
	return &greeterPRPCClient{client}
}

func (c *greeterPRPCClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
	out := new(HelloReply)
	err := c.client.Call(ctx, "prpc.Greeter", "SayHello", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

type greeterClient struct {
	cc grpc.ClientConnInterface
}

func NewGreeterClient(cc grpc.ClientConnInterface) GreeterClient {
	return &greeterClient{cc}
}

func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
	out := new(HelloReply)
	err := c.cc.Invoke(ctx, "/prpc.Greeter/SayHello", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// GreeterServer is the server API for Greeter service.
type GreeterServer interface {
	// Sends a greeting
	SayHello(context.Context, *HelloRequest) (*HelloReply, error)
}

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

func (*UnimplementedGreeterServer) SayHello(ctx context.Context, req *HelloRequest) (*HelloReply, error) {
	return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented")
}

func RegisterGreeterServer(s Registrar, srv GreeterServer) {
	s.RegisterService(&_Greeter_serviceDesc, srv)
}

func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(HelloRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GreeterServer).SayHello(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/prpc.Greeter/SayHello",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _Greeter_serviceDesc = grpc.ServiceDesc{
	ServiceName: "prpc.Greeter",
	HandlerType: (*GreeterServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "SayHello",
			Handler:    _Greeter_SayHello_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "go.chromium.org/luci/grpc/prpc/helloworld_test.proto",
}

// CalcClient is the client API for Calc service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type CalcClient interface {
	Multiply(ctx context.Context, in *MultiplyRequest, opts ...grpc.CallOption) (*MultiplyResponse, error)
}
type calcPRPCClient struct {
	client *Client
}

func NewCalcPRPCClient(client *Client) CalcClient {
	return &calcPRPCClient{client}
}

func (c *calcPRPCClient) Multiply(ctx context.Context, in *MultiplyRequest, opts ...grpc.CallOption) (*MultiplyResponse, error) {
	out := new(MultiplyResponse)
	err := c.client.Call(ctx, "prpc.Calc", "Multiply", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

type calcClient struct {
	cc grpc.ClientConnInterface
}

func NewCalcClient(cc grpc.ClientConnInterface) CalcClient {
	return &calcClient{cc}
}

func (c *calcClient) Multiply(ctx context.Context, in *MultiplyRequest, opts ...grpc.CallOption) (*MultiplyResponse, error) {
	out := new(MultiplyResponse)
	err := c.cc.Invoke(ctx, "/prpc.Calc/Multiply", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// CalcServer is the server API for Calc service.
type CalcServer interface {
	Multiply(context.Context, *MultiplyRequest) (*MultiplyResponse, error)
}

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

func (*UnimplementedCalcServer) Multiply(ctx context.Context, req *MultiplyRequest) (*MultiplyResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Multiply not implemented")
}

func RegisterCalcServer(s Registrar, srv CalcServer) {
	s.RegisterService(&_Calc_serviceDesc, srv)
}

func _Calc_Multiply_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(MultiplyRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(CalcServer).Multiply(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/prpc.Calc/Multiply",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(CalcServer).Multiply(ctx, req.(*MultiplyRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _Calc_serviceDesc = grpc.ServiceDesc{
	ServiceName: "prpc.Calc",
	HandlerType: (*CalcServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Multiply",
			Handler:    _Calc_Multiply_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "go.chromium.org/luci/grpc/prpc/helloworld_test.proto",
}
