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

// SysrootServiceClient is the client API for SysrootService 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 SysrootServiceClient interface {
	// Create the base sysroot structure.
	Create(ctx context.Context, in *SysrootCreateRequest, opts ...grpc.CallOption) (*SysrootCreateResponse, error)
	// Generate sysroot archive.  Added in R83.
	GenerateArchive(ctx context.Context, in *SysrootGenerateArchiveRequest, opts ...grpc.CallOption) (*SysrootGenerateArchiveResponse, error)
	// Install the toolchain into the sysroot.
	InstallToolchain(ctx context.Context, in *InstallToolchainRequest, opts ...grpc.CallOption) (*InstallToolchainResponse, error)
	// Install packages into the sysroot. By default will install all packages.
	InstallPackages(ctx context.Context, in *InstallPackagesRequest, opts ...grpc.CallOption) (*InstallPackagesResponse, error)
	// Install SimpleChrome sysroot.  Added in R79.
	CreateSimpleChromeSysroot(ctx context.Context, in *CreateSimpleChromeSysrootRequest, opts ...grpc.CallOption) (*CreateSimpleChromeSysrootResponse, error)
}

type sysrootServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewSysrootServiceClient(cc grpc.ClientConnInterface) SysrootServiceClient {
	return &sysrootServiceClient{cc}
}

func (c *sysrootServiceClient) Create(ctx context.Context, in *SysrootCreateRequest, opts ...grpc.CallOption) (*SysrootCreateResponse, error) {
	out := new(SysrootCreateResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SysrootService/Create", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *sysrootServiceClient) GenerateArchive(ctx context.Context, in *SysrootGenerateArchiveRequest, opts ...grpc.CallOption) (*SysrootGenerateArchiveResponse, error) {
	out := new(SysrootGenerateArchiveResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SysrootService/GenerateArchive", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *sysrootServiceClient) InstallToolchain(ctx context.Context, in *InstallToolchainRequest, opts ...grpc.CallOption) (*InstallToolchainResponse, error) {
	out := new(InstallToolchainResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SysrootService/InstallToolchain", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *sysrootServiceClient) InstallPackages(ctx context.Context, in *InstallPackagesRequest, opts ...grpc.CallOption) (*InstallPackagesResponse, error) {
	out := new(InstallPackagesResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SysrootService/InstallPackages", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *sysrootServiceClient) CreateSimpleChromeSysroot(ctx context.Context, in *CreateSimpleChromeSysrootRequest, opts ...grpc.CallOption) (*CreateSimpleChromeSysrootResponse, error) {
	out := new(CreateSimpleChromeSysrootResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SysrootService/CreateSimpleChromeSysroot", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// SysrootServiceServer is the server API for SysrootService service.
// All implementations must embed UnimplementedSysrootServiceServer
// for forward compatibility
type SysrootServiceServer interface {
	// Create the base sysroot structure.
	Create(context.Context, *SysrootCreateRequest) (*SysrootCreateResponse, error)
	// Generate sysroot archive.  Added in R83.
	GenerateArchive(context.Context, *SysrootGenerateArchiveRequest) (*SysrootGenerateArchiveResponse, error)
	// Install the toolchain into the sysroot.
	InstallToolchain(context.Context, *InstallToolchainRequest) (*InstallToolchainResponse, error)
	// Install packages into the sysroot. By default will install all packages.
	InstallPackages(context.Context, *InstallPackagesRequest) (*InstallPackagesResponse, error)
	// Install SimpleChrome sysroot.  Added in R79.
	CreateSimpleChromeSysroot(context.Context, *CreateSimpleChromeSysrootRequest) (*CreateSimpleChromeSysrootResponse, error)
	mustEmbedUnimplementedSysrootServiceServer()
}

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

func (UnimplementedSysrootServiceServer) Create(context.Context, *SysrootCreateRequest) (*SysrootCreateResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Create not implemented")
}
func (UnimplementedSysrootServiceServer) GenerateArchive(context.Context, *SysrootGenerateArchiveRequest) (*SysrootGenerateArchiveResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GenerateArchive not implemented")
}
func (UnimplementedSysrootServiceServer) InstallToolchain(context.Context, *InstallToolchainRequest) (*InstallToolchainResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method InstallToolchain not implemented")
}
func (UnimplementedSysrootServiceServer) InstallPackages(context.Context, *InstallPackagesRequest) (*InstallPackagesResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method InstallPackages not implemented")
}
func (UnimplementedSysrootServiceServer) CreateSimpleChromeSysroot(context.Context, *CreateSimpleChromeSysrootRequest) (*CreateSimpleChromeSysrootResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method CreateSimpleChromeSysroot not implemented")
}
func (UnimplementedSysrootServiceServer) mustEmbedUnimplementedSysrootServiceServer() {}

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

func RegisterSysrootServiceServer(s grpc.ServiceRegistrar, srv SysrootServiceServer) {
	s.RegisterService(&SysrootService_ServiceDesc, srv)
}

func _SysrootService_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SysrootCreateRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SysrootServiceServer).Create(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SysrootService/Create",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SysrootServiceServer).Create(ctx, req.(*SysrootCreateRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _SysrootService_GenerateArchive_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SysrootGenerateArchiveRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SysrootServiceServer).GenerateArchive(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SysrootService/GenerateArchive",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SysrootServiceServer).GenerateArchive(ctx, req.(*SysrootGenerateArchiveRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _SysrootService_InstallToolchain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(InstallToolchainRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SysrootServiceServer).InstallToolchain(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SysrootService/InstallToolchain",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SysrootServiceServer).InstallToolchain(ctx, req.(*InstallToolchainRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _SysrootService_InstallPackages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(InstallPackagesRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SysrootServiceServer).InstallPackages(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SysrootService/InstallPackages",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SysrootServiceServer).InstallPackages(ctx, req.(*InstallPackagesRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _SysrootService_CreateSimpleChromeSysroot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(CreateSimpleChromeSysrootRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SysrootServiceServer).CreateSimpleChromeSysroot(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SysrootService/CreateSimpleChromeSysroot",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SysrootServiceServer).CreateSimpleChromeSysroot(ctx, req.(*CreateSimpleChromeSysrootRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// SysrootService_ServiceDesc is the grpc.ServiceDesc for SysrootService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var SysrootService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.SysrootService",
	HandlerType: (*SysrootServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Create",
			Handler:    _SysrootService_Create_Handler,
		},
		{
			MethodName: "GenerateArchive",
			Handler:    _SysrootService_GenerateArchive_Handler,
		},
		{
			MethodName: "InstallToolchain",
			Handler:    _SysrootService_InstallToolchain_Handler,
		},
		{
			MethodName: "InstallPackages",
			Handler:    _SysrootService_InstallPackages_Handler,
		},
		{
			MethodName: "CreateSimpleChromeSysroot",
			Handler:    _SysrootService_CreateSimpleChromeSysroot_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/sysroot.proto",
}
