// Code generated by protoc-gen-go4grpc; DO NOT EDIT
// source: api.proto

/*
Package apipb is a generated protocol buffer package.

It is generated from these files:
	api.proto

It has these top-level messages:
	HasAncestorRequest
	HasAncestorResponse
	GetRefRequest
	GetRefResponse
	GoFindTryWorkRequest
	GoFindTryWorkResponse
	GerritTryWorkItem
*/
package apipb

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

import (
	context "context"
	grpc "grpc.go4.org"
)

// 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 HasAncestorRequest struct {
	Commit   string `protobuf:"bytes,1,opt,name=commit" json:"commit,omitempty"`
	Ancestor string `protobuf:"bytes,2,opt,name=ancestor" json:"ancestor,omitempty"`
}

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

func (m *HasAncestorRequest) GetCommit() string {
	if m != nil {
		return m.Commit
	}
	return ""
}

func (m *HasAncestorRequest) GetAncestor() string {
	if m != nil {
		return m.Ancestor
	}
	return ""
}

type HasAncestorResponse struct {
	// has_ancestor is whether ancestor appears in commit's history.
	HasAncestor bool `protobuf:"varint,1,opt,name=has_ancestor,json=hasAncestor" json:"has_ancestor,omitempty"`
	// unknown_commit is true if the provided commit was unknown.
	UnknownCommit bool `protobuf:"varint,2,opt,name=unknown_commit,json=unknownCommit" json:"unknown_commit,omitempty"`
}

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

func (m *HasAncestorResponse) GetHasAncestor() bool {
	if m != nil {
		return m.HasAncestor
	}
	return false
}

func (m *HasAncestorResponse) GetUnknownCommit() bool {
	if m != nil {
		return m.UnknownCommit
	}
	return false
}

type GetRefRequest struct {
	Ref string `protobuf:"bytes,1,opt,name=ref" json:"ref,omitempty"`
	// Either gerrit_server & gerrit_project must be specified, or
	// github. Currently only Gerrit is supported.
	GerritServer  string `protobuf:"bytes,2,opt,name=gerrit_server,json=gerritServer" json:"gerrit_server,omitempty"`
	GerritProject string `protobuf:"bytes,3,opt,name=gerrit_project,json=gerritProject" json:"gerrit_project,omitempty"`
}

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

func (m *GetRefRequest) GetRef() string {
	if m != nil {
		return m.Ref
	}
	return ""
}

func (m *GetRefRequest) GetGerritServer() string {
	if m != nil {
		return m.GerritServer
	}
	return ""
}

func (m *GetRefRequest) GetGerritProject() string {
	if m != nil {
		return m.GerritProject
	}
	return ""
}

type GetRefResponse struct {
	Value string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"`
}

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

func (m *GetRefResponse) GetValue() string {
	if m != nil {
		return m.Value
	}
	return ""
}

type GoFindTryWorkRequest struct {
	// for_staging says whether this is a trybot request for the staging
	// cluster. When using staging, the comment "Run-StagingTryBot"
	// is used instead of label:Run-TryBot=1.
	ForStaging bool `protobuf:"varint,1,opt,name=for_staging,json=forStaging" json:"for_staging,omitempty"`
}

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

func (m *GoFindTryWorkRequest) GetForStaging() bool {
	if m != nil {
		return m.ForStaging
	}
	return false
}

type GoFindTryWorkResponse struct {
	// waiting are the Gerrit CLs wanting a trybot run and not yet with results.
	// These might already be running.
	Waiting []*GerritTryWorkItem `protobuf:"bytes,1,rep,name=waiting" json:"waiting,omitempty"`
}

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

func (m *GoFindTryWorkResponse) GetWaiting() []*GerritTryWorkItem {
	if m != nil {
		return m.Waiting
	}
	return nil
}

type GerritTryWorkItem struct {
	Project  string `protobuf:"bytes,1,opt,name=project" json:"project,omitempty"`
	Branch   string `protobuf:"bytes,2,opt,name=branch" json:"branch,omitempty"`
	ChangeId string `protobuf:"bytes,3,opt,name=change_id,json=changeId" json:"change_id,omitempty"`
	Commit   string `protobuf:"bytes,4,opt,name=commit" json:"commit,omitempty"`
	// go_commit is set for subrepos and is the Go commit(s) to test against.
	// go_branch is a branch name of go_commit, for showing to users when
	// a try set fails.
	GoCommit []string `protobuf:"bytes,5,rep,name=go_commit,json=goCommit" json:"go_commit,omitempty"`
	GoBranch []string `protobuf:"bytes,6,rep,name=go_branch,json=goBranch" json:"go_branch,omitempty"`
}

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

func (m *GerritTryWorkItem) GetProject() string {
	if m != nil {
		return m.Project
	}
	return ""
}

func (m *GerritTryWorkItem) GetBranch() string {
	if m != nil {
		return m.Branch
	}
	return ""
}

func (m *GerritTryWorkItem) GetChangeId() string {
	if m != nil {
		return m.ChangeId
	}
	return ""
}

func (m *GerritTryWorkItem) GetCommit() string {
	if m != nil {
		return m.Commit
	}
	return ""
}

func (m *GerritTryWorkItem) GetGoCommit() []string {
	if m != nil {
		return m.GoCommit
	}
	return nil
}

func (m *GerritTryWorkItem) GetGoBranch() []string {
	if m != nil {
		return m.GoBranch
	}
	return nil
}

func init() {
	proto.RegisterType((*HasAncestorRequest)(nil), "apipb.HasAncestorRequest")
	proto.RegisterType((*HasAncestorResponse)(nil), "apipb.HasAncestorResponse")
	proto.RegisterType((*GetRefRequest)(nil), "apipb.GetRefRequest")
	proto.RegisterType((*GetRefResponse)(nil), "apipb.GetRefResponse")
	proto.RegisterType((*GoFindTryWorkRequest)(nil), "apipb.GoFindTryWorkRequest")
	proto.RegisterType((*GoFindTryWorkResponse)(nil), "apipb.GoFindTryWorkResponse")
	proto.RegisterType((*GerritTryWorkItem)(nil), "apipb.GerritTryWorkItem")
}

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

type MaintnerServiceClient interface {
	// HasAncestor reports whether one commit contains another commit
	// in its git history.
	HasAncestor(ctx context.Context, in *HasAncestorRequest, opts ...grpc.CallOption) (*HasAncestorResponse, error)
	// GetRef returns information about a git ref.
	GetRef(ctx context.Context, in *GetRefRequest, opts ...grpc.CallOption) (*GetRefResponse, error)
	// GoFindTryWork finds trybot work for the coordinator to build & test.
	GoFindTryWork(ctx context.Context, in *GoFindTryWorkRequest, opts ...grpc.CallOption) (*GoFindTryWorkResponse, error)
}

type maintnerServiceClient struct {
	cc *grpc.ClientConn
}

func NewMaintnerServiceClient(cc *grpc.ClientConn) MaintnerServiceClient {
	return &maintnerServiceClient{cc}
}

func (c *maintnerServiceClient) HasAncestor(ctx context.Context, in *HasAncestorRequest, opts ...grpc.CallOption) (*HasAncestorResponse, error) {
	out := new(HasAncestorResponse)
	err := grpc.Invoke(ctx, "/apipb.MaintnerService/HasAncestor", in, out, c.cc, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *maintnerServiceClient) GetRef(ctx context.Context, in *GetRefRequest, opts ...grpc.CallOption) (*GetRefResponse, error) {
	out := new(GetRefResponse)
	err := grpc.Invoke(ctx, "/apipb.MaintnerService/GetRef", in, out, c.cc, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *maintnerServiceClient) GoFindTryWork(ctx context.Context, in *GoFindTryWorkRequest, opts ...grpc.CallOption) (*GoFindTryWorkResponse, error) {
	out := new(GoFindTryWorkResponse)
	err := grpc.Invoke(ctx, "/apipb.MaintnerService/GoFindTryWork", in, out, c.cc, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// Server API for MaintnerService service

type MaintnerServiceServer interface {
	// HasAncestor reports whether one commit contains another commit
	// in its git history.
	HasAncestor(context.Context, *HasAncestorRequest) (*HasAncestorResponse, error)
	// GetRef returns information about a git ref.
	GetRef(context.Context, *GetRefRequest) (*GetRefResponse, error)
	// GoFindTryWork finds trybot work for the coordinator to build & test.
	GoFindTryWork(context.Context, *GoFindTryWorkRequest) (*GoFindTryWorkResponse, error)
}

func RegisterMaintnerServiceServer(s *grpc.Server, srv MaintnerServiceServer) {
	s.RegisterService(&_MaintnerService_serviceDesc, srv)
}

func _MaintnerService_HasAncestor_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(HasAncestorRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(MaintnerServiceServer).HasAncestor(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/apipb.MaintnerService/HasAncestor",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(MaintnerServiceServer).HasAncestor(ctx, req.(*HasAncestorRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _MaintnerService_GetRef_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetRefRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(MaintnerServiceServer).GetRef(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/apipb.MaintnerService/GetRef",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(MaintnerServiceServer).GetRef(ctx, req.(*GetRefRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _MaintnerService_GoFindTryWork_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GoFindTryWorkRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(MaintnerServiceServer).GoFindTryWork(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/apipb.MaintnerService/GoFindTryWork",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(MaintnerServiceServer).GoFindTryWork(ctx, req.(*GoFindTryWorkRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _MaintnerService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "apipb.MaintnerService",
	HandlerType: (*MaintnerServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "HasAncestor",
			Handler:    _MaintnerService_HasAncestor_Handler,
		},
		{
			MethodName: "GetRef",
			Handler:    _MaintnerService_GetRef_Handler,
		},
		{
			MethodName: "GoFindTryWork",
			Handler:    _MaintnerService_GoFindTryWork_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "api.proto",
}

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

var fileDescriptor0 = []byte{
	// 445 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x53, 0x51, 0x6f, 0xd3, 0x30,
	0x10, 0x56, 0x57, 0xda, 0xb5, 0xd7, 0x75, 0x80, 0xe9, 0x50, 0x48, 0x91, 0x18, 0x41, 0xa0, 0x3d,
	0xf5, 0xa1, 0x08, 0xf1, 0x0c, 0x43, 0x74, 0x03, 0x21, 0xa1, 0x0c, 0x89, 0xc7, 0xc8, 0x4d, 0xaf,
	0xa9, 0x19, 0xb1, 0x83, 0xed, 0x6e, 0xe2, 0x7f, 0xf1, 0x6b, 0xf8, 0x35, 0x28, 0xf6, 0xb9, 0xa4,
	0x6b, 0xdf, 0x72, 0xdf, 0x7d, 0xe7, 0xfb, 0xee, 0xbe, 0x0b, 0xf4, 0x79, 0x25, 0x26, 0x95, 0x56,
	0x56, 0xb1, 0x0e, 0xaf, 0x44, 0x35, 0x4f, 0x2e, 0x80, 0x5d, 0x70, 0xf3, 0x4e, 0xe6, 0x68, 0xac,
	0xd2, 0x29, 0xfe, 0x5a, 0xa3, 0xb1, 0xec, 0x31, 0x74, 0x73, 0x55, 0x96, 0xc2, 0x46, 0xad, 0xd3,
	0xd6, 0x59, 0x3f, 0xa5, 0x88, 0xc5, 0xd0, 0xe3, 0x44, 0x8d, 0x0e, 0x5c, 0x66, 0x13, 0x27, 0x19,
	0x3c, 0xda, 0x7a, 0xc9, 0x54, 0x4a, 0x1a, 0x64, 0xcf, 0xe1, 0x68, 0xc5, 0x4d, 0xb6, 0x29, 0xab,
	0x1f, 0xec, 0xa5, 0x83, 0xd5, 0x7f, 0x2a, 0x7b, 0x09, 0xc7, 0x6b, 0x79, 0x2d, 0xd5, 0xad, 0xcc,
	0xa8, 0xeb, 0x81, 0x23, 0x0d, 0x09, 0x3d, 0x77, 0x60, 0x52, 0xc2, 0x70, 0x86, 0x36, 0xc5, 0x65,
	0x50, 0xf9, 0x00, 0xda, 0x1a, 0x97, 0x24, 0xb1, 0xfe, 0x64, 0x2f, 0x60, 0x58, 0xa0, 0xd6, 0xc2,
	0x66, 0x06, 0xf5, 0x0d, 0x06, 0x91, 0x47, 0x1e, 0xbc, 0x72, 0x58, 0xdd, 0x8e, 0x48, 0x95, 0x56,
	0x3f, 0x30, 0xb7, 0x51, 0xdb, 0xb1, 0xa8, 0xf4, 0xab, 0x07, 0x93, 0x57, 0x70, 0x1c, 0xda, 0xd1,
	0x28, 0x23, 0xe8, 0xdc, 0xf0, 0x9f, 0x6b, 0xa4, 0x8e, 0x3e, 0x48, 0xde, 0xc2, 0x68, 0xa6, 0x3e,
	0x0a, 0xb9, 0xf8, 0xa6, 0x7f, 0x7f, 0x57, 0xfa, 0x3a, 0xa8, 0x7b, 0x06, 0x83, 0xa5, 0xd2, 0x99,
	0xb1, 0xbc, 0x10, 0xb2, 0xa0, 0xb9, 0x61, 0xa9, 0xf4, 0x95, 0x47, 0x92, 0xcf, 0x70, 0x72, 0xa7,
	0x90, 0xfa, 0x4c, 0xe1, 0xf0, 0x96, 0x0b, 0xeb, 0xab, 0xda, 0x67, 0x83, 0x69, 0x34, 0x71, 0x66,
	0x4d, 0x66, 0x4e, 0x20, 0xd1, 0x2f, 0x2d, 0x96, 0x69, 0x20, 0x26, 0x7f, 0x5a, 0xf0, 0x70, 0x27,
	0xcd, 0x22, 0x38, 0x0c, 0x33, 0x7a, 0xcd, 0x21, 0xac, 0x1d, 0x9e, 0x6b, 0x2e, 0xf3, 0x15, 0xad,
	0x88, 0x22, 0x36, 0x86, 0x7e, 0xbe, 0xe2, 0xb2, 0xc0, 0x4c, 0x2c, 0x68, 0x2f, 0x3d, 0x0f, 0x5c,
	0x2e, 0x1a, 0x67, 0x71, 0x6f, 0xeb, 0x2c, 0xc6, 0xd0, 0x2f, 0x54, 0xf0, 0xae, 0x73, 0xda, 0xae,
	0x8b, 0x0a, 0x75, 0xde, 0x4c, 0x52, 0xb3, 0x6e, 0x48, 0xbe, 0x77, 0xf1, 0xf4, 0x6f, 0x0b, 0xee,
	0x7f, 0xe1, 0x42, 0x5a, 0x89, 0xba, 0xb6, 0x47, 0xe4, 0xc8, 0x3e, 0xc0, 0xa0, 0x71, 0x48, 0xec,
	0x09, 0x0d, 0xbf, 0x7b, 0xa6, 0x71, 0xbc, 0x2f, 0x45, 0x4b, 0x7c, 0x03, 0x5d, 0x6f, 0x1f, 0x1b,
	0x6d, 0xb6, 0xd7, 0x38, 0x9e, 0xf8, 0xe4, 0x0e, 0x4a, 0x65, 0x9f, 0x60, 0xb8, 0x65, 0x0a, 0x1b,
	0x07, 0xde, 0x1e, 0x8f, 0xe3, 0xa7, 0xfb, 0x93, 0xfe, 0xad, 0x79, 0xd7, 0xfd, 0x69, 0xaf, 0xff,
	0x05, 0x00, 0x00, 0xff, 0xff, 0xbb, 0x60, 0x62, 0xc0, 0x76, 0x03, 0x00, 0x00,
}
