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

// SdkServiceClient is the client API for SdkService 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 SdkServiceClient interface {
	// Create method, supports replacing an existing chroot.
	Create(ctx context.Context, in *CreateRequest, opts ...grpc.CallOption) (*CreateResponse, error)
	// Delete a chroot. Added in R79.
	Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error)
	// Clean up unneeded files from the chroot. Added in R81.
	Clean(ctx context.Context, in *CleanRequest, opts ...grpc.CallOption) (*CleanResponse, error)
	// Unmount a chroot. Added in R81.
	Unmount(ctx context.Context, in *UnmountRequest, opts ...grpc.CallOption) (*UnmountResponse, error)
	// Update the chroot.
	Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*UpdateResponse, error)
	// Create a chroot snapshot. Added in R83.
	CreateSnapshot(ctx context.Context, in *CreateSnapshotRequest, opts ...grpc.CallOption) (*CreateSnapshotResponse, error)
	// Restore a chroot to a snapshot. Added in R83.
	RestoreSnapshot(ctx context.Context, in *RestoreSnapshotRequest, opts ...grpc.CallOption) (*RestoreSnapshotResponse, error)
	// Unmount a filesystem path and any submounts under it.  Added in R86.
	UnmountPath(ctx context.Context, in *UnmountPathRequest, opts ...grpc.CallOption) (*UnmountPathResponse, error)
}

type sdkServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewSdkServiceClient(cc grpc.ClientConnInterface) SdkServiceClient {
	return &sdkServiceClient{cc}
}

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

func (c *sdkServiceClient) Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error) {
	out := new(DeleteResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SdkService/Delete", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *sdkServiceClient) Clean(ctx context.Context, in *CleanRequest, opts ...grpc.CallOption) (*CleanResponse, error) {
	out := new(CleanResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SdkService/Clean", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *sdkServiceClient) Unmount(ctx context.Context, in *UnmountRequest, opts ...grpc.CallOption) (*UnmountResponse, error) {
	out := new(UnmountResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SdkService/Unmount", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *sdkServiceClient) Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*UpdateResponse, error) {
	out := new(UpdateResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SdkService/Update", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *sdkServiceClient) CreateSnapshot(ctx context.Context, in *CreateSnapshotRequest, opts ...grpc.CallOption) (*CreateSnapshotResponse, error) {
	out := new(CreateSnapshotResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SdkService/CreateSnapshot", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *sdkServiceClient) RestoreSnapshot(ctx context.Context, in *RestoreSnapshotRequest, opts ...grpc.CallOption) (*RestoreSnapshotResponse, error) {
	out := new(RestoreSnapshotResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SdkService/RestoreSnapshot", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *sdkServiceClient) UnmountPath(ctx context.Context, in *UnmountPathRequest, opts ...grpc.CallOption) (*UnmountPathResponse, error) {
	out := new(UnmountPathResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.SdkService/UnmountPath", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// SdkServiceServer is the server API for SdkService service.
// All implementations must embed UnimplementedSdkServiceServer
// for forward compatibility
type SdkServiceServer interface {
	// Create method, supports replacing an existing chroot.
	Create(context.Context, *CreateRequest) (*CreateResponse, error)
	// Delete a chroot. Added in R79.
	Delete(context.Context, *DeleteRequest) (*DeleteResponse, error)
	// Clean up unneeded files from the chroot. Added in R81.
	Clean(context.Context, *CleanRequest) (*CleanResponse, error)
	// Unmount a chroot. Added in R81.
	Unmount(context.Context, *UnmountRequest) (*UnmountResponse, error)
	// Update the chroot.
	Update(context.Context, *UpdateRequest) (*UpdateResponse, error)
	// Create a chroot snapshot. Added in R83.
	CreateSnapshot(context.Context, *CreateSnapshotRequest) (*CreateSnapshotResponse, error)
	// Restore a chroot to a snapshot. Added in R83.
	RestoreSnapshot(context.Context, *RestoreSnapshotRequest) (*RestoreSnapshotResponse, error)
	// Unmount a filesystem path and any submounts under it.  Added in R86.
	UnmountPath(context.Context, *UnmountPathRequest) (*UnmountPathResponse, error)
	mustEmbedUnimplementedSdkServiceServer()
}

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

func (UnimplementedSdkServiceServer) Create(context.Context, *CreateRequest) (*CreateResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Create not implemented")
}
func (UnimplementedSdkServiceServer) Delete(context.Context, *DeleteRequest) (*DeleteResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented")
}
func (UnimplementedSdkServiceServer) Clean(context.Context, *CleanRequest) (*CleanResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Clean not implemented")
}
func (UnimplementedSdkServiceServer) Unmount(context.Context, *UnmountRequest) (*UnmountResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Unmount not implemented")
}
func (UnimplementedSdkServiceServer) Update(context.Context, *UpdateRequest) (*UpdateResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Update not implemented")
}
func (UnimplementedSdkServiceServer) CreateSnapshot(context.Context, *CreateSnapshotRequest) (*CreateSnapshotResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method CreateSnapshot not implemented")
}
func (UnimplementedSdkServiceServer) RestoreSnapshot(context.Context, *RestoreSnapshotRequest) (*RestoreSnapshotResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method RestoreSnapshot not implemented")
}
func (UnimplementedSdkServiceServer) UnmountPath(context.Context, *UnmountPathRequest) (*UnmountPathResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method UnmountPath not implemented")
}
func (UnimplementedSdkServiceServer) mustEmbedUnimplementedSdkServiceServer() {}

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

func RegisterSdkServiceServer(s grpc.ServiceRegistrar, srv SdkServiceServer) {
	s.RegisterService(&SdkService_ServiceDesc, srv)
}

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

func _SdkService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(DeleteRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SdkServiceServer).Delete(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SdkService/Delete",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SdkServiceServer).Delete(ctx, req.(*DeleteRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _SdkService_Clean_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(CleanRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SdkServiceServer).Clean(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SdkService/Clean",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SdkServiceServer).Clean(ctx, req.(*CleanRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _SdkService_Unmount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(UnmountRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SdkServiceServer).Unmount(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SdkService/Unmount",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SdkServiceServer).Unmount(ctx, req.(*UnmountRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _SdkService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(UpdateRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SdkServiceServer).Update(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SdkService/Update",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SdkServiceServer).Update(ctx, req.(*UpdateRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _SdkService_CreateSnapshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(CreateSnapshotRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SdkServiceServer).CreateSnapshot(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SdkService/CreateSnapshot",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SdkServiceServer).CreateSnapshot(ctx, req.(*CreateSnapshotRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _SdkService_RestoreSnapshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(RestoreSnapshotRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SdkServiceServer).RestoreSnapshot(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SdkService/RestoreSnapshot",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SdkServiceServer).RestoreSnapshot(ctx, req.(*RestoreSnapshotRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _SdkService_UnmountPath_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(UnmountPathRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(SdkServiceServer).UnmountPath(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.SdkService/UnmountPath",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(SdkServiceServer).UnmountPath(ctx, req.(*UnmountPathRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// SdkService_ServiceDesc is the grpc.ServiceDesc for SdkService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var SdkService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.SdkService",
	HandlerType: (*SdkServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Create",
			Handler:    _SdkService_Create_Handler,
		},
		{
			MethodName: "Delete",
			Handler:    _SdkService_Delete_Handler,
		},
		{
			MethodName: "Clean",
			Handler:    _SdkService_Clean_Handler,
		},
		{
			MethodName: "Unmount",
			Handler:    _SdkService_Unmount_Handler,
		},
		{
			MethodName: "Update",
			Handler:    _SdkService_Update_Handler,
		},
		{
			MethodName: "CreateSnapshot",
			Handler:    _SdkService_CreateSnapshot_Handler,
		},
		{
			MethodName: "RestoreSnapshot",
			Handler:    _SdkService_RestoreSnapshot_Handler,
		},
		{
			MethodName: "UnmountPath",
			Handler:    _SdkService_UnmountPath_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/sdk.proto",
}
