// Copyright 2016 Google Inc.
//
// 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.

syntax = "proto3";

package google.bytestream;

import "google/api/annotations.proto";
import "google/protobuf/wrappers.proto";

option go_package = "google.golang.org/genproto/googleapis/bytestream;bytestream";
option java_outer_classname = "ByteStreamProto";
option java_package = "com.google.bytestream";


// #### Introduction
//
// The Byte Stream API enables a client to read and write a stream of bytes to
// and from a resource. Resources have names, and these names are supplied in
// the API calls below to identify the resource that is being read from or
// written to.
//
// All implementations of the Byte Stream API export the interface defined here:
//
// * `Read()`: Reads the contents of a resource.
//
// * `Write()`: Writes the contents of a resource. The client can call `Write()`
//   multiple times with the same resource and can check the status of the write
//   by calling `QueryWriteStatus()`.
//
// #### Service parameters and metadata
//
// The ByteStream API provides no direct way to access/modify any metadata
// associated with the resource.
//
// #### Errors
//
// The errors returned by the service are in the Google canonical error space.
service ByteStream {
  // `Read()` is used to retrieve the contents of a resource as a sequence
  // of bytes. The bytes are returned in a sequence of responses, and the
  // responses are delivered as the results of a server-side streaming RPC.
  rpc Read(ReadRequest) returns (stream ReadResponse);

  // `Write()` is used to send the contents of a resource as a sequence of
  // bytes. The bytes are sent in a sequence of request protos of a client-side
  // streaming RPC.
  //
  // A `Write()` action is resumable. If there is an error or the connection is
  // broken during the `Write()`, the client should check the status of the
  // `Write()` by calling `QueryWriteStatus()` and continue writing from the
  // returned `committed_size`. This may be less than the amount of data the
  // client previously sent.
  //
  // Calling `Write()` on a resource name that was previously written and
  // finalized could cause an error, depending on whether the underlying service
  // allows over-writing of previously written resources.
  //
  // When the client closes the request channel, the service will respond with
  // a `WriteResponse`. The service will not view the resource as `complete`
  // until the client has sent a `WriteRequest` with `finish_write` set to
  // `true`. Sending any requests on a stream after sending a request with
  // `finish_write` set to `true` will cause an error. The client **should**
  // check the `WriteResponse` it receives to determine how much data the
  // service was able to commit and whether the service views the resource as
  // `complete` or not.
  rpc Write(stream WriteRequest) returns (WriteResponse);

  // `QueryWriteStatus()` is used to find the `committed_size` for a resource
  // that is being written, which can then be used as the `write_offset` for
  // the next `Write()` call.
  //
  // If the resource does not exist (i.e., the resource has been deleted, or the
  // first `Write()` has not yet reached the service), this method returns the
  // error `NOT_FOUND`.
  //
  // The client **may** call `QueryWriteStatus()` at any time to determine how
  // much data has been processed for this resource. This is useful if the
  // client is buffering data and needs to know which data can be safely
  // evicted. For any sequence of `QueryWriteStatus()` calls for a given
  // resource name, the sequence of returned `committed_size` values will be
  // non-decreasing.
  rpc QueryWriteStatus(QueryWriteStatusRequest) returns (QueryWriteStatusResponse);
}

// Request object for ByteStream.Read.
message ReadRequest {
  // The name of the resource to read.
  string resource_name = 1;

  // The offset for the first byte to return in the read, relative to the start
  // of the resource.
  //
  // A `read_offset` that is negative or greater than the size of the resource
  // will cause an `OUT_OF_RANGE` error.
  int64 read_offset = 2;

  // The maximum number of `data` bytes the server is allowed to return in the
  // sum of all `ReadResponse` messages. A `read_limit` of zero indicates that
  // there is no limit, and a negative `read_limit` will cause an error.
  //
  // If the stream returns fewer bytes than allowed by the `read_limit` and no
  // error occurred, the stream includes all data from the `read_offset` to the
  // end of the resource.
  int64 read_limit = 3;
}

// Response object for ByteStream.Read.
message ReadResponse {
  // A portion of the data for the resource. The service **may** leave `data`
  // empty for any given `ReadResponse`. This enables the service to inform the
  // client that the request is still live while it is running an operation to
  // generate more data.
  bytes data = 10;
}

// Request object for ByteStream.Write.
message WriteRequest {
  // The name of the resource to write. This **must** be set on the first
  // `WriteRequest` of each `Write()` action. If it is set on subsequent calls,
  // it **must** match the value of the first request.
  string resource_name = 1;

  // The offset from the beginning of the resource at which the data should be
  // written. It is required on all `WriteRequest`s.
  //
  // In the first `WriteRequest` of a `Write()` action, it indicates
  // the initial offset for the `Write()` call. The value **must** be equal to
  // the `committed_size` that a call to `QueryWriteStatus()` would return.
  //
  // On subsequent calls, this value **must** be set and **must** be equal to
  // the sum of the first `write_offset` and the sizes of all `data` bundles
  // sent previously on this stream.
  //
  // An incorrect value will cause an error.
  int64 write_offset = 2;

  // If `true`, this indicates that the write is complete. Sending any
  // `WriteRequest`s subsequent to one in which `finish_write` is `true` will
  // cause an error.
  bool finish_write = 3;

  // A portion of the data for the resource. The client **may** leave `data`
  // empty for any given `WriteRequest`. This enables the client to inform the
  // service that the request is still live while it is running an operation to
  // generate more data.
  bytes data = 10;
}

// Response object for ByteStream.Write.
message WriteResponse {
  // The number of bytes that have been processed for the given resource.
  int64 committed_size = 1;
}

// Request object for ByteStream.QueryWriteStatus.
message QueryWriteStatusRequest {
  // The name of the resource whose write status is being requested.
  string resource_name = 1;
}

// Response object for ByteStream.QueryWriteStatus.
message QueryWriteStatusResponse {
  // The number of bytes that have been processed for the given resource.
  int64 committed_size = 1;

  // `complete` is `true` only if the client has sent a `WriteRequest` with
  // `finish_write` set to true, and the server has processed that request.
  bool complete = 2;
}
