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

package api

import (
	context "context"
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	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

// Request for the method discovery endpoint.
type MethodGetRequest struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_MethodGetRequest proto.InternalMessageInfo

// Response from the method discovery endpoint.
type MethodGetResponse struct {
	// All registered methods.
	Methods              []*MethodGetResponse_Method `protobuf:"bytes,1,rep,name=methods,proto3" json:"methods,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                    `json:"-"`
	XXX_unrecognized     []byte                      `json:"-"`
	XXX_sizecache        int32                       `json:"-"`
}

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

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

var xxx_messageInfo_MethodGetResponse proto.InternalMessageInfo

func (m *MethodGetResponse) GetMethods() []*MethodGetResponse_Method {
	if m != nil {
		return m.Methods
	}
	return nil
}

type MethodGetResponse_Method struct {
	// The full method name, i.e. package.Service/Method.
	Method               string   `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_MethodGetResponse_Method proto.InternalMessageInfo

func (m *MethodGetResponse_Method) GetMethod() string {
	if m != nil {
		return m.Method
	}
	return ""
}

// Request for the API (major) version number.
type VersionGetRequest struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_VersionGetRequest proto.InternalMessageInfo

// Response with the API (major) version number.
type VersionGetResponse struct {
	Version              *VersionGetResponse_Version `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                    `json:"-"`
	XXX_unrecognized     []byte                      `json:"-"`
	XXX_sizecache        int32                       `json:"-"`
}

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

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

var xxx_messageInfo_VersionGetResponse proto.InternalMessageInfo

func (m *VersionGetResponse) GetVersion() *VersionGetResponse_Version {
	if m != nil {
		return m.Version
	}
	return nil
}

type VersionGetResponse_Version struct {
	// Version number components: "major.minor.bug".
	Major                int32    `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"`
	Minor                int32    `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"`
	Bug                  int32    `protobuf:"varint,3,opt,name=bug,proto3" json:"bug,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_VersionGetResponse_Version proto.InternalMessageInfo

func (m *VersionGetResponse_Version) GetMajor() int32 {
	if m != nil {
		return m.Major
	}
	return 0
}

func (m *VersionGetResponse_Version) GetMinor() int32 {
	if m != nil {
		return m.Minor
	}
	return 0
}

func (m *VersionGetResponse_Version) GetBug() int32 {
	if m != nil {
		return m.Bug
	}
	return 0
}

func init() {
	proto.RegisterType((*MethodGetRequest)(nil), "chromite.api.MethodGetRequest")
	proto.RegisterType((*MethodGetResponse)(nil), "chromite.api.MethodGetResponse")
	proto.RegisterType((*MethodGetResponse_Method)(nil), "chromite.api.MethodGetResponse.Method")
	proto.RegisterType((*VersionGetRequest)(nil), "chromite.api.VersionGetRequest")
	proto.RegisterType((*VersionGetResponse)(nil), "chromite.api.VersionGetResponse")
	proto.RegisterType((*VersionGetResponse_Version)(nil), "chromite.api.VersionGetResponse.Version")
}

func init() { proto.RegisterFile("chromite/api/api.proto", fileDescriptor_4c67cb8e48a2638e) }

var fileDescriptor_4c67cb8e48a2638e = []byte{
	// 346 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xc1, 0x6a, 0xfa, 0x40,
	0x10, 0xc6, 0x89, 0x41, 0xc3, 0x7f, 0xf4, 0x5f, 0xe2, 0xb6, 0x48, 0x08, 0xa5, 0x86, 0x1c, 0x8a,
	0xa7, 0x04, 0x52, 0x28, 0x3d, 0x16, 0x2f, 0x39, 0x79, 0x49, 0xa1, 0x14, 0x2f, 0x25, 0xea, 0x36,
	0x6e, 0x69, 0x32, 0xe9, 0x66, 0x63, 0xe9, 0xe3, 0xf4, 0x55, 0x7c, 0x1f, 0xdf, 0xa1, 0xb8, 0xbb,
	0x29, 0x11, 0x11, 0x0f, 0x81, 0xcc, 0x6f, 0xf7, 0x9b, 0x6f, 0xe6, 0x63, 0x61, 0xb4, 0x5c, 0x73,
	0xcc, 0x99, 0xa0, 0x61, 0x5a, 0xb2, 0xfd, 0x17, 0x94, 0x1c, 0x05, 0x92, 0x41, 0xc3, 0x83, 0xb4,
	0x64, 0xee, 0xf5, 0xc1, 0xad, 0x45, 0xcd, 0x3e, 0x56, 0xaf, 0x7f, 0x77, 0x7d, 0x02, 0xf6, 0x8c,
	0x8a, 0x35, 0xae, 0x62, 0x2a, 0x12, 0xfa, 0x59, 0xd3, 0x4a, 0xf8, 0x5f, 0x30, 0x6c, 0xb1, 0xaa,
	0xc4, 0xa2, 0xa2, 0xe4, 0x11, 0xac, 0x5c, 0xc2, 0xca, 0x31, 0x3c, 0x73, 0xd2, 0x8f, 0x6e, 0x83,
	0xb6, 0x4d, 0x70, 0xa4, 0xd0, 0x24, 0x69, 0x64, 0xae, 0x07, 0x3d, 0x85, 0xc8, 0x08, 0x7a, 0x0a,
	0x3a, 0x86, 0x67, 0x4c, 0xfe, 0x25, 0xba, 0xf2, 0x2f, 0x61, 0xf8, 0x4c, 0x79, 0xc5, 0xb0, 0x68,
	0x4d, 0xf3, 0x63, 0x00, 0x69, 0x53, 0x3d, 0xcf, 0x14, 0xac, 0x8d, 0xa2, 0xb2, 0x49, 0x3f, 0x9a,
	0x1c, 0xce, 0x73, 0x2c, 0x69, 0x50, 0xd2, 0x08, 0xdd, 0x18, 0x2c, 0xcd, 0xc8, 0x15, 0x74, 0xf3,
	0xf4, 0x1d, 0xb9, 0x6c, 0xd6, 0x4d, 0x54, 0x21, 0x29, 0x2b, 0x90, 0x3b, 0x1d, 0x4d, 0xf7, 0x05,
	0xb1, 0xc1, 0x5c, 0xd4, 0x99, 0x63, 0x4a, 0xb6, 0xff, 0x8d, 0x36, 0xf0, 0x5f, 0xad, 0xf6, 0x44,
	0xf9, 0x86, 0x2d, 0x29, 0x79, 0x01, 0x33, 0xa6, 0x82, 0xdc, 0x9c, 0xcc, 0x48, 0xee, 0xe6, 0x8e,
	0xcf, 0x64, 0xe8, 0xdb, 0xdb, 0x9d, 0x3b, 0x00, 0x88, 0xa9, 0x98, 0xe9, 0x14, 0xfb, 0xdb, 0x9d,
	0x6b, 0x81, 0x99, 0x96, 0xcc, 0xee, 0x44, 0xdf, 0x70, 0xa1, 0x17, 0x68, 0x8c, 0xe7, 0xca, 0x78,
	0x7c, 0x3a, 0x0c, 0xe5, 0xec, 0x9d, 0x4b, 0xab, 0x65, 0xad, 0x0f, 0x0f, 0xac, 0xa7, 0x0f, 0xf3,
	0xfb, 0x0c, 0x75, 0x93, 0x3a, 0x0f, 0x90, 0x67, 0x61, 0x53, 0x60, 0x15, 0xb2, 0xe2, 0x8d, 0xa7,
	0xa1, 0x7c, 0x62, 0x61, 0x86, 0x61, 0xfb, 0x09, 0x2e, 0x7a, 0x12, 0xdf, 0xfd, 0x06, 0x00, 0x00,
	0xff, 0xff, 0x9f, 0x6c, 0x42, 0xd2, 0xbf, 0x02, 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

// MethodServiceClient is the client API for MethodService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type MethodServiceClient interface {
	Get(ctx context.Context, in *MethodGetRequest, opts ...grpc.CallOption) (*MethodGetResponse, error)
}

type methodServiceClient struct {
	cc *grpc.ClientConn
}

func NewMethodServiceClient(cc *grpc.ClientConn) MethodServiceClient {
	return &methodServiceClient{cc}
}

func (c *methodServiceClient) Get(ctx context.Context, in *MethodGetRequest, opts ...grpc.CallOption) (*MethodGetResponse, error) {
	out := new(MethodGetResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.MethodService/Get", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// MethodServiceServer is the server API for MethodService service.
type MethodServiceServer interface {
	Get(context.Context, *MethodGetRequest) (*MethodGetResponse, error)
}

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

func (*UnimplementedMethodServiceServer) Get(ctx context.Context, req *MethodGetRequest) (*MethodGetResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Get not implemented")
}

func RegisterMethodServiceServer(s *grpc.Server, srv MethodServiceServer) {
	s.RegisterService(&_MethodService_serviceDesc, srv)
}

func _MethodService_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(MethodGetRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(MethodServiceServer).Get(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.MethodService/Get",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(MethodServiceServer).Get(ctx, req.(*MethodGetRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _MethodService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.MethodService",
	HandlerType: (*MethodServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Get",
			Handler:    _MethodService_Get_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/api.proto",
}

// VersionServiceClient is the client API for VersionService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type VersionServiceClient interface {
	Get(ctx context.Context, in *VersionGetRequest, opts ...grpc.CallOption) (*VersionGetResponse, error)
}

type versionServiceClient struct {
	cc *grpc.ClientConn
}

func NewVersionServiceClient(cc *grpc.ClientConn) VersionServiceClient {
	return &versionServiceClient{cc}
}

func (c *versionServiceClient) Get(ctx context.Context, in *VersionGetRequest, opts ...grpc.CallOption) (*VersionGetResponse, error) {
	out := new(VersionGetResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.VersionService/Get", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// VersionServiceServer is the server API for VersionService service.
type VersionServiceServer interface {
	Get(context.Context, *VersionGetRequest) (*VersionGetResponse, error)
}

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

func (*UnimplementedVersionServiceServer) Get(ctx context.Context, req *VersionGetRequest) (*VersionGetResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Get not implemented")
}

func RegisterVersionServiceServer(s *grpc.Server, srv VersionServiceServer) {
	s.RegisterService(&_VersionService_serviceDesc, srv)
}

func _VersionService_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(VersionGetRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(VersionServiceServer).Get(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.VersionService/Get",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(VersionServiceServer).Get(ctx, req.(*VersionGetRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _VersionService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.VersionService",
	HandlerType: (*VersionServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Get",
			Handler:    _VersionService_Get_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/api.proto",
}
