// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc             v4.25.1
// source: relui.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

const (
	ReleaseService_UpdateSigningStatus_FullMethodName = "/protos.ReleaseService/UpdateSigningStatus"
)

// ReleaseServiceClient is the client API for ReleaseService 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 ReleaseServiceClient interface {
	// UpdateSigningStatus is a bidirectional connection where server is requesting that the client:
	// - Sign a release artifact.
	// - Provide an update on a previous request to sign a release artifact.
	// - Consider a previous request to sign a release artifact as obsolete.
	// The client initiates a connection with the server and waits for the server to issue a request
	// such as:
	// - An update on the status of a signing request (either running or completed).
	// - An acknowledgement that a request to sign a release artifact has been accepted and initiated.
	UpdateSigningStatus(ctx context.Context, opts ...grpc.CallOption) (ReleaseService_UpdateSigningStatusClient, error)
}

type releaseServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewReleaseServiceClient(cc grpc.ClientConnInterface) ReleaseServiceClient {
	return &releaseServiceClient{cc}
}

func (c *releaseServiceClient) UpdateSigningStatus(ctx context.Context, opts ...grpc.CallOption) (ReleaseService_UpdateSigningStatusClient, error) {
	stream, err := c.cc.NewStream(ctx, &ReleaseService_ServiceDesc.Streams[0], ReleaseService_UpdateSigningStatus_FullMethodName, opts...)
	if err != nil {
		return nil, err
	}
	x := &releaseServiceUpdateSigningStatusClient{stream}
	return x, nil
}

type ReleaseService_UpdateSigningStatusClient interface {
	Send(*SigningStatus) error
	Recv() (*SigningRequest, error)
	grpc.ClientStream
}

type releaseServiceUpdateSigningStatusClient struct {
	grpc.ClientStream
}

func (x *releaseServiceUpdateSigningStatusClient) Send(m *SigningStatus) error {
	return x.ClientStream.SendMsg(m)
}

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

// ReleaseServiceServer is the server API for ReleaseService service.
// All implementations must embed UnimplementedReleaseServiceServer
// for forward compatibility
type ReleaseServiceServer interface {
	// UpdateSigningStatus is a bidirectional connection where server is requesting that the client:
	// - Sign a release artifact.
	// - Provide an update on a previous request to sign a release artifact.
	// - Consider a previous request to sign a release artifact as obsolete.
	// The client initiates a connection with the server and waits for the server to issue a request
	// such as:
	// - An update on the status of a signing request (either running or completed).
	// - An acknowledgement that a request to sign a release artifact has been accepted and initiated.
	UpdateSigningStatus(ReleaseService_UpdateSigningStatusServer) error
	mustEmbedUnimplementedReleaseServiceServer()
}

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

func (UnimplementedReleaseServiceServer) UpdateSigningStatus(ReleaseService_UpdateSigningStatusServer) error {
	return status.Errorf(codes.Unimplemented, "method UpdateSigningStatus not implemented")
}
func (UnimplementedReleaseServiceServer) mustEmbedUnimplementedReleaseServiceServer() {}

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

func RegisterReleaseServiceServer(s grpc.ServiceRegistrar, srv ReleaseServiceServer) {
	s.RegisterService(&ReleaseService_ServiceDesc, srv)
}

func _ReleaseService_UpdateSigningStatus_Handler(srv interface{}, stream grpc.ServerStream) error {
	return srv.(ReleaseServiceServer).UpdateSigningStatus(&releaseServiceUpdateSigningStatusServer{stream})
}

type ReleaseService_UpdateSigningStatusServer interface {
	Send(*SigningRequest) error
	Recv() (*SigningStatus, error)
	grpc.ServerStream
}

type releaseServiceUpdateSigningStatusServer struct {
	grpc.ServerStream
}

func (x *releaseServiceUpdateSigningStatusServer) Send(m *SigningRequest) error {
	return x.ServerStream.SendMsg(m)
}

func (x *releaseServiceUpdateSigningStatusServer) Recv() (*SigningStatus, error) {
	m := new(SigningStatus)
	if err := x.ServerStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

// ReleaseService_ServiceDesc is the grpc.ServiceDesc for ReleaseService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var ReleaseService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "protos.ReleaseService",
	HandlerType: (*ReleaseServiceServer)(nil),
	Methods:     []grpc.MethodDesc{},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "UpdateSigningStatus",
			Handler:       _ReleaseService_UpdateSigningStatus_Handler,
			ServerStreams: true,
			ClientStreams: true,
		},
	},
	Metadata: "relui.proto",
}
