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

package apipb

import (
	context "context"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7

// MaintnerServiceClient is the client API for MaintnerService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
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)
	// ListGoReleases lists Go releases sorted by version with latest first.
	//
	// A release is considered to exist for each git tag named "goX", "goX.Y", or
	// "goX.Y.Z", as long as it has a corresponding "release-branch.goX" or
	// "release-branch.goX.Y" release branch.
	//
	// ListGoReleases returns only the latest patch versions of releases which
	// are considered supported per policy. For example, Go 1.12.6 and 1.11.11.
	// The response is guaranteed to have two versions, otherwise an error
	// is returned.
	ListGoReleases(ctx context.Context, in *ListGoReleasesRequest, opts ...grpc.CallOption) (*ListGoReleasesResponse, error)
	// GetDashboard returns the information for the build.golang.org
	// dashboard. It does not (at least currently)
	// contain any pass/fail information; it only contains information on the branches
	// and commits themselves.
	GetDashboard(ctx context.Context, in *DashboardRequest, opts ...grpc.CallOption) (*DashboardResponse, error)
}

type maintnerServiceClient struct {
	cc grpc.ClientConnInterface
}

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

func (c *maintnerServiceClient) HasAncestor(ctx context.Context, in *HasAncestorRequest, opts ...grpc.CallOption) (*HasAncestorResponse, error) {
	out := new(HasAncestorResponse)
	err := c.cc.Invoke(ctx, "/apipb.MaintnerService/HasAncestor", in, out, 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 := c.cc.Invoke(ctx, "/apipb.MaintnerService/GetRef", in, out, 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 := c.cc.Invoke(ctx, "/apipb.MaintnerService/GoFindTryWork", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

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

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

// MaintnerServiceServer is the server API for MaintnerService service.
// All implementations must embed UnimplementedMaintnerServiceServer
// for forward compatibility
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)
	// ListGoReleases lists Go releases sorted by version with latest first.
	//
	// A release is considered to exist for each git tag named "goX", "goX.Y", or
	// "goX.Y.Z", as long as it has a corresponding "release-branch.goX" or
	// "release-branch.goX.Y" release branch.
	//
	// ListGoReleases returns only the latest patch versions of releases which
	// are considered supported per policy. For example, Go 1.12.6 and 1.11.11.
	// The response is guaranteed to have two versions, otherwise an error
	// is returned.
	ListGoReleases(context.Context, *ListGoReleasesRequest) (*ListGoReleasesResponse, error)
	// GetDashboard returns the information for the build.golang.org
	// dashboard. It does not (at least currently)
	// contain any pass/fail information; it only contains information on the branches
	// and commits themselves.
	GetDashboard(context.Context, *DashboardRequest) (*DashboardResponse, error)
	mustEmbedUnimplementedMaintnerServiceServer()
}

// UnimplementedMaintnerServiceServer must be embedded to have forward compatible implementations.
type UnimplementedMaintnerServiceServer struct {
}

func (UnimplementedMaintnerServiceServer) HasAncestor(context.Context, *HasAncestorRequest) (*HasAncestorResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method HasAncestor not implemented")
}
func (UnimplementedMaintnerServiceServer) GetRef(context.Context, *GetRefRequest) (*GetRefResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetRef not implemented")
}
func (UnimplementedMaintnerServiceServer) GoFindTryWork(context.Context, *GoFindTryWorkRequest) (*GoFindTryWorkResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GoFindTryWork not implemented")
}
func (UnimplementedMaintnerServiceServer) ListGoReleases(context.Context, *ListGoReleasesRequest) (*ListGoReleasesResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ListGoReleases not implemented")
}
func (UnimplementedMaintnerServiceServer) GetDashboard(context.Context, *DashboardRequest) (*DashboardResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetDashboard not implemented")
}
func (UnimplementedMaintnerServiceServer) mustEmbedUnimplementedMaintnerServiceServer() {}

// UnsafeMaintnerServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to MaintnerServiceServer will
// result in compilation errors.
type UnsafeMaintnerServiceServer interface {
	mustEmbedUnimplementedMaintnerServiceServer()
}

func RegisterMaintnerServiceServer(s grpc.ServiceRegistrar, 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)
}

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

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

// MaintnerService_ServiceDesc is the grpc.ServiceDesc for MaintnerService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
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,
		},
		{
			MethodName: "ListGoReleases",
			Handler:    _MaintnerService_ListGoReleases_Handler,
		},
		{
			MethodName: "GetDashboard",
			Handler:    _MaintnerService_GetDashboard_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "api.proto",
}
