// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.1.0
// - protoc             v3.17.1
// source: chromite/api/portage_explorer.proto

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

// PortageExplorerServiceClient is the client API for PortageExplorerService 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 PortageExplorerServiceClient interface {
	// Run each individual spider to record data.
	RunSpiders(ctx context.Context, in *RunSpidersRequest, opts ...grpc.CallOption) (*RunSpidersResponse, error)
}

type portageExplorerServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewPortageExplorerServiceClient(cc grpc.ClientConnInterface) PortageExplorerServiceClient {
	return &portageExplorerServiceClient{cc}
}

func (c *portageExplorerServiceClient) RunSpiders(ctx context.Context, in *RunSpidersRequest, opts ...grpc.CallOption) (*RunSpidersResponse, error) {
	out := new(RunSpidersResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PortageExplorerService/RunSpiders", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// PortageExplorerServiceServer is the server API for PortageExplorerService service.
// All implementations must embed UnimplementedPortageExplorerServiceServer
// for forward compatibility
type PortageExplorerServiceServer interface {
	// Run each individual spider to record data.
	RunSpiders(context.Context, *RunSpidersRequest) (*RunSpidersResponse, error)
	mustEmbedUnimplementedPortageExplorerServiceServer()
}

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

func (UnimplementedPortageExplorerServiceServer) RunSpiders(context.Context, *RunSpidersRequest) (*RunSpidersResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method RunSpiders not implemented")
}
func (UnimplementedPortageExplorerServiceServer) mustEmbedUnimplementedPortageExplorerServiceServer() {
}

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

func RegisterPortageExplorerServiceServer(s grpc.ServiceRegistrar, srv PortageExplorerServiceServer) {
	s.RegisterService(&PortageExplorerService_ServiceDesc, srv)
}

func _PortageExplorerService_RunSpiders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(RunSpidersRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PortageExplorerServiceServer).RunSpiders(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PortageExplorerService/RunSpiders",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PortageExplorerServiceServer).RunSpiders(ctx, req.(*RunSpidersRequest))
	}
	return interceptor(ctx, in, info, handler)
}

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