// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc             v4.23.4
// source: gomote.proto

package protos

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

// GomoteServiceClient is the client API for GomoteService 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 GomoteServiceClient interface {
	// Authenticate provides authentication information without any additional action.
	Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateResponse, error)
	// AddBootstrap adds the bootstrap version of Go to the work directory.
	AddBootstrap(ctx context.Context, in *AddBootstrapRequest, opts ...grpc.CallOption) (*AddBootstrapResponse, error)
	// CreateInstance creates a gomote instance.
	CreateInstance(ctx context.Context, in *CreateInstanceRequest, opts ...grpc.CallOption) (GomoteService_CreateInstanceClient, error)
	// DestroyInstance destroys a gomote instance.
	DestroyInstance(ctx context.Context, in *DestroyInstanceRequest, opts ...grpc.CallOption) (*DestroyInstanceResponse, error)
	// ExecuteCommand executes a command on the gomote instance.
	ExecuteCommand(ctx context.Context, in *ExecuteCommandRequest, opts ...grpc.CallOption) (GomoteService_ExecuteCommandClient, error)
	// InstanceAlive gives the liveness state of a gomote instance.
	InstanceAlive(ctx context.Context, in *InstanceAliveRequest, opts ...grpc.CallOption) (*InstanceAliveResponse, error)
	// ListDirectory lists the contents of a directory on an gomote instance.
	ListDirectory(ctx context.Context, in *ListDirectoryRequest, opts ...grpc.CallOption) (*ListDirectoryResponse, error)
	// ListInstances lists all of the live gomote instances owned by the caller.
	ListInstances(ctx context.Context, in *ListInstancesRequest, opts ...grpc.CallOption) (*ListInstancesResponse, error)
	// ListSwarmingBuilders lists all of the swarming builders for the project.
	ListSwarmingBuilders(ctx context.Context, in *ListSwarmingBuildersRequest, opts ...grpc.CallOption) (*ListSwarmingBuildersResponse, error)
	// ReadTGZToURL tars and zips a directory which exists on the gomote instance and returns a URL where it can be
	// downloaded from.
	ReadTGZToURL(ctx context.Context, in *ReadTGZToURLRequest, opts ...grpc.CallOption) (*ReadTGZToURLResponse, error)
	// RemoveFiles removes files or directories from the gomote instance.
	RemoveFiles(ctx context.Context, in *RemoveFilesRequest, opts ...grpc.CallOption) (*RemoveFilesResponse, error)
	// SignSSHKey signs an SSH public key which can be used to SSH into instances owned by the caller.
	SignSSHKey(ctx context.Context, in *SignSSHKeyRequest, opts ...grpc.CallOption) (*SignSSHKeyResponse, error)
	// UploadFile generates a signed URL and associated fields to be used when uploading the object to GCS. Once uploaded
	// the corresponding Write endpoint can be used to send the file to the gomote instance.
	UploadFile(ctx context.Context, in *UploadFileRequest, opts ...grpc.CallOption) (*UploadFileResponse, error)
	// WriteFileFromURL
	WriteFileFromURL(ctx context.Context, in *WriteFileFromURLRequest, opts ...grpc.CallOption) (*WriteFileFromURLResponse, error)
	// WriteTGZFromURL retrieves a tar and zipped file from a URL and expands it onto the file system of a gomote instance.
	WriteTGZFromURL(ctx context.Context, in *WriteTGZFromURLRequest, opts ...grpc.CallOption) (*WriteTGZFromURLResponse, error)
}

type gomoteServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewGomoteServiceClient(cc grpc.ClientConnInterface) GomoteServiceClient {
	return &gomoteServiceClient{cc}
}

func (c *gomoteServiceClient) Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateResponse, error) {
	out := new(AuthenticateResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/Authenticate", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) AddBootstrap(ctx context.Context, in *AddBootstrapRequest, opts ...grpc.CallOption) (*AddBootstrapResponse, error) {
	out := new(AddBootstrapResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/AddBootstrap", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) CreateInstance(ctx context.Context, in *CreateInstanceRequest, opts ...grpc.CallOption) (GomoteService_CreateInstanceClient, error) {
	stream, err := c.cc.NewStream(ctx, &GomoteService_ServiceDesc.Streams[0], "/protos.GomoteService/CreateInstance", opts...)
	if err != nil {
		return nil, err
	}
	x := &gomoteServiceCreateInstanceClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type GomoteService_CreateInstanceClient interface {
	Recv() (*CreateInstanceResponse, error)
	grpc.ClientStream
}

type gomoteServiceCreateInstanceClient struct {
	grpc.ClientStream
}

func (x *gomoteServiceCreateInstanceClient) Recv() (*CreateInstanceResponse, error) {
	m := new(CreateInstanceResponse)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

func (c *gomoteServiceClient) DestroyInstance(ctx context.Context, in *DestroyInstanceRequest, opts ...grpc.CallOption) (*DestroyInstanceResponse, error) {
	out := new(DestroyInstanceResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/DestroyInstance", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) ExecuteCommand(ctx context.Context, in *ExecuteCommandRequest, opts ...grpc.CallOption) (GomoteService_ExecuteCommandClient, error) {
	stream, err := c.cc.NewStream(ctx, &GomoteService_ServiceDesc.Streams[1], "/protos.GomoteService/ExecuteCommand", opts...)
	if err != nil {
		return nil, err
	}
	x := &gomoteServiceExecuteCommandClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type GomoteService_ExecuteCommandClient interface {
	Recv() (*ExecuteCommandResponse, error)
	grpc.ClientStream
}

type gomoteServiceExecuteCommandClient struct {
	grpc.ClientStream
}

func (x *gomoteServiceExecuteCommandClient) Recv() (*ExecuteCommandResponse, error) {
	m := new(ExecuteCommandResponse)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

func (c *gomoteServiceClient) InstanceAlive(ctx context.Context, in *InstanceAliveRequest, opts ...grpc.CallOption) (*InstanceAliveResponse, error) {
	out := new(InstanceAliveResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/InstanceAlive", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) ListDirectory(ctx context.Context, in *ListDirectoryRequest, opts ...grpc.CallOption) (*ListDirectoryResponse, error) {
	out := new(ListDirectoryResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/ListDirectory", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) ListInstances(ctx context.Context, in *ListInstancesRequest, opts ...grpc.CallOption) (*ListInstancesResponse, error) {
	out := new(ListInstancesResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/ListInstances", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) ListSwarmingBuilders(ctx context.Context, in *ListSwarmingBuildersRequest, opts ...grpc.CallOption) (*ListSwarmingBuildersResponse, error) {
	out := new(ListSwarmingBuildersResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/ListSwarmingBuilders", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) ReadTGZToURL(ctx context.Context, in *ReadTGZToURLRequest, opts ...grpc.CallOption) (*ReadTGZToURLResponse, error) {
	out := new(ReadTGZToURLResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/ReadTGZToURL", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) RemoveFiles(ctx context.Context, in *RemoveFilesRequest, opts ...grpc.CallOption) (*RemoveFilesResponse, error) {
	out := new(RemoveFilesResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/RemoveFiles", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) SignSSHKey(ctx context.Context, in *SignSSHKeyRequest, opts ...grpc.CallOption) (*SignSSHKeyResponse, error) {
	out := new(SignSSHKeyResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/SignSSHKey", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) UploadFile(ctx context.Context, in *UploadFileRequest, opts ...grpc.CallOption) (*UploadFileResponse, error) {
	out := new(UploadFileResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/UploadFile", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) WriteFileFromURL(ctx context.Context, in *WriteFileFromURLRequest, opts ...grpc.CallOption) (*WriteFileFromURLResponse, error) {
	out := new(WriteFileFromURLResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/WriteFileFromURL", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *gomoteServiceClient) WriteTGZFromURL(ctx context.Context, in *WriteTGZFromURLRequest, opts ...grpc.CallOption) (*WriteTGZFromURLResponse, error) {
	out := new(WriteTGZFromURLResponse)
	err := c.cc.Invoke(ctx, "/protos.GomoteService/WriteTGZFromURL", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// GomoteServiceServer is the server API for GomoteService service.
// All implementations must embed UnimplementedGomoteServiceServer
// for forward compatibility
type GomoteServiceServer interface {
	// Authenticate provides authentication information without any additional action.
	Authenticate(context.Context, *AuthenticateRequest) (*AuthenticateResponse, error)
	// AddBootstrap adds the bootstrap version of Go to the work directory.
	AddBootstrap(context.Context, *AddBootstrapRequest) (*AddBootstrapResponse, error)
	// CreateInstance creates a gomote instance.
	CreateInstance(*CreateInstanceRequest, GomoteService_CreateInstanceServer) error
	// DestroyInstance destroys a gomote instance.
	DestroyInstance(context.Context, *DestroyInstanceRequest) (*DestroyInstanceResponse, error)
	// ExecuteCommand executes a command on the gomote instance.
	ExecuteCommand(*ExecuteCommandRequest, GomoteService_ExecuteCommandServer) error
	// InstanceAlive gives the liveness state of a gomote instance.
	InstanceAlive(context.Context, *InstanceAliveRequest) (*InstanceAliveResponse, error)
	// ListDirectory lists the contents of a directory on an gomote instance.
	ListDirectory(context.Context, *ListDirectoryRequest) (*ListDirectoryResponse, error)
	// ListInstances lists all of the live gomote instances owned by the caller.
	ListInstances(context.Context, *ListInstancesRequest) (*ListInstancesResponse, error)
	// ListSwarmingBuilders lists all of the swarming builders for the project.
	ListSwarmingBuilders(context.Context, *ListSwarmingBuildersRequest) (*ListSwarmingBuildersResponse, error)
	// ReadTGZToURL tars and zips a directory which exists on the gomote instance and returns a URL where it can be
	// downloaded from.
	ReadTGZToURL(context.Context, *ReadTGZToURLRequest) (*ReadTGZToURLResponse, error)
	// RemoveFiles removes files or directories from the gomote instance.
	RemoveFiles(context.Context, *RemoveFilesRequest) (*RemoveFilesResponse, error)
	// SignSSHKey signs an SSH public key which can be used to SSH into instances owned by the caller.
	SignSSHKey(context.Context, *SignSSHKeyRequest) (*SignSSHKeyResponse, error)
	// UploadFile generates a signed URL and associated fields to be used when uploading the object to GCS. Once uploaded
	// the corresponding Write endpoint can be used to send the file to the gomote instance.
	UploadFile(context.Context, *UploadFileRequest) (*UploadFileResponse, error)
	// WriteFileFromURL
	WriteFileFromURL(context.Context, *WriteFileFromURLRequest) (*WriteFileFromURLResponse, error)
	// WriteTGZFromURL retrieves a tar and zipped file from a URL and expands it onto the file system of a gomote instance.
	WriteTGZFromURL(context.Context, *WriteTGZFromURLRequest) (*WriteTGZFromURLResponse, error)
	mustEmbedUnimplementedGomoteServiceServer()
}

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

func (UnimplementedGomoteServiceServer) Authenticate(context.Context, *AuthenticateRequest) (*AuthenticateResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Authenticate not implemented")
}
func (UnimplementedGomoteServiceServer) AddBootstrap(context.Context, *AddBootstrapRequest) (*AddBootstrapResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method AddBootstrap not implemented")
}
func (UnimplementedGomoteServiceServer) CreateInstance(*CreateInstanceRequest, GomoteService_CreateInstanceServer) error {
	return status.Errorf(codes.Unimplemented, "method CreateInstance not implemented")
}
func (UnimplementedGomoteServiceServer) DestroyInstance(context.Context, *DestroyInstanceRequest) (*DestroyInstanceResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method DestroyInstance not implemented")
}
func (UnimplementedGomoteServiceServer) ExecuteCommand(*ExecuteCommandRequest, GomoteService_ExecuteCommandServer) error {
	return status.Errorf(codes.Unimplemented, "method ExecuteCommand not implemented")
}
func (UnimplementedGomoteServiceServer) InstanceAlive(context.Context, *InstanceAliveRequest) (*InstanceAliveResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method InstanceAlive not implemented")
}
func (UnimplementedGomoteServiceServer) ListDirectory(context.Context, *ListDirectoryRequest) (*ListDirectoryResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ListDirectory not implemented")
}
func (UnimplementedGomoteServiceServer) ListInstances(context.Context, *ListInstancesRequest) (*ListInstancesResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ListInstances not implemented")
}
func (UnimplementedGomoteServiceServer) ListSwarmingBuilders(context.Context, *ListSwarmingBuildersRequest) (*ListSwarmingBuildersResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ListSwarmingBuilders not implemented")
}
func (UnimplementedGomoteServiceServer) ReadTGZToURL(context.Context, *ReadTGZToURLRequest) (*ReadTGZToURLResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ReadTGZToURL not implemented")
}
func (UnimplementedGomoteServiceServer) RemoveFiles(context.Context, *RemoveFilesRequest) (*RemoveFilesResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method RemoveFiles not implemented")
}
func (UnimplementedGomoteServiceServer) SignSSHKey(context.Context, *SignSSHKeyRequest) (*SignSSHKeyResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method SignSSHKey not implemented")
}
func (UnimplementedGomoteServiceServer) UploadFile(context.Context, *UploadFileRequest) (*UploadFileResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method UploadFile not implemented")
}
func (UnimplementedGomoteServiceServer) WriteFileFromURL(context.Context, *WriteFileFromURLRequest) (*WriteFileFromURLResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method WriteFileFromURL not implemented")
}
func (UnimplementedGomoteServiceServer) WriteTGZFromURL(context.Context, *WriteTGZFromURLRequest) (*WriteTGZFromURLResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method WriteTGZFromURL not implemented")
}
func (UnimplementedGomoteServiceServer) mustEmbedUnimplementedGomoteServiceServer() {}

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

func RegisterGomoteServiceServer(s grpc.ServiceRegistrar, srv GomoteServiceServer) {
	s.RegisterService(&GomoteService_ServiceDesc, srv)
}

func _GomoteService_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(AuthenticateRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).Authenticate(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/Authenticate",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).Authenticate(ctx, req.(*AuthenticateRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_AddBootstrap_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(AddBootstrapRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).AddBootstrap(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/AddBootstrap",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).AddBootstrap(ctx, req.(*AddBootstrapRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_CreateInstance_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(CreateInstanceRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(GomoteServiceServer).CreateInstance(m, &gomoteServiceCreateInstanceServer{stream})
}

type GomoteService_CreateInstanceServer interface {
	Send(*CreateInstanceResponse) error
	grpc.ServerStream
}

type gomoteServiceCreateInstanceServer struct {
	grpc.ServerStream
}

func (x *gomoteServiceCreateInstanceServer) Send(m *CreateInstanceResponse) error {
	return x.ServerStream.SendMsg(m)
}

func _GomoteService_DestroyInstance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(DestroyInstanceRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).DestroyInstance(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/DestroyInstance",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).DestroyInstance(ctx, req.(*DestroyInstanceRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_ExecuteCommand_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(ExecuteCommandRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(GomoteServiceServer).ExecuteCommand(m, &gomoteServiceExecuteCommandServer{stream})
}

type GomoteService_ExecuteCommandServer interface {
	Send(*ExecuteCommandResponse) error
	grpc.ServerStream
}

type gomoteServiceExecuteCommandServer struct {
	grpc.ServerStream
}

func (x *gomoteServiceExecuteCommandServer) Send(m *ExecuteCommandResponse) error {
	return x.ServerStream.SendMsg(m)
}

func _GomoteService_InstanceAlive_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(InstanceAliveRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).InstanceAlive(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/InstanceAlive",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).InstanceAlive(ctx, req.(*InstanceAliveRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_ListDirectory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ListDirectoryRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).ListDirectory(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/ListDirectory",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).ListDirectory(ctx, req.(*ListDirectoryRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_ListInstances_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ListInstancesRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).ListInstances(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/ListInstances",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).ListInstances(ctx, req.(*ListInstancesRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_ListSwarmingBuilders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ListSwarmingBuildersRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).ListSwarmingBuilders(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/ListSwarmingBuilders",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).ListSwarmingBuilders(ctx, req.(*ListSwarmingBuildersRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_ReadTGZToURL_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ReadTGZToURLRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).ReadTGZToURL(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/ReadTGZToURL",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).ReadTGZToURL(ctx, req.(*ReadTGZToURLRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_RemoveFiles_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(RemoveFilesRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).RemoveFiles(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/RemoveFiles",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).RemoveFiles(ctx, req.(*RemoveFilesRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_SignSSHKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SignSSHKeyRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).SignSSHKey(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/SignSSHKey",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).SignSSHKey(ctx, req.(*SignSSHKeyRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_UploadFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(UploadFileRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).UploadFile(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/UploadFile",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).UploadFile(ctx, req.(*UploadFileRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_WriteFileFromURL_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(WriteFileFromURLRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).WriteFileFromURL(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/WriteFileFromURL",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).WriteFileFromURL(ctx, req.(*WriteFileFromURLRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GomoteService_WriteTGZFromURL_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(WriteTGZFromURLRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GomoteServiceServer).WriteTGZFromURL(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/protos.GomoteService/WriteTGZFromURL",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GomoteServiceServer).WriteTGZFromURL(ctx, req.(*WriteTGZFromURLRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// GomoteService_ServiceDesc is the grpc.ServiceDesc for GomoteService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var GomoteService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "protos.GomoteService",
	HandlerType: (*GomoteServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Authenticate",
			Handler:    _GomoteService_Authenticate_Handler,
		},
		{
			MethodName: "AddBootstrap",
			Handler:    _GomoteService_AddBootstrap_Handler,
		},
		{
			MethodName: "DestroyInstance",
			Handler:    _GomoteService_DestroyInstance_Handler,
		},
		{
			MethodName: "InstanceAlive",
			Handler:    _GomoteService_InstanceAlive_Handler,
		},
		{
			MethodName: "ListDirectory",
			Handler:    _GomoteService_ListDirectory_Handler,
		},
		{
			MethodName: "ListInstances",
			Handler:    _GomoteService_ListInstances_Handler,
		},
		{
			MethodName: "ListSwarmingBuilders",
			Handler:    _GomoteService_ListSwarmingBuilders_Handler,
		},
		{
			MethodName: "ReadTGZToURL",
			Handler:    _GomoteService_ReadTGZToURL_Handler,
		},
		{
			MethodName: "RemoveFiles",
			Handler:    _GomoteService_RemoveFiles_Handler,
		},
		{
			MethodName: "SignSSHKey",
			Handler:    _GomoteService_SignSSHKey_Handler,
		},
		{
			MethodName: "UploadFile",
			Handler:    _GomoteService_UploadFile_Handler,
		},
		{
			MethodName: "WriteFileFromURL",
			Handler:    _GomoteService_WriteFileFromURL_Handler,
		},
		{
			MethodName: "WriteTGZFromURL",
			Handler:    _GomoteService_WriteTGZFromURL_Handler,
		},
	},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "CreateInstance",
			Handler:       _GomoteService_CreateInstance_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "ExecuteCommand",
			Handler:       _GomoteService_ExecuteCommand_Handler,
			ServerStreams: true,
		},
	},
	Metadata: "gomote.proto",
}
