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

package api

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

// PackageServiceClient is the client API for PackageService 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 PackageServiceClient interface {
	// Check if the build target has chrome in its depgraph.  Added in R79.
	BuildsChrome(ctx context.Context, in *BuildsChromeRequest, opts ...grpc.CallOption) (*BuildsChromeResponse, error)
	// Find the best (highest) available version of the requested package.
	// This must be run after the chroot is set up (for chroot package lookup) or
	// after the sysroot is created (for build target package lookup).
	// Added in R79.
	GetBestVisible(ctx context.Context, in *GetBestVisibleRequest, opts ...grpc.CallOption) (*GetBestVisibleResponse, error)
	// Like GetBestVisible, but returns only the chrome version. The chrome
	// package version is something like 78.9.0.123_rc-r1, where the chrome
	// version itself is just 78.9.0.123. This case does not have a spec in
	// Portage, so it cannot be directly fetched by GetBestVisible.
	// Added in R79.
	GetChromeVersion(ctx context.Context, in *GetChromeVersionRequest, opts ...grpc.CallOption) (*GetChromeVersionResponse, error)
	// Return the various build version fields that can be stored (e.g. in
	// metadata.json).  Added in R79.
	GetTargetVersions(ctx context.Context, in *GetTargetVersionsRequest, opts ...grpc.CallOption) (*GetTargetVersionsResponse, error)
	// Return the various metabuilder fields for a release builder.
	// This can be run after InstallPackages. Added in R84.
	GetBuilderMetadata(ctx context.Context, in *GetBuilderMetadataRequest, opts ...grpc.CallOption) (*GetBuilderMetadataResponse, error)
	// Check if there is an available chrome prebuilt for the most recent
	// version of chrome.  Added in R79.
	HasChromePrebuilt(ctx context.Context, in *HasChromePrebuiltRequest, opts ...grpc.CallOption) (*HasChromePrebuiltResponse, error)
	// Check if there is an available prebuilt for the most recent version of the
	// package.  Added in R83.
	HasPrebuilt(ctx context.Context, in *HasPrebuiltRequest, opts ...grpc.CallOption) (*HasPrebuiltResponse, error)
	// Check whether the Chrome source tree is needed.  Does not compile nor
	// install any packages.
	NeedsChromeSource(ctx context.Context, in *NeedsChromeSourceRequest, opts ...grpc.CallOption) (*NeedsChromeSourceResponse, error)
	// The generic uprev process -- performs uprevs for all packages in the
	// public and/or private overlays for the build target(s) specified.
	// This handles all cros_workon packages except those that have a separate
	// uprev process.  Added in R79.
	Uprev(ctx context.Context, in *UprevPackagesRequest, opts ...grpc.CallOption) (*UprevPackagesResponse, error)
	// Uprev a package that is externally versioned (e.g. Chrome).
	// This endpoint iterates over a list of git refs that represent versions
	// and searches for a new version, updating and upreving the package ebuild
	// if such a version is found. The exact behavior depends on the package.
	// Added in R79.
	UprevVersionedPackage(ctx context.Context, in *UprevVersionedPackageRequest, opts ...grpc.CallOption) (*UprevVersionedPackageResponse, error)
}

type packageServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewPackageServiceClient(cc grpc.ClientConnInterface) PackageServiceClient {
	return &packageServiceClient{cc}
}

func (c *packageServiceClient) BuildsChrome(ctx context.Context, in *BuildsChromeRequest, opts ...grpc.CallOption) (*BuildsChromeResponse, error) {
	out := new(BuildsChromeResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PackageService/BuildsChrome", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *packageServiceClient) GetBestVisible(ctx context.Context, in *GetBestVisibleRequest, opts ...grpc.CallOption) (*GetBestVisibleResponse, error) {
	out := new(GetBestVisibleResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PackageService/GetBestVisible", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *packageServiceClient) GetChromeVersion(ctx context.Context, in *GetChromeVersionRequest, opts ...grpc.CallOption) (*GetChromeVersionResponse, error) {
	out := new(GetChromeVersionResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PackageService/GetChromeVersion", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *packageServiceClient) GetTargetVersions(ctx context.Context, in *GetTargetVersionsRequest, opts ...grpc.CallOption) (*GetTargetVersionsResponse, error) {
	out := new(GetTargetVersionsResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PackageService/GetTargetVersions", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *packageServiceClient) GetBuilderMetadata(ctx context.Context, in *GetBuilderMetadataRequest, opts ...grpc.CallOption) (*GetBuilderMetadataResponse, error) {
	out := new(GetBuilderMetadataResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PackageService/GetBuilderMetadata", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *packageServiceClient) HasChromePrebuilt(ctx context.Context, in *HasChromePrebuiltRequest, opts ...grpc.CallOption) (*HasChromePrebuiltResponse, error) {
	out := new(HasChromePrebuiltResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PackageService/HasChromePrebuilt", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *packageServiceClient) HasPrebuilt(ctx context.Context, in *HasPrebuiltRequest, opts ...grpc.CallOption) (*HasPrebuiltResponse, error) {
	out := new(HasPrebuiltResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PackageService/HasPrebuilt", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *packageServiceClient) NeedsChromeSource(ctx context.Context, in *NeedsChromeSourceRequest, opts ...grpc.CallOption) (*NeedsChromeSourceResponse, error) {
	out := new(NeedsChromeSourceResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PackageService/NeedsChromeSource", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *packageServiceClient) Uprev(ctx context.Context, in *UprevPackagesRequest, opts ...grpc.CallOption) (*UprevPackagesResponse, error) {
	out := new(UprevPackagesResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PackageService/Uprev", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *packageServiceClient) UprevVersionedPackage(ctx context.Context, in *UprevVersionedPackageRequest, opts ...grpc.CallOption) (*UprevVersionedPackageResponse, error) {
	out := new(UprevVersionedPackageResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PackageService/UprevVersionedPackage", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// PackageServiceServer is the server API for PackageService service.
// All implementations must embed UnimplementedPackageServiceServer
// for forward compatibility
type PackageServiceServer interface {
	// Check if the build target has chrome in its depgraph.  Added in R79.
	BuildsChrome(context.Context, *BuildsChromeRequest) (*BuildsChromeResponse, error)
	// Find the best (highest) available version of the requested package.
	// This must be run after the chroot is set up (for chroot package lookup) or
	// after the sysroot is created (for build target package lookup).
	// Added in R79.
	GetBestVisible(context.Context, *GetBestVisibleRequest) (*GetBestVisibleResponse, error)
	// Like GetBestVisible, but returns only the chrome version. The chrome
	// package version is something like 78.9.0.123_rc-r1, where the chrome
	// version itself is just 78.9.0.123. This case does not have a spec in
	// Portage, so it cannot be directly fetched by GetBestVisible.
	// Added in R79.
	GetChromeVersion(context.Context, *GetChromeVersionRequest) (*GetChromeVersionResponse, error)
	// Return the various build version fields that can be stored (e.g. in
	// metadata.json).  Added in R79.
	GetTargetVersions(context.Context, *GetTargetVersionsRequest) (*GetTargetVersionsResponse, error)
	// Return the various metabuilder fields for a release builder.
	// This can be run after InstallPackages. Added in R84.
	GetBuilderMetadata(context.Context, *GetBuilderMetadataRequest) (*GetBuilderMetadataResponse, error)
	// Check if there is an available chrome prebuilt for the most recent
	// version of chrome.  Added in R79.
	HasChromePrebuilt(context.Context, *HasChromePrebuiltRequest) (*HasChromePrebuiltResponse, error)
	// Check if there is an available prebuilt for the most recent version of the
	// package.  Added in R83.
	HasPrebuilt(context.Context, *HasPrebuiltRequest) (*HasPrebuiltResponse, error)
	// Check whether the Chrome source tree is needed.  Does not compile nor
	// install any packages.
	NeedsChromeSource(context.Context, *NeedsChromeSourceRequest) (*NeedsChromeSourceResponse, error)
	// The generic uprev process -- performs uprevs for all packages in the
	// public and/or private overlays for the build target(s) specified.
	// This handles all cros_workon packages except those that have a separate
	// uprev process.  Added in R79.
	Uprev(context.Context, *UprevPackagesRequest) (*UprevPackagesResponse, error)
	// Uprev a package that is externally versioned (e.g. Chrome).
	// This endpoint iterates over a list of git refs that represent versions
	// and searches for a new version, updating and upreving the package ebuild
	// if such a version is found. The exact behavior depends on the package.
	// Added in R79.
	UprevVersionedPackage(context.Context, *UprevVersionedPackageRequest) (*UprevVersionedPackageResponse, error)
	mustEmbedUnimplementedPackageServiceServer()
}

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

func (UnimplementedPackageServiceServer) BuildsChrome(context.Context, *BuildsChromeRequest) (*BuildsChromeResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method BuildsChrome not implemented")
}
func (UnimplementedPackageServiceServer) GetBestVisible(context.Context, *GetBestVisibleRequest) (*GetBestVisibleResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetBestVisible not implemented")
}
func (UnimplementedPackageServiceServer) GetChromeVersion(context.Context, *GetChromeVersionRequest) (*GetChromeVersionResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetChromeVersion not implemented")
}
func (UnimplementedPackageServiceServer) GetTargetVersions(context.Context, *GetTargetVersionsRequest) (*GetTargetVersionsResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetTargetVersions not implemented")
}
func (UnimplementedPackageServiceServer) GetBuilderMetadata(context.Context, *GetBuilderMetadataRequest) (*GetBuilderMetadataResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetBuilderMetadata not implemented")
}
func (UnimplementedPackageServiceServer) HasChromePrebuilt(context.Context, *HasChromePrebuiltRequest) (*HasChromePrebuiltResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method HasChromePrebuilt not implemented")
}
func (UnimplementedPackageServiceServer) HasPrebuilt(context.Context, *HasPrebuiltRequest) (*HasPrebuiltResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method HasPrebuilt not implemented")
}
func (UnimplementedPackageServiceServer) NeedsChromeSource(context.Context, *NeedsChromeSourceRequest) (*NeedsChromeSourceResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method NeedsChromeSource not implemented")
}
func (UnimplementedPackageServiceServer) Uprev(context.Context, *UprevPackagesRequest) (*UprevPackagesResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Uprev not implemented")
}
func (UnimplementedPackageServiceServer) UprevVersionedPackage(context.Context, *UprevVersionedPackageRequest) (*UprevVersionedPackageResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method UprevVersionedPackage not implemented")
}
func (UnimplementedPackageServiceServer) mustEmbedUnimplementedPackageServiceServer() {}

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

func RegisterPackageServiceServer(s grpc.ServiceRegistrar, srv PackageServiceServer) {
	s.RegisterService(&PackageService_ServiceDesc, srv)
}

func _PackageService_BuildsChrome_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(BuildsChromeRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PackageServiceServer).BuildsChrome(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PackageService/BuildsChrome",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PackageServiceServer).BuildsChrome(ctx, req.(*BuildsChromeRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _PackageService_GetBestVisible_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetBestVisibleRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PackageServiceServer).GetBestVisible(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PackageService/GetBestVisible",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PackageServiceServer).GetBestVisible(ctx, req.(*GetBestVisibleRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _PackageService_GetChromeVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetChromeVersionRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PackageServiceServer).GetChromeVersion(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PackageService/GetChromeVersion",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PackageServiceServer).GetChromeVersion(ctx, req.(*GetChromeVersionRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _PackageService_GetTargetVersions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetTargetVersionsRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PackageServiceServer).GetTargetVersions(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PackageService/GetTargetVersions",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PackageServiceServer).GetTargetVersions(ctx, req.(*GetTargetVersionsRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _PackageService_GetBuilderMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetBuilderMetadataRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PackageServiceServer).GetBuilderMetadata(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PackageService/GetBuilderMetadata",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PackageServiceServer).GetBuilderMetadata(ctx, req.(*GetBuilderMetadataRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _PackageService_HasChromePrebuilt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(HasChromePrebuiltRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PackageServiceServer).HasChromePrebuilt(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PackageService/HasChromePrebuilt",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PackageServiceServer).HasChromePrebuilt(ctx, req.(*HasChromePrebuiltRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _PackageService_HasPrebuilt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(HasPrebuiltRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PackageServiceServer).HasPrebuilt(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PackageService/HasPrebuilt",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PackageServiceServer).HasPrebuilt(ctx, req.(*HasPrebuiltRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _PackageService_NeedsChromeSource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(NeedsChromeSourceRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PackageServiceServer).NeedsChromeSource(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PackageService/NeedsChromeSource",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PackageServiceServer).NeedsChromeSource(ctx, req.(*NeedsChromeSourceRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _PackageService_Uprev_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(UprevPackagesRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PackageServiceServer).Uprev(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PackageService/Uprev",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PackageServiceServer).Uprev(ctx, req.(*UprevPackagesRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _PackageService_UprevVersionedPackage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(UprevVersionedPackageRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PackageServiceServer).UprevVersionedPackage(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PackageService/UprevVersionedPackage",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PackageServiceServer).UprevVersionedPackage(ctx, req.(*UprevVersionedPackageRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// PackageService_ServiceDesc is the grpc.ServiceDesc for PackageService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var PackageService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.PackageService",
	HandlerType: (*PackageServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "BuildsChrome",
			Handler:    _PackageService_BuildsChrome_Handler,
		},
		{
			MethodName: "GetBestVisible",
			Handler:    _PackageService_GetBestVisible_Handler,
		},
		{
			MethodName: "GetChromeVersion",
			Handler:    _PackageService_GetChromeVersion_Handler,
		},
		{
			MethodName: "GetTargetVersions",
			Handler:    _PackageService_GetTargetVersions_Handler,
		},
		{
			MethodName: "GetBuilderMetadata",
			Handler:    _PackageService_GetBuilderMetadata_Handler,
		},
		{
			MethodName: "HasChromePrebuilt",
			Handler:    _PackageService_HasChromePrebuilt_Handler,
		},
		{
			MethodName: "HasPrebuilt",
			Handler:    _PackageService_HasPrebuilt_Handler,
		},
		{
			MethodName: "NeedsChromeSource",
			Handler:    _PackageService_NeedsChromeSource_Handler,
		},
		{
			MethodName: "Uprev",
			Handler:    _PackageService_Uprev_Handler,
		},
		{
			MethodName: "UprevVersionedPackage",
			Handler:    _PackageService_UprevVersionedPackage_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/packages.proto",
}
