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

// PayloadServiceClient is the client API for PayloadService 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 PayloadServiceClient interface {
	// Added in R79.
	GeneratePayload(ctx context.Context, in *GenerationRequest, opts ...grpc.CallOption) (*GenerationResponse, error)
}

type payloadServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewPayloadServiceClient(cc grpc.ClientConnInterface) PayloadServiceClient {
	return &payloadServiceClient{cc}
}

func (c *payloadServiceClient) GeneratePayload(ctx context.Context, in *GenerationRequest, opts ...grpc.CallOption) (*GenerationResponse, error) {
	out := new(GenerationResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PayloadService/GeneratePayload", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// PayloadServiceServer is the server API for PayloadService service.
// All implementations must embed UnimplementedPayloadServiceServer
// for forward compatibility
type PayloadServiceServer interface {
	// Added in R79.
	GeneratePayload(context.Context, *GenerationRequest) (*GenerationResponse, error)
	mustEmbedUnimplementedPayloadServiceServer()
}

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

func (UnimplementedPayloadServiceServer) GeneratePayload(context.Context, *GenerationRequest) (*GenerationResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GeneratePayload not implemented")
}
func (UnimplementedPayloadServiceServer) mustEmbedUnimplementedPayloadServiceServer() {}

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

func RegisterPayloadServiceServer(s grpc.ServiceRegistrar, srv PayloadServiceServer) {
	s.RegisterService(&PayloadService_ServiceDesc, srv)
}

func _PayloadService_GeneratePayload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GenerationRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PayloadServiceServer).GeneratePayload(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PayloadService/GeneratePayload",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PayloadServiceServer).GeneratePayload(ctx, req.(*GenerationRequest))
	}
	return interceptor(ctx, in, info, handler)
}

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