// Copyright 2017 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc             v3.21.7
// source: go.chromium.org/luci/cipd/api/cipd/v1/cas.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

const (
	Storage_GetObjectURL_FullMethodName = "/cipd.Storage/GetObjectURL"
	Storage_BeginUpload_FullMethodName  = "/cipd.Storage/BeginUpload"
	Storage_FinishUpload_FullMethodName = "/cipd.Storage/FinishUpload"
	Storage_CancelUpload_FullMethodName = "/cipd.Storage/CancelUpload"
)

// StorageClient is the client API for Storage 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 StorageClient interface {
	// Produces a signed URL that can be used to fetch an object.
	//
	// Returns NOT_FOUND status code if there's no such object.
	GetObjectURL(ctx context.Context, in *GetObjectURLRequest, opts ...grpc.CallOption) (*ObjectURL, error)
	// Initiates an upload operation.
	//
	// Once the upload is initiated the client is responsible for uploading the
	// object to the temporary location (provided via 'upload_url' which should be
	// used as an upload URL in Google Storage Resumable Upload protocol) and
	// finishing the upload with a call to FinishUpload, which will launch
	// the verification of the object's hash on the server side.
	//
	// If the client knows the hash of the object it wants to upload already, it
	// can provide it via 'object' field. In that case Storage may reply right
	// away that such object already exists by retuning ALREADY_EXISTS status
	// code.
	//
	// If the client doesn't know the hash yet (perhaps if the object's body is
	// generated on the fly), it still can open an upload operation and start
	// streaming the data. When finalizing the upload the backend will calculate
	// and return the resulting hash of the object.
	//
	// An UploadOperation returned by this method contains tokens that grant
	// direct upload access to whoever possesses them, so it should be treated as
	// a secret. See UploadOperation for more info.
	BeginUpload(ctx context.Context, in *BeginUploadRequest, opts ...grpc.CallOption) (*UploadOperation, error)
	// Finishes the pending upload operation, returning its new status.
	//
	// Clients are expected to finish Google Storage Resumable protocol first
	// before calling FinishUpload. Failure to do so will cause the upload
	// operation to end up in ERROR state.
	//
	// This call is idempotent and it is expected that clients will keep polling
	// it if they want to wait for the server to verify the hash of the uploaded
	// object.
	//
	// Returns NOT_FOUND if the provided upload operation doesn't exist.
	//
	// Errors related to the uploaded file body are communicated through 'status'
	// field of the upload operation, since they are not directly related to this
	// RPC call, but rather to the upload operation itself.
	FinishUpload(ctx context.Context, in *FinishUploadRequest, opts ...grpc.CallOption) (*UploadOperation, error)
	// CancelUpload aborts the pending upload operation.
	//
	// It moves it to CANCELED state if it was in UPLOADING state and cleans up
	// any temporary garbage. Returns the most recent state of the upload
	// operation (whatever it may be).
	//
	// Does nothing if the operation is already canceled or failed.
	//
	// Returns:
	//
	//	NOT_FOUND if the provided upload operation doesn't exist.
	//	FAILED_PRECONDITION if the upload operation is in PUBLISHED or VERIFYING
	//	   state (i.e. finished or being finalized now).
	CancelUpload(ctx context.Context, in *CancelUploadRequest, opts ...grpc.CallOption) (*UploadOperation, error)
}

type storageClient struct {
	cc grpc.ClientConnInterface
}

func NewStorageClient(cc grpc.ClientConnInterface) StorageClient {
	return &storageClient{cc}
}

func (c *storageClient) GetObjectURL(ctx context.Context, in *GetObjectURLRequest, opts ...grpc.CallOption) (*ObjectURL, error) {
	out := new(ObjectURL)
	err := c.cc.Invoke(ctx, Storage_GetObjectURL_FullMethodName, in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *storageClient) BeginUpload(ctx context.Context, in *BeginUploadRequest, opts ...grpc.CallOption) (*UploadOperation, error) {
	out := new(UploadOperation)
	err := c.cc.Invoke(ctx, Storage_BeginUpload_FullMethodName, in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *storageClient) FinishUpload(ctx context.Context, in *FinishUploadRequest, opts ...grpc.CallOption) (*UploadOperation, error) {
	out := new(UploadOperation)
	err := c.cc.Invoke(ctx, Storage_FinishUpload_FullMethodName, in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *storageClient) CancelUpload(ctx context.Context, in *CancelUploadRequest, opts ...grpc.CallOption) (*UploadOperation, error) {
	out := new(UploadOperation)
	err := c.cc.Invoke(ctx, Storage_CancelUpload_FullMethodName, in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// StorageServer is the server API for Storage service.
// All implementations must embed UnimplementedStorageServer
// for forward compatibility
type StorageServer interface {
	// Produces a signed URL that can be used to fetch an object.
	//
	// Returns NOT_FOUND status code if there's no such object.
	GetObjectURL(context.Context, *GetObjectURLRequest) (*ObjectURL, error)
	// Initiates an upload operation.
	//
	// Once the upload is initiated the client is responsible for uploading the
	// object to the temporary location (provided via 'upload_url' which should be
	// used as an upload URL in Google Storage Resumable Upload protocol) and
	// finishing the upload with a call to FinishUpload, which will launch
	// the verification of the object's hash on the server side.
	//
	// If the client knows the hash of the object it wants to upload already, it
	// can provide it via 'object' field. In that case Storage may reply right
	// away that such object already exists by retuning ALREADY_EXISTS status
	// code.
	//
	// If the client doesn't know the hash yet (perhaps if the object's body is
	// generated on the fly), it still can open an upload operation and start
	// streaming the data. When finalizing the upload the backend will calculate
	// and return the resulting hash of the object.
	//
	// An UploadOperation returned by this method contains tokens that grant
	// direct upload access to whoever possesses them, so it should be treated as
	// a secret. See UploadOperation for more info.
	BeginUpload(context.Context, *BeginUploadRequest) (*UploadOperation, error)
	// Finishes the pending upload operation, returning its new status.
	//
	// Clients are expected to finish Google Storage Resumable protocol first
	// before calling FinishUpload. Failure to do so will cause the upload
	// operation to end up in ERROR state.
	//
	// This call is idempotent and it is expected that clients will keep polling
	// it if they want to wait for the server to verify the hash of the uploaded
	// object.
	//
	// Returns NOT_FOUND if the provided upload operation doesn't exist.
	//
	// Errors related to the uploaded file body are communicated through 'status'
	// field of the upload operation, since they are not directly related to this
	// RPC call, but rather to the upload operation itself.
	FinishUpload(context.Context, *FinishUploadRequest) (*UploadOperation, error)
	// CancelUpload aborts the pending upload operation.
	//
	// It moves it to CANCELED state if it was in UPLOADING state and cleans up
	// any temporary garbage. Returns the most recent state of the upload
	// operation (whatever it may be).
	//
	// Does nothing if the operation is already canceled or failed.
	//
	// Returns:
	//
	//	NOT_FOUND if the provided upload operation doesn't exist.
	//	FAILED_PRECONDITION if the upload operation is in PUBLISHED or VERIFYING
	//	   state (i.e. finished or being finalized now).
	CancelUpload(context.Context, *CancelUploadRequest) (*UploadOperation, error)
	mustEmbedUnimplementedStorageServer()
}

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

func (UnimplementedStorageServer) GetObjectURL(context.Context, *GetObjectURLRequest) (*ObjectURL, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetObjectURL not implemented")
}
func (UnimplementedStorageServer) BeginUpload(context.Context, *BeginUploadRequest) (*UploadOperation, error) {
	return nil, status.Errorf(codes.Unimplemented, "method BeginUpload not implemented")
}
func (UnimplementedStorageServer) FinishUpload(context.Context, *FinishUploadRequest) (*UploadOperation, error) {
	return nil, status.Errorf(codes.Unimplemented, "method FinishUpload not implemented")
}
func (UnimplementedStorageServer) CancelUpload(context.Context, *CancelUploadRequest) (*UploadOperation, error) {
	return nil, status.Errorf(codes.Unimplemented, "method CancelUpload not implemented")
}
func (UnimplementedStorageServer) mustEmbedUnimplementedStorageServer() {}

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

func RegisterStorageServer(s grpc.ServiceRegistrar, srv StorageServer) {
	s.RegisterService(&Storage_ServiceDesc, srv)
}

func _Storage_GetObjectURL_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetObjectURLRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(StorageServer).GetObjectURL(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: Storage_GetObjectURL_FullMethodName,
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(StorageServer).GetObjectURL(ctx, req.(*GetObjectURLRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _Storage_BeginUpload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(BeginUploadRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(StorageServer).BeginUpload(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: Storage_BeginUpload_FullMethodName,
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(StorageServer).BeginUpload(ctx, req.(*BeginUploadRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _Storage_FinishUpload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(FinishUploadRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(StorageServer).FinishUpload(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: Storage_FinishUpload_FullMethodName,
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(StorageServer).FinishUpload(ctx, req.(*FinishUploadRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _Storage_CancelUpload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(CancelUploadRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(StorageServer).CancelUpload(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: Storage_CancelUpload_FullMethodName,
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(StorageServer).CancelUpload(ctx, req.(*CancelUploadRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// Storage_ServiceDesc is the grpc.ServiceDesc for Storage service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Storage_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "cipd.Storage",
	HandlerType: (*StorageServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "GetObjectURL",
			Handler:    _Storage_GetObjectURL_Handler,
		},
		{
			MethodName: "BeginUpload",
			Handler:    _Storage_BeginUpload_Handler,
		},
		{
			MethodName: "FinishUpload",
			Handler:    _Storage_FinishUpload_Handler,
		},
		{
			MethodName: "CancelUpload",
			Handler:    _Storage_CancelUpload_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "go.chromium.org/luci/cipd/api/cipd/v1/cas.proto",
}
