// M-Files Server gRPC API 26.11. Generated from the M-Files Server IDL; do not edit.
// Documentation: https://developer.m-files.com/APIs/gRPC-API/
syntax = "proto3";

package MFiles;

import "mfiles/api/annotations.proto";
import "mfiles/structs.proto";

option csharp_namespace = "MFiles.Grpc";
option go_package = "github.com/M-Files/mfiles-grpc-api/go/mfiles;mfiles";
option java_multiple_files = true;
option java_package = "com.mfiles.grpc";
option objc_class_prefix = "MF_";

// Stateless file upload. No method requires a sticky session.
//
// The file_ref identifies state in Master Storage, not in an MFServer process, so any server instance
// can serve any call.
//
// The file data is sent with the hand-written client-streaming methods of IRPCFileTransferStreaming in
// mfiles.filestreaming.proto, as the IDL supports only unary methods:
// - FileUploadWhole: uploads a whole file in one call.
// - FileUploadBlock: uploads one block between FileUploadBegin and FileUploadEnd.
//
// Uploads identified by a `file_ref` string instead of an upload ID. Together with
// [IRPCFileTransferStreaming](mfiles:MFiles.IRPCFileTransferStreaming), which carries the data,
// this service is an alternative to the upload sessions of
// [UploadTempFile](mfiles:MFiles.IRPCObjectOperations.UploadTempFile) and
// [UploadFile](mfiles:MFiles.IRPCObjectOperations.UploadFile).
//
// **Availability.** Stateless uploads are switched off by default in M-Files Server 26.11: every
// method of this service and of `IRPCFileTransferStreaming` then answers "Not implemented.", and
// [ServerVaultCapabilities](mfiles:MFiles.ServerVaultCapabilities)
// `file_upload_stateless_supported` is false. Check that capability first; when it is false, upload
// with [UploadTempFile](mfiles:MFiles.IRPCObjectOperations.UploadTempFile) and
// [UploadTempFileCommit](mfiles:MFiles.IRPCObjectOperations.UploadTempFileCommit) instead. See
// [Files](https://developer.m-files.com/APIs/gRPC-API/runtime/files/).
//
// **Two ways to upload.**
//
// - A file that fits in one storage request (see the size limit of `FileUploadWhole`):
//   [FileUploadWhole](mfiles:MFiles.IRPCFileTransferStreaming.FileUploadWhole), one call.
// - Any file: [FileUploadBegin](mfiles:MFiles.IRPCFileTransfer.FileUploadBegin),
//   [FileUploadBlock](mfiles:MFiles.IRPCFileTransferStreaming.FileUploadBlock) for each block, then
//   [FileUploadEnd](mfiles:MFiles.IRPCFileTransfer.FileUploadEnd).
//
// **Using the upload.** An ended upload is used by its `file_ref`: as the content of an existing file
// of a checked-out object with [FileUploadAttach](mfiles:MFiles.IRPCFileTransfer.FileUploadAttach),
// in the `file_ref` field of the uploaded-file sources of
// [AddObjectWithFiles](mfiles:MFiles.IRPCObjectOperations.AddObjectWithFiles), with
// [DownloadTempFileFromUpload_Begin](mfiles:MFiles.IRPCObjectOperations.DownloadTempFileFromUpload_Begin),
// and as OCR input in [IRPCScanningAndOCR](mfiles:MFiles.IRPCScanningAndOCR).
//
// **Where the upload is stored.** This depends on where the vault keeps its file data, and decides
// what `FileUploadBegin` returns:
//
// | Vault file data | `file_ref` | Blocks | Served by |
// | --- | --- | --- | --- |
// | Master Storage | a GUID | up to the Master Storage single request limit, any order | any server instance |
// | Azure Blob Storage | a GUID | up to the Blob Storage block size (4 MiB by default), any order | any server instance |
// | Disk or database | the upload ID in decimal | up to 4 MiB, in order | the server and login session that began it |
//
// In the last case the upload is an upload session as with `UploadTempFile`: it is bound to the
// login session and the server instance, and anonymous sessions cannot upload.
service IRPCFileTransfer {
	option (mfiles.api.service) = { book: "vault" level: LEVEL_STANDARD title: "Stateless file upload sessions" };

	// Begins an upload in blocks and returns its `file_ref` and the block rules.
	//
	// Upload the blocks with
	// [FileUploadBlock](mfiles:MFiles.IRPCFileTransferStreaming.FileUploadBlock), each at most
	// `max_block_size` bytes; all blocks but the last must be exactly `max_block_size` bytes when
	// `require_sequential_blocks` is true. Then call
	// [FileUploadEnd](mfiles:MFiles.IRPCFileTransfer.FileUploadEnd).
	//
	// A file has at most 50,000 blocks. If `total_size_in_bytes` is larger than 50,000 times the
	// maximum block size, the call fails with `ERROR_FILE_TOO_LARGE`. Event handlers of the vault can
	// cancel the upload here; the call then fails with their error.
	rpc FileUploadBegin( FileUploadBeginRequest ) returns ( FileUploadBeginResponse ) {
		option (mfiles.api.method) = { session: SESSION_REQUIREMENT_SESSION_OR_ASSERTION };
	}

	// Completes an upload in blocks. Binds the content to no object; use FileUploadAttach or
	// AddObjectWithFiles for that.
	//
	// `block_count` must match the uploaded blocks 0..`block_count`-1 ("The block count does not match
	// the uploaded blocks." otherwise), and the content must have the `total_size_in_bytes` given to
	// `FileUploadBegin`, if any ("File size mismatch.").
	rpc FileUploadEnd( FileUploadEndRequest ) returns ( FileUploadEndResponse ) {
		option (mfiles.api.method) = { session: SESSION_REQUIREMENT_SESSION_OR_ASSERTION };
	}

	// Stores an ended upload as the new content of an existing file of an object that is checked out to
	// the caller.
	//
	// Works like [UploadFileCommit](mfiles:MFiles.IRPCObjectOperations.UploadFileCommit): the object
	// must be checked out to the caller and the caller needs edit access to it. The server calculates
	// the MD5 checksum from the content.
	//
	// `file.size` must be the exact size of the upload, with `size_precision`
	// `FILE_SIZE_PRECISION_EXACT` ("The size of the attached file must be exact."). Time stamps that are
	// not set get the current time.
	//
	// An upload can be attached once. Attaching it to another file fails with "The uploaded file has
	// already been attached.". When the vault uses Master Storage, repeating the same attach (a retried
	// call) succeeds without attaching the file again.
	rpc FileUploadAttach( FileUploadAttachRequest ) returns ( FileUploadAttachResponse ) {
		option (mfiles.api.method) = { session: SESSION_REQUIREMENT_SESSION_OR_ASSERTION returns_metadata_structure_version: true };
	}
}

// The request of FileUploadBegin.
message FileUploadBeginRequest {

	// The size of the whole file in bytes, if known; 0 if not. If set, the ended upload must have exactly this size.
	int64 total_size_in_bytes = 1;
}

// The response of FileUploadBegin.
message FileUploadBeginResponse {

	// Identifies the upload in `FileUploadBlock`, `FileUploadEnd`, `FileUploadAttach` and the other methods that take an uploaded file.
	string file_ref = 1;

	// The maximum size of one block in bytes.
	int64 max_block_size = 2;

	// True if the blocks must be uploaded in order, one at a time, and every block but the last must be `max_block_size` bytes. False if blocks can be uploaded in any order and concurrently, also through different server instances.
	bool require_sequential_blocks = 3;
}

// The request of FileUploadEnd.
message FileUploadEndRequest {

	// The `file_ref` from `FileUploadBegin`.
	string file_ref = 1;

	// The number of uploaded blocks, at most 50,000. The blocks are indexes 0 to `block_count`-1.
	int64 block_count = 2;
}

// The response of FileUploadEnd.
message FileUploadEndResponse {
}

// FileUploadAttach method request structure. The server calculates the MD5 checksum of the file from the content.
message FileUploadAttachRequest {

	// The `file_ref` of an ended upload (`FileUploadEnd` or `FileUploadWhole`).
	string file_ref = 1;

	// The object that owns the file. If set, it must be that object.
	ObjID obj_id = 2;

	// The file to replace, with the `file_ver` of the checked-out version and the exact `size` of the upload.
	File file = 3;
}

// The response of FileUploadAttach.
message FileUploadAttachResponse {

	// True if `after_upload` is filled.
	bool is_object_info_available = 1;

	// The version information of the object after the attach, if `is_object_info_available` is true.
	ObjectVersionEx after_upload = 2;

	// Information about objects that were also updated during the operation.
	repeated ObjectVersionEx updated_objects = 3;
}
