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

// 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)
	// Added in R121.
	GenerateUnsignedPayload(ctx context.Context, in *GenerateUnsignedPayloadRequest, opts ...grpc.CallOption) (*GenerateUnsignedPayloadResponse, error)
	// Added in R121.
	FinalizePayload(ctx context.Context, in *FinalizePayloadRequest, opts ...grpc.CallOption) (*FinalizePayloadResponse, 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
}

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

func (c *payloadServiceClient) FinalizePayload(ctx context.Context, in *FinalizePayloadRequest, opts ...grpc.CallOption) (*FinalizePayloadResponse, error) {
	out := new(FinalizePayloadResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.PayloadService/FinalizePayload", 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)
	// Added in R121.
	GenerateUnsignedPayload(context.Context, *GenerateUnsignedPayloadRequest) (*GenerateUnsignedPayloadResponse, error)
	// Added in R121.
	FinalizePayload(context.Context, *FinalizePayloadRequest) (*FinalizePayloadResponse, 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) GenerateUnsignedPayload(context.Context, *GenerateUnsignedPayloadRequest) (*GenerateUnsignedPayloadResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GenerateUnsignedPayload not implemented")
}
func (UnimplementedPayloadServiceServer) FinalizePayload(context.Context, *FinalizePayloadRequest) (*FinalizePayloadResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method FinalizePayload 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)
}

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

func _PayloadService_FinalizePayload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(FinalizePayloadRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(PayloadServiceServer).FinalizePayload(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.PayloadService/FinalizePayload",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(PayloadServiceServer).FinalizePayload(ctx, req.(*FinalizePayloadRequest))
	}
	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,
		},
		{
			MethodName: "GenerateUnsignedPayload",
			Handler:    _PayloadService_GenerateUnsignedPayload_Handler,
		},
		{
			MethodName: "FinalizePayload",
			Handler:    _PayloadService_FinalizePayload_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/payload.proto",
}
