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

// ImageServiceClient is the client API for ImageService 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 ImageServiceClient interface {
	// Build an image.
	// Example json:
	// {
	//  "build_target": {"name": "reef"},
	// }
	Create(ctx context.Context, in *CreateImageRequest, opts ...grpc.CallOption) (*CreateImageResult, error)
	// Test an image.
	// Example json:
	// {
	//  "build_target": {"name": "reef"},
	//  "image": {"path": "/mnt/host/source/src/build/images/reef/latest"},
	//  "result": {"directory": "/tmp/image_test_results"}
	// }
	Test(ctx context.Context, in *TestImageRequest, opts ...grpc.CallOption) (*TestImageResult, error)
	// Execute SignerTest for an image.  Added in R78.
	// Example json:
	// {
	//  "build_target": {"name": "reef"},
	//  "image": {"path": "/mnt/host/source/src/build/images/reef/latest"},
	//  "result": {"directory": "/tmp/image_test_results"}
	// }
	SignerTest(ctx context.Context, in *TestImageRequest, opts ...grpc.CallOption) (*TestImageResult, error)
	// Execute PushImage for a script.  Added in R89.
	// Example json:
	// {
	//   "dryrun": true,
	//   "gs_image_dir": "gs://chromeos-image-archive/atlas-release/R89-13604.0.0",
	//   "sysroot": {
	//       "build_target": {
	//           "name": "atlas"
	//       }
	//   },
	//   "sign_types": [1, 6]
	// }
	PushImage(ctx context.Context, in *PushImageRequest, opts ...grpc.CallOption) (*PushImageResponse, error)
}

type imageServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewImageServiceClient(cc grpc.ClientConnInterface) ImageServiceClient {
	return &imageServiceClient{cc}
}

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

func (c *imageServiceClient) Test(ctx context.Context, in *TestImageRequest, opts ...grpc.CallOption) (*TestImageResult, error) {
	out := new(TestImageResult)
	err := c.cc.Invoke(ctx, "/chromite.api.ImageService/Test", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *imageServiceClient) SignerTest(ctx context.Context, in *TestImageRequest, opts ...grpc.CallOption) (*TestImageResult, error) {
	out := new(TestImageResult)
	err := c.cc.Invoke(ctx, "/chromite.api.ImageService/SignerTest", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *imageServiceClient) PushImage(ctx context.Context, in *PushImageRequest, opts ...grpc.CallOption) (*PushImageResponse, error) {
	out := new(PushImageResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.ImageService/PushImage", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// ImageServiceServer is the server API for ImageService service.
// All implementations must embed UnimplementedImageServiceServer
// for forward compatibility
type ImageServiceServer interface {
	// Build an image.
	// Example json:
	// {
	//  "build_target": {"name": "reef"},
	// }
	Create(context.Context, *CreateImageRequest) (*CreateImageResult, error)
	// Test an image.
	// Example json:
	// {
	//  "build_target": {"name": "reef"},
	//  "image": {"path": "/mnt/host/source/src/build/images/reef/latest"},
	//  "result": {"directory": "/tmp/image_test_results"}
	// }
	Test(context.Context, *TestImageRequest) (*TestImageResult, error)
	// Execute SignerTest for an image.  Added in R78.
	// Example json:
	// {
	//  "build_target": {"name": "reef"},
	//  "image": {"path": "/mnt/host/source/src/build/images/reef/latest"},
	//  "result": {"directory": "/tmp/image_test_results"}
	// }
	SignerTest(context.Context, *TestImageRequest) (*TestImageResult, error)
	// Execute PushImage for a script.  Added in R89.
	// Example json:
	// {
	//   "dryrun": true,
	//   "gs_image_dir": "gs://chromeos-image-archive/atlas-release/R89-13604.0.0",
	//   "sysroot": {
	//       "build_target": {
	//           "name": "atlas"
	//       }
	//   },
	//   "sign_types": [1, 6]
	// }
	PushImage(context.Context, *PushImageRequest) (*PushImageResponse, error)
	mustEmbedUnimplementedImageServiceServer()
}

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

func (UnimplementedImageServiceServer) Create(context.Context, *CreateImageRequest) (*CreateImageResult, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Create not implemented")
}
func (UnimplementedImageServiceServer) Test(context.Context, *TestImageRequest) (*TestImageResult, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Test not implemented")
}
func (UnimplementedImageServiceServer) SignerTest(context.Context, *TestImageRequest) (*TestImageResult, error) {
	return nil, status.Errorf(codes.Unimplemented, "method SignerTest not implemented")
}
func (UnimplementedImageServiceServer) PushImage(context.Context, *PushImageRequest) (*PushImageResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method PushImage not implemented")
}
func (UnimplementedImageServiceServer) mustEmbedUnimplementedImageServiceServer() {}

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

func RegisterImageServiceServer(s grpc.ServiceRegistrar, srv ImageServiceServer) {
	s.RegisterService(&ImageService_ServiceDesc, srv)
}

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

func _ImageService_Test_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(TestImageRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(ImageServiceServer).Test(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.ImageService/Test",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(ImageServiceServer).Test(ctx, req.(*TestImageRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _ImageService_SignerTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(TestImageRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(ImageServiceServer).SignerTest(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.ImageService/SignerTest",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(ImageServiceServer).SignerTest(ctx, req.(*TestImageRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _ImageService_PushImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(PushImageRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(ImageServiceServer).PushImage(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.ImageService/PushImage",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(ImageServiceServer).PushImage(ctx, req.(*PushImageRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// ImageService_ServiceDesc is the grpc.ServiceDesc for ImageService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var ImageService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.ImageService",
	HandlerType: (*ImageServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Create",
			Handler:    _ImageService_Create_Handler,
		},
		{
			MethodName: "Test",
			Handler:    _ImageService_Test_Handler,
		},
		{
			MethodName: "SignerTest",
			Handler:    _ImageService_SignerTest_Handler,
		},
		{
			MethodName: "PushImage",
			Handler:    _ImageService_PushImage_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/image.proto",
}
