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

// RemoteTestDriverServiceClient is the client API for RemoteTestDriverService 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 RemoteTestDriverServiceClient interface {
	// Build RTDs (Tauto, Tast, etc.) and put them into a folder containing
	// everything needed to build a Dockerized RTD image. The caller can then do a
	// docker build from inside that directory.
	Assemble(ctx context.Context, in *AssembleRequest, opts ...grpc.CallOption) (*AssembleResponse, error)
}

type remoteTestDriverServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewRemoteTestDriverServiceClient(cc grpc.ClientConnInterface) RemoteTestDriverServiceClient {
	return &remoteTestDriverServiceClient{cc}
}

func (c *remoteTestDriverServiceClient) Assemble(ctx context.Context, in *AssembleRequest, opts ...grpc.CallOption) (*AssembleResponse, error) {
	out := new(AssembleResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.RemoteTestDriverService/Assemble", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// RemoteTestDriverServiceServer is the server API for RemoteTestDriverService service.
// All implementations must embed UnimplementedRemoteTestDriverServiceServer
// for forward compatibility
type RemoteTestDriverServiceServer interface {
	// Build RTDs (Tauto, Tast, etc.) and put them into a folder containing
	// everything needed to build a Dockerized RTD image. The caller can then do a
	// docker build from inside that directory.
	Assemble(context.Context, *AssembleRequest) (*AssembleResponse, error)
	mustEmbedUnimplementedRemoteTestDriverServiceServer()
}

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

func (UnimplementedRemoteTestDriverServiceServer) Assemble(context.Context, *AssembleRequest) (*AssembleResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Assemble not implemented")
}
func (UnimplementedRemoteTestDriverServiceServer) mustEmbedUnimplementedRemoteTestDriverServiceServer() {
}

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

func RegisterRemoteTestDriverServiceServer(s grpc.ServiceRegistrar, srv RemoteTestDriverServiceServer) {
	s.RegisterService(&RemoteTestDriverService_ServiceDesc, srv)
}

func _RemoteTestDriverService_Assemble_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(AssembleRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(RemoteTestDriverServiceServer).Assemble(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.RemoteTestDriverService/Assemble",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(RemoteTestDriverServiceServer).Assemble(ctx, req.(*AssembleRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// RemoteTestDriverService_ServiceDesc is the grpc.ServiceDesc for RemoteTestDriverService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var RemoteTestDriverService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.RemoteTestDriverService",
	HandlerType: (*RemoteTestDriverServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Assemble",
			Handler:    _RemoteTestDriverService_Assemble_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/remote_test_driver.proto",
}
