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

package grpc

import (
	proto "github.com/golang/protobuf/proto"
	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
	prototype "github.com/golang/protobuf/v2/reflect/prototype"
	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
)

// 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 Request struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

type xxx_Request struct{ m *Request }

func (m *Request) ProtoReflect() protoreflect.Message {
	return xxx_Request{m}
}
func (m xxx_Request) Type() protoreflect.MessageType {
	return xxx_Grpc_ProtoFile_MessageTypes[0].Type
}
func (m xxx_Request) KnownFields() protoreflect.KnownFields {
	return xxx_Grpc_ProtoFile_MessageTypes[0].KnownFieldsOf(m.m)
}
func (m xxx_Request) UnknownFields() protoreflect.UnknownFields {
	return xxx_Grpc_ProtoFile_MessageTypes[0].UnknownFieldsOf(m.m)
}
func (m xxx_Request) Interface() protoreflect.ProtoMessage {
	return m.m
}
func (m xxx_Request) ProtoMutable() {}

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

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

var xxx_messageInfo_Request proto.InternalMessageInfo

type Response struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

type xxx_Response struct{ m *Response }

func (m *Response) ProtoReflect() protoreflect.Message {
	return xxx_Response{m}
}
func (m xxx_Response) Type() protoreflect.MessageType {
	return xxx_Grpc_ProtoFile_MessageTypes[1].Type
}
func (m xxx_Response) KnownFields() protoreflect.KnownFields {
	return xxx_Grpc_ProtoFile_MessageTypes[1].KnownFieldsOf(m.m)
}
func (m xxx_Response) UnknownFields() protoreflect.UnknownFields {
	return xxx_Grpc_ProtoFile_MessageTypes[1].UnknownFieldsOf(m.m)
}
func (m xxx_Response) Interface() protoreflect.ProtoMessage {
	return m.m
}
func (m xxx_Response) ProtoMutable() {}

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

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

var xxx_messageInfo_Response proto.InternalMessageInfo

func init() {
	proto.RegisterFile("grpc/grpc.proto", fileDescriptor_81ea47a3f88c2082)
	proto.RegisterType((*Request)(nil), "goproto.protoc.grpc.Request")
	proto.RegisterType((*Response)(nil), "goproto.protoc.grpc.Response")
}

var fileDescriptor_81ea47a3f88c2082 = []byte{
	// 211 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4f, 0x2f, 0x2a, 0x48,
	0xd6, 0x07, 0x11, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0xc2, 0xe9, 0xf9, 0x60, 0x06, 0x84,
	0x9b, 0xac, 0x07, 0x92, 0x52, 0xe2, 0xe4, 0x62, 0x0f, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x51,
	0xe2, 0xe2, 0xe2, 0x08, 0x4a, 0x2d, 0x2e, 0xc8, 0xcf, 0x2b, 0x4e, 0x35, 0xda, 0xc8, 0xc4, 0xc5,
	0x12, 0x92, 0x5a, 0x5c, 0x22, 0xe4, 0xc1, 0xc5, 0x19, 0x9a, 0x97, 0x58, 0x54, 0xe9, 0x9c, 0x98,
	0x93, 0x23, 0x24, 0xa3, 0x87, 0xc5, 0x08, 0x3d, 0xa8, 0x7e, 0x29, 0x59, 0x1c, 0xb2, 0x10, 0x23,
	0x85, 0xbc, 0xb9, 0xb8, 0x5c, 0xf2, 0xcb, 0xf3, 0x8a, 0x4b, 0x8a, 0x52, 0x13, 0x73, 0x29, 0x32,
	0xca, 0x80, 0x51, 0xc8, 0x93, 0x8b, 0x23, 0xb4, 0x80, 0x0a, 0x46, 0x69, 0x30, 0x0a, 0xb9, 0x73,
	0xb1, 0x38, 0x65, 0xa6, 0x64, 0x52, 0x68, 0x8c, 0x01, 0xa3, 0x93, 0x7d, 0x94, 0x6d, 0x7a, 0x66,
	0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x7e, 0x7a, 0x7e, 0x4e, 0x62, 0x5e, 0xba, 0x3e,
	0x58, 0x75, 0x52, 0x69, 0x9a, 0x7e, 0x99, 0x91, 0x7e, 0x72, 0x6e, 0x0a, 0x84, 0x9f, 0xac, 0x9b,
	0x9e, 0x9a, 0xa7, 0x9b, 0x9e, 0xaf, 0x5f, 0x92, 0x5a, 0x5c, 0x92, 0x92, 0x58, 0x92, 0x08, 0x8e,
	0xa6, 0x24, 0x36, 0xb0, 0xa4, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x29, 0xd5, 0xc4, 0xd0, 0xba,
	0x01, 0x00, 0x00,
}

func init() {
	xxx_Grpc_ProtoFile_FileDesc.Messages = xxx_Grpc_ProtoFile_MessageDescs[0:2]
	var err error
	Grpc_ProtoFile, err = prototype.NewFile(&xxx_Grpc_ProtoFile_FileDesc)
	if err != nil {
		panic(err)
	}
}

const _ = protoimpl.EnforceVersion(protoimpl.Version - 0)

var Grpc_ProtoFile protoreflect.FileDescriptor

var xxx_Grpc_ProtoFile_FileDesc = prototype.File{
	Syntax:  protoreflect.Proto3,
	Path:    "grpc/grpc.proto",
	Package: "goproto.protoc.grpc",
}
var xxx_Grpc_ProtoFile_MessageTypes = [2]protoimpl.MessageType{
	{Type: prototype.GoMessage(
		xxx_Grpc_ProtoFile_MessageDescs[0].Reference(),
		func(protoreflect.MessageType) protoreflect.ProtoMessage {
			return new(Request)
		},
	)},
	{Type: prototype.GoMessage(
		xxx_Grpc_ProtoFile_MessageDescs[1].Reference(),
		func(protoreflect.MessageType) protoreflect.ProtoMessage {
			return new(Response)
		},
	)},
}
var xxx_Grpc_ProtoFile_MessageDescs = [2]prototype.Message{
	{
		Name: "Request",
	},
	{
		Name: "Response",
	},
}
