// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc             v3.21.12
// source: bisection/proto/culprit_detection.proto

package proto

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

const (
	CulpritDetection_GetPerformanceDifference_FullMethodName = "/CulpritDetection/GetPerformanceDifference"
)

// CulpritDetectionClient is the client API for CulpritDetection 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 CulpritDetectionClient interface {
	// GetPerformanceDifference determines whether two changes are performantly different.
	//
	// Performance differences are used to find culprits for performance metrics.
	// Thus, a performance difference indicates some performance regression.
	// See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/speed/bisects.md
	// for more details.
	GetPerformanceDifference(ctx context.Context, in *GetPerformanceDifferenceRequest, opts ...grpc.CallOption) (*GetPerformanceDifferenceResponse, error)
}

type culpritDetectionClient struct {
	cc grpc.ClientConnInterface
}

func NewCulpritDetectionClient(cc grpc.ClientConnInterface) CulpritDetectionClient {
	return &culpritDetectionClient{cc}
}

func (c *culpritDetectionClient) GetPerformanceDifference(ctx context.Context, in *GetPerformanceDifferenceRequest, opts ...grpc.CallOption) (*GetPerformanceDifferenceResponse, error) {
	out := new(GetPerformanceDifferenceResponse)
	err := c.cc.Invoke(ctx, CulpritDetection_GetPerformanceDifference_FullMethodName, in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// CulpritDetectionServer is the server API for CulpritDetection service.
// All implementations must embed UnimplementedCulpritDetectionServer
// for forward compatibility
type CulpritDetectionServer interface {
	// GetPerformanceDifference determines whether two changes are performantly different.
	//
	// Performance differences are used to find culprits for performance metrics.
	// Thus, a performance difference indicates some performance regression.
	// See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/speed/bisects.md
	// for more details.
	GetPerformanceDifference(context.Context, *GetPerformanceDifferenceRequest) (*GetPerformanceDifferenceResponse, error)
	mustEmbedUnimplementedCulpritDetectionServer()
}

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

func (UnimplementedCulpritDetectionServer) GetPerformanceDifference(context.Context, *GetPerformanceDifferenceRequest) (*GetPerformanceDifferenceResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetPerformanceDifference not implemented")
}
func (UnimplementedCulpritDetectionServer) mustEmbedUnimplementedCulpritDetectionServer() {}

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

func RegisterCulpritDetectionServer(s grpc.ServiceRegistrar, srv CulpritDetectionServer) {
	s.RegisterService(&CulpritDetection_ServiceDesc, srv)
}

func _CulpritDetection_GetPerformanceDifference_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetPerformanceDifferenceRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(CulpritDetectionServer).GetPerformanceDifference(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: CulpritDetection_GetPerformanceDifference_FullMethodName,
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(CulpritDetectionServer).GetPerformanceDifference(ctx, req.(*GetPerformanceDifferenceRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// CulpritDetection_ServiceDesc is the grpc.ServiceDesc for CulpritDetection service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var CulpritDetection_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "CulpritDetection",
	HandlerType: (*CulpritDetectionServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "GetPerformanceDifference",
			Handler:    _CulpritDetection_GetPerformanceDifference_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "bisection/proto/culprit_detection.proto",
}
