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

// FirmwareServiceClient is the client API for FirmwareService 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 FirmwareServiceClient interface {
	// TODO(b/177907747): Drop this once the migration is complete.
	// Builds all of the firmware targets on ToT at specified location.
	BuildAllTotFirmware(ctx context.Context, in *BuildAllTotFirmwareRequest, opts ...grpc.CallOption) (*BuildAllTotFirmwareResponse, error)
	// TODO(b/177907747): Drop this once the migration is complete.
	// Runs all of the firmware tests on ToT at specified location.
	TestAllTotFirmware(ctx context.Context, in *TestAllTotFirmwareRequest, opts ...grpc.CallOption) (*TestAllTotFirmwareResponse, error)
	// Builds all of the firmware targets at specified location. Added in R90.
	BuildAllFirmware(ctx context.Context, in *BuildAllFirmwareRequest, opts ...grpc.CallOption) (*BuildAllFirmwareResponse, error)
	// Runs all of the firmware tests at specified location. Added in R90.
	TestAllFirmware(ctx context.Context, in *TestAllFirmwareRequest, opts ...grpc.CallOption) (*TestAllFirmwareResponse, error)
	// Bundles any firmware images and other artifacts. Added in R90.
	BundleFirmwareArtifacts(ctx context.Context, in *BundleFirmwareArtifactsRequest, opts ...grpc.CallOption) (*BundleFirmwareArtifactsResponse, error)
}

type firmwareServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewFirmwareServiceClient(cc grpc.ClientConnInterface) FirmwareServiceClient {
	return &firmwareServiceClient{cc}
}

func (c *firmwareServiceClient) BuildAllTotFirmware(ctx context.Context, in *BuildAllTotFirmwareRequest, opts ...grpc.CallOption) (*BuildAllTotFirmwareResponse, error) {
	out := new(BuildAllTotFirmwareResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.FirmwareService/BuildAllTotFirmware", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *firmwareServiceClient) TestAllTotFirmware(ctx context.Context, in *TestAllTotFirmwareRequest, opts ...grpc.CallOption) (*TestAllTotFirmwareResponse, error) {
	out := new(TestAllTotFirmwareResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.FirmwareService/TestAllTotFirmware", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *firmwareServiceClient) BuildAllFirmware(ctx context.Context, in *BuildAllFirmwareRequest, opts ...grpc.CallOption) (*BuildAllFirmwareResponse, error) {
	out := new(BuildAllFirmwareResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.FirmwareService/BuildAllFirmware", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *firmwareServiceClient) TestAllFirmware(ctx context.Context, in *TestAllFirmwareRequest, opts ...grpc.CallOption) (*TestAllFirmwareResponse, error) {
	out := new(TestAllFirmwareResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.FirmwareService/TestAllFirmware", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *firmwareServiceClient) BundleFirmwareArtifacts(ctx context.Context, in *BundleFirmwareArtifactsRequest, opts ...grpc.CallOption) (*BundleFirmwareArtifactsResponse, error) {
	out := new(BundleFirmwareArtifactsResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.FirmwareService/BundleFirmwareArtifacts", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// FirmwareServiceServer is the server API for FirmwareService service.
// All implementations must embed UnimplementedFirmwareServiceServer
// for forward compatibility
type FirmwareServiceServer interface {
	// TODO(b/177907747): Drop this once the migration is complete.
	// Builds all of the firmware targets on ToT at specified location.
	BuildAllTotFirmware(context.Context, *BuildAllTotFirmwareRequest) (*BuildAllTotFirmwareResponse, error)
	// TODO(b/177907747): Drop this once the migration is complete.
	// Runs all of the firmware tests on ToT at specified location.
	TestAllTotFirmware(context.Context, *TestAllTotFirmwareRequest) (*TestAllTotFirmwareResponse, error)
	// Builds all of the firmware targets at specified location. Added in R90.
	BuildAllFirmware(context.Context, *BuildAllFirmwareRequest) (*BuildAllFirmwareResponse, error)
	// Runs all of the firmware tests at specified location. Added in R90.
	TestAllFirmware(context.Context, *TestAllFirmwareRequest) (*TestAllFirmwareResponse, error)
	// Bundles any firmware images and other artifacts. Added in R90.
	BundleFirmwareArtifacts(context.Context, *BundleFirmwareArtifactsRequest) (*BundleFirmwareArtifactsResponse, error)
	mustEmbedUnimplementedFirmwareServiceServer()
}

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

func (UnimplementedFirmwareServiceServer) BuildAllTotFirmware(context.Context, *BuildAllTotFirmwareRequest) (*BuildAllTotFirmwareResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method BuildAllTotFirmware not implemented")
}
func (UnimplementedFirmwareServiceServer) TestAllTotFirmware(context.Context, *TestAllTotFirmwareRequest) (*TestAllTotFirmwareResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method TestAllTotFirmware not implemented")
}
func (UnimplementedFirmwareServiceServer) BuildAllFirmware(context.Context, *BuildAllFirmwareRequest) (*BuildAllFirmwareResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method BuildAllFirmware not implemented")
}
func (UnimplementedFirmwareServiceServer) TestAllFirmware(context.Context, *TestAllFirmwareRequest) (*TestAllFirmwareResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method TestAllFirmware not implemented")
}
func (UnimplementedFirmwareServiceServer) BundleFirmwareArtifacts(context.Context, *BundleFirmwareArtifactsRequest) (*BundleFirmwareArtifactsResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method BundleFirmwareArtifacts not implemented")
}
func (UnimplementedFirmwareServiceServer) mustEmbedUnimplementedFirmwareServiceServer() {}

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

func RegisterFirmwareServiceServer(s grpc.ServiceRegistrar, srv FirmwareServiceServer) {
	s.RegisterService(&FirmwareService_ServiceDesc, srv)
}

func _FirmwareService_BuildAllTotFirmware_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(BuildAllTotFirmwareRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(FirmwareServiceServer).BuildAllTotFirmware(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.FirmwareService/BuildAllTotFirmware",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(FirmwareServiceServer).BuildAllTotFirmware(ctx, req.(*BuildAllTotFirmwareRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _FirmwareService_TestAllTotFirmware_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(TestAllTotFirmwareRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(FirmwareServiceServer).TestAllTotFirmware(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.FirmwareService/TestAllTotFirmware",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(FirmwareServiceServer).TestAllTotFirmware(ctx, req.(*TestAllTotFirmwareRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _FirmwareService_BuildAllFirmware_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(BuildAllFirmwareRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(FirmwareServiceServer).BuildAllFirmware(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.FirmwareService/BuildAllFirmware",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(FirmwareServiceServer).BuildAllFirmware(ctx, req.(*BuildAllFirmwareRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _FirmwareService_TestAllFirmware_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(TestAllFirmwareRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(FirmwareServiceServer).TestAllFirmware(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.FirmwareService/TestAllFirmware",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(FirmwareServiceServer).TestAllFirmware(ctx, req.(*TestAllFirmwareRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _FirmwareService_BundleFirmwareArtifacts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(BundleFirmwareArtifactsRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(FirmwareServiceServer).BundleFirmwareArtifacts(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.FirmwareService/BundleFirmwareArtifacts",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(FirmwareServiceServer).BundleFirmwareArtifacts(ctx, req.(*BundleFirmwareArtifactsRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// FirmwareService_ServiceDesc is the grpc.ServiceDesc for FirmwareService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var FirmwareService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.FirmwareService",
	HandlerType: (*FirmwareServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "BuildAllTotFirmware",
			Handler:    _FirmwareService_BuildAllTotFirmware_Handler,
		},
		{
			MethodName: "TestAllTotFirmware",
			Handler:    _FirmwareService_TestAllTotFirmware_Handler,
		},
		{
			MethodName: "BuildAllFirmware",
			Handler:    _FirmwareService_BuildAllFirmware_Handler,
		},
		{
			MethodName: "TestAllFirmware",
			Handler:    _FirmwareService_TestAllFirmware_Handler,
		},
		{
			MethodName: "BundleFirmwareArtifacts",
			Handler:    _FirmwareService_BundleFirmwareArtifacts_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/firmware.proto",
}
