// Copyright 2017 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.pubsub.v1;

import "google/api/annotations.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option cc_enable_arenas = true;
option csharp_namespace = "Google.Cloud.PubSub.V1";
option go_package = "google.golang.org/genproto/googleapis/pubsub/v1;pubsub";
option java_multiple_files = true;
option java_outer_classname = "PubsubProto";
option java_package = "com.google.pubsub.v1";


// The service that an application uses to manipulate subscriptions and to
// consume messages from a subscription via the `Pull` method.
service Subscriber {
  // Creates a subscription to a given topic.
  // If the subscription already exists, returns `ALREADY_EXISTS`.
  // If the corresponding topic doesn't exist, returns `NOT_FOUND`.
  //
  // If the name is not provided in the request, the server will assign a random
  // name for this subscription on the same project as the topic, conforming
  // to the
  // [resource name format](https://cloud.google.com/pubsub/docs/overview#names).
  // The generated name is populated in the returned Subscription object.
  // Note that for REST API requests, you must specify a name in the request.
  rpc CreateSubscription(Subscription) returns (Subscription) {
    option (google.api.http) = { put: "/v1/{name=projects/*/subscriptions/*}" body: "*" };
  }

  // Gets the configuration details of a subscription.
  rpc GetSubscription(GetSubscriptionRequest) returns (Subscription) {
    option (google.api.http) = { get: "/v1/{subscription=projects/*/subscriptions/*}" };
  }

  // Updates an existing subscription. Note that certain properties of a
  // subscription, such as its topic, are not modifiable.
  rpc UpdateSubscription(UpdateSubscriptionRequest) returns (Subscription) {
    option (google.api.http) = { patch: "/v1/{subscription.name=projects/*/subscriptions/*}" body: "*" };
  }

  // Lists matching subscriptions.
  rpc ListSubscriptions(ListSubscriptionsRequest) returns (ListSubscriptionsResponse) {
    option (google.api.http) = { get: "/v1/{project=projects/*}/subscriptions" };
  }

  // Deletes an existing subscription. All messages retained in the subscription
  // are immediately dropped. Calls to `Pull` after deletion will return
  // `NOT_FOUND`. After a subscription is deleted, a new one may be created with
  // the same name, but the new one has no association with the old
  // subscription or its topic unless the same topic is specified.
  rpc DeleteSubscription(DeleteSubscriptionRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { delete: "/v1/{subscription=projects/*/subscriptions/*}" };
  }

  // Modifies the ack deadline for a specific message. This method is useful
  // to indicate that more time is needed to process a message by the
  // subscriber, or to make the message available for redelivery if the
  // processing was interrupted. Note that this does not modify the
  // subscription-level `ackDeadlineSeconds` used for subsequent messages.
  rpc ModifyAckDeadline(ModifyAckDeadlineRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { post: "/v1/{subscription=projects/*/subscriptions/*}:modifyAckDeadline" body: "*" };
  }

  // Acknowledges the messages associated with the `ack_ids` in the
  // `AcknowledgeRequest`. The Pub/Sub system can remove the relevant messages
  // from the subscription.
  //
  // Acknowledging a message whose ack deadline has expired may succeed,
  // but such a message may be redelivered later. Acknowledging a message more
  // than once will not result in an error.
  rpc Acknowledge(AcknowledgeRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { post: "/v1/{subscription=projects/*/subscriptions/*}:acknowledge" body: "*" };
  }

  // Pulls messages from the server. Returns an empty list if there are no
  // messages available in the backlog. The server may return `UNAVAILABLE` if
  // there are too many concurrent pull requests pending for the given
  // subscription.
  rpc Pull(PullRequest) returns (PullResponse) {
    option (google.api.http) = { post: "/v1/{subscription=projects/*/subscriptions/*}:pull" body: "*" };
  }

  // (EXPERIMENTAL) StreamingPull is an experimental feature. This RPC will
  // respond with UNIMPLEMENTED errors unless you have been invited to test
  // this feature. Contact cloud-pubsub@google.com with any questions.
  //
  // Establishes a stream with the server, which sends messages down to the
  // client. The client streams acknowledgements and ack deadline modifications
  // back to the server. The server will close the stream and return the status
  // on any error. The server may close the stream with status `OK` to reassign
  // server-side resources, in which case, the client should re-establish the
  // stream. `UNAVAILABLE` may also be returned in the case of a transient error
  // (e.g., a server restart). These should also be retried by the client. Flow
  // control can be achieved by configuring the underlying RPC channel.
  rpc StreamingPull(stream StreamingPullRequest) returns (stream StreamingPullResponse);

  // Modifies the `PushConfig` for a specified subscription.
  //
  // This may be used to change a push subscription to a pull one (signified by
  // an empty `PushConfig`) or vice versa, or change the endpoint URL and other
  // attributes of a push subscription. Messages will accumulate for delivery
  // continuously through the call regardless of changes to the `PushConfig`.
  rpc ModifyPushConfig(ModifyPushConfigRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { post: "/v1/{subscription=projects/*/subscriptions/*}:modifyPushConfig" body: "*" };
  }

  // Lists the existing snapshots.
  rpc ListSnapshots(ListSnapshotsRequest) returns (ListSnapshotsResponse) {
    option (google.api.http) = { get: "/v1/{project=projects/*}/snapshots" };
  }

  // Creates a snapshot from the requested subscription.
  // If the snapshot already exists, returns `ALREADY_EXISTS`.
  // If the requested subscription doesn't exist, returns `NOT_FOUND`.
  //
  // If the name is not provided in the request, the server will assign a random
  // name for this snapshot on the same project as the subscription, conforming
  // to the
  // [resource name format](https://cloud.google.com/pubsub/docs/overview#names).
  // The generated name is populated in the returned Snapshot object.
  // Note that for REST API requests, you must specify a name in the request.
  rpc CreateSnapshot(CreateSnapshotRequest) returns (Snapshot) {
    option (google.api.http) = { put: "/v1/{name=projects/*/snapshots/*}" body: "*" };
  }

  // Removes an existing snapshot. All messages retained in the snapshot
  // are immediately dropped. After a snapshot is deleted, a new one may be
  // created with the same name, but the new one has no association with the old
  // snapshot or its subscription, unless the same subscription is specified.
  rpc DeleteSnapshot(DeleteSnapshotRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { delete: "/v1/{snapshot=projects/*/snapshots/*}" };
  }

  // Seeks an existing subscription to a point in time or to a given snapshot,
  // whichever is provided in the request.
  rpc Seek(SeekRequest) returns (SeekResponse) {
    option (google.api.http) = { post: "/v1/{subscription=projects/*/subscriptions/*}:seek" body: "*" };
  }
}

// The service that an application uses to manipulate topics, and to send
// messages to a topic.
service Publisher {
  // Creates the given topic with the given name.
  rpc CreateTopic(Topic) returns (Topic) {
    option (google.api.http) = { put: "/v1/{name=projects/*/topics/*}" body: "*" };
  }

  // Adds one or more messages to the topic. Returns `NOT_FOUND` if the topic
  // does not exist. The message payload must not be empty; it must contain
  //  either a non-empty data field, or at least one attribute.
  rpc Publish(PublishRequest) returns (PublishResponse) {
    option (google.api.http) = { post: "/v1/{topic=projects/*/topics/*}:publish" body: "*" };
  }

  // Gets the configuration of a topic.
  rpc GetTopic(GetTopicRequest) returns (Topic) {
    option (google.api.http) = { get: "/v1/{topic=projects/*/topics/*}" };
  }

  // Lists matching topics.
  rpc ListTopics(ListTopicsRequest) returns (ListTopicsResponse) {
    option (google.api.http) = { get: "/v1/{project=projects/*}/topics" };
  }

  // Lists the name of the subscriptions for this topic.
  rpc ListTopicSubscriptions(ListTopicSubscriptionsRequest) returns (ListTopicSubscriptionsResponse) {
    option (google.api.http) = { get: "/v1/{topic=projects/*/topics/*}/subscriptions" };
  }

  // Deletes the topic with the given name. Returns `NOT_FOUND` if the topic
  // does not exist. After a topic is deleted, a new topic may be created with
  // the same name; this is an entirely new topic with none of the old
  // configuration or subscriptions. Existing subscriptions to this topic are
  // not deleted, but their `topic` field is set to `_deleted-topic_`.
  rpc DeleteTopic(DeleteTopicRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { delete: "/v1/{topic=projects/*/topics/*}" };
  }
}

// A topic resource.
message Topic {
  // The name of the topic. It must have the format
  // `"projects/{project}/topics/{topic}"`. `{topic}` must start with a letter,
  // and contain only letters (`[A-Za-z]`), numbers (`[0-9]`), dashes (`-`),
  // underscores (`_`), periods (`.`), tildes (`~`), plus (`+`) or percent
  // signs (`%`). It must be between 3 and 255 characters in length, and it
  // must not start with `"goog"`.
  string name = 1;
}

// A message data and its attributes. The message payload must not be empty;
// it must contain either a non-empty data field, or at least one attribute.
message PubsubMessage {
  // The message payload.
  bytes data = 1;

  // Optional attributes for this message.
  map<string, string> attributes = 2;

  // ID of this message, assigned by the server when the message is published.
  // Guaranteed to be unique within the topic. This value may be read by a
  // subscriber that receives a `PubsubMessage` via a `Pull` call or a push
  // delivery. It must not be populated by the publisher in a `Publish` call.
  string message_id = 3;

  // The time at which the message was published, populated by the server when
  // it receives the `Publish` call. It must not be populated by the
  // publisher in a `Publish` call.
  google.protobuf.Timestamp publish_time = 4;
}

// Request for the GetTopic method.
message GetTopicRequest {
  // The name of the topic to get.
  // Format is `projects/{project}/topics/{topic}`.
  string topic = 1;
}

// Request for the Publish method.
message PublishRequest {
  // The messages in the request will be published on this topic.
  // Format is `projects/{project}/topics/{topic}`.
  string topic = 1;

  // The messages to publish.
  repeated PubsubMessage messages = 2;
}

// Response for the `Publish` method.
message PublishResponse {
  // The server-assigned ID of each published message, in the same order as
  // the messages in the request. IDs are guaranteed to be unique within
  // the topic.
  repeated string message_ids = 1;
}

// Request for the `ListTopics` method.
message ListTopicsRequest {
  // The name of the cloud project that topics belong to.
  // Format is `projects/{project}`.
  string project = 1;

  // Maximum number of topics to return.
  int32 page_size = 2;

  // The value returned by the last `ListTopicsResponse`; indicates that this is
  // a continuation of a prior `ListTopics` call, and that the system should
  // return the next page of data.
  string page_token = 3;
}

// Response for the `ListTopics` method.
message ListTopicsResponse {
  // The resulting topics.
  repeated Topic topics = 1;

  // If not empty, indicates that there may be more topics that match the
  // request; this value should be passed in a new `ListTopicsRequest`.
  string next_page_token = 2;
}

// Request for the `ListTopicSubscriptions` method.
message ListTopicSubscriptionsRequest {
  // The name of the topic that subscriptions are attached to.
  // Format is `projects/{project}/topics/{topic}`.
  string topic = 1;

  // Maximum number of subscription names to return.
  int32 page_size = 2;

  // The value returned by the last `ListTopicSubscriptionsResponse`; indicates
  // that this is a continuation of a prior `ListTopicSubscriptions` call, and
  // that the system should return the next page of data.
  string page_token = 3;
}

// Response for the `ListTopicSubscriptions` method.
message ListTopicSubscriptionsResponse {
  // The names of the subscriptions that match the request.
  repeated string subscriptions = 1;

  // If not empty, indicates that there may be more subscriptions that match
  // the request; this value should be passed in a new
  // `ListTopicSubscriptionsRequest` to get more subscriptions.
  string next_page_token = 2;
}

// Request for the `DeleteTopic` method.
message DeleteTopicRequest {
  // Name of the topic to delete.
  // Format is `projects/{project}/topics/{topic}`.
  string topic = 1;
}

// A subscription resource.
message Subscription {
  // The name of the subscription. It must have the format
  // `"projects/{project}/subscriptions/{subscription}"`. `{subscription}` must
  // start with a letter, and contain only letters (`[A-Za-z]`), numbers
  // (`[0-9]`), dashes (`-`), underscores (`_`), periods (`.`), tildes (`~`),
  // plus (`+`) or percent signs (`%`). It must be between 3 and 255 characters
  // in length, and it must not start with `"goog"`.
  string name = 1;

  // The name of the topic from which this subscription is receiving messages.
  // Format is `projects/{project}/topics/{topic}`.
  // The value of this field will be `_deleted-topic_` if the topic has been
  // deleted.
  string topic = 2;

  // If push delivery is used with this subscription, this field is
  // used to configure it. An empty `pushConfig` signifies that the subscriber
  // will pull and ack messages using API methods.
  PushConfig push_config = 4;

  // This value is the maximum time after a subscriber receives a message
  // before the subscriber should acknowledge the message. After message
  // delivery but before the ack deadline expires and before the message is
  // acknowledged, it is an outstanding message and will not be delivered
  // again during that time (on a best-effort basis).
  //
  // For pull subscriptions, this value is used as the initial value for the ack
  // deadline. To override this value for a given message, call
  // `ModifyAckDeadline` with the corresponding `ack_id` if using
  // pull.
  // The minimum custom deadline you can specify is 10 seconds.
  // The maximum custom deadline you can specify is 600 seconds (10 minutes).
  // If this parameter is 0, a default value of 10 seconds is used.
  //
  // For push delivery, this value is also used to set the request timeout for
  // the call to the push endpoint.
  //
  // If the subscriber never acknowledges the message, the Pub/Sub
  // system will eventually redeliver the message.
  int32 ack_deadline_seconds = 5;

  // Indicates whether to retain acknowledged messages. If true, then
  // messages are not expunged from the subscription's backlog, even if they are
  // acknowledged, until they fall out of the `message_retention_duration`
  // window.
  bool retain_acked_messages = 7;

  // How long to retain unacknowledged messages in the subscription's backlog,
  // from the moment a message is published.
  // If `retain_acked_messages` is true, then this also configures the retention
  // of acknowledged messages, and thus configures how far back in time a `Seek`
  // can be done. Defaults to 7 days. Cannot be more than 7 days or less than 10
  // minutes.
  google.protobuf.Duration message_retention_duration = 8;
}

// Configuration for a push delivery endpoint.
message PushConfig {
  // A URL locating the endpoint to which messages should be pushed.
  // For example, a Webhook endpoint might use "https://example.com/push".
  string push_endpoint = 1;

  // Endpoint configuration attributes.
  //
  // Every endpoint has a set of API supported attributes that can be used to
  // control different aspects of the message delivery.
  //
  // The currently supported attribute is `x-goog-version`, which you can
  // use to change the format of the pushed message. This attribute
  // indicates the version of the data expected by the endpoint. This
  // controls the shape of the pushed message (i.e., its fields and metadata).
  // The endpoint version is based on the version of the Pub/Sub API.
  //
  // If not present during the `CreateSubscription` call, it will default to
  // the version of the API used to make such call. If not present during a
  // `ModifyPushConfig` call, its value will not be changed. `GetSubscription`
  // calls will always return a valid version, even if the subscription was
  // created without this attribute.
  //
  // The possible values for this attribute are:
  //
  // * `v1beta1`: uses the push format defined in the v1beta1 Pub/Sub API.
  // * `v1` or `v1beta2`: uses the push format defined in the v1 Pub/Sub API.
  map<string, string> attributes = 2;
}

// A message and its corresponding acknowledgment ID.
message ReceivedMessage {
  // This ID can be used to acknowledge the received message.
  string ack_id = 1;

  // The message.
  PubsubMessage message = 2;
}

// Request for the GetSubscription method.
message GetSubscriptionRequest {
  // The name of the subscription to get.
  // Format is `projects/{project}/subscriptions/{sub}`.
  string subscription = 1;
}

// Request for the UpdateSubscription method.
message UpdateSubscriptionRequest {
  // The updated subscription object.
  Subscription subscription = 1;

  // Indicates which fields in the provided subscription to update.
  // Must be specified and non-empty.
  google.protobuf.FieldMask update_mask = 2;
}

// Request for the `ListSubscriptions` method.
message ListSubscriptionsRequest {
  // The name of the cloud project that subscriptions belong to.
  // Format is `projects/{project}`.
  string project = 1;

  // Maximum number of subscriptions to return.
  int32 page_size = 2;

  // The value returned by the last `ListSubscriptionsResponse`; indicates that
  // this is a continuation of a prior `ListSubscriptions` call, and that the
  // system should return the next page of data.
  string page_token = 3;
}

// Response for the `ListSubscriptions` method.
message ListSubscriptionsResponse {
  // The subscriptions that match the request.
  repeated Subscription subscriptions = 1;

  // If not empty, indicates that there may be more subscriptions that match
  // the request; this value should be passed in a new
  // `ListSubscriptionsRequest` to get more subscriptions.
  string next_page_token = 2;
}

// Request for the DeleteSubscription method.
message DeleteSubscriptionRequest {
  // The subscription to delete.
  // Format is `projects/{project}/subscriptions/{sub}`.
  string subscription = 1;
}

// Request for the ModifyPushConfig method.
message ModifyPushConfigRequest {
  // The name of the subscription.
  // Format is `projects/{project}/subscriptions/{sub}`.
  string subscription = 1;

  // The push configuration for future deliveries.
  //
  // An empty `pushConfig` indicates that the Pub/Sub system should
  // stop pushing messages from the given subscription and allow
  // messages to be pulled and acknowledged - effectively pausing
  // the subscription if `Pull` is not called.
  PushConfig push_config = 2;
}

// Request for the `Pull` method.
message PullRequest {
  // The subscription from which messages should be pulled.
  // Format is `projects/{project}/subscriptions/{sub}`.
  string subscription = 1;

  // If this field set to true, the system will respond immediately even if
  // it there are no messages available to return in the `Pull` response.
  // Otherwise, the system may wait (for a bounded amount of time) until at
  // least one message is available, rather than returning no messages. The
  // client may cancel the request if it does not wish to wait any longer for
  // the response.
  bool return_immediately = 2;

  // The maximum number of messages returned for this request. The Pub/Sub
  // system may return fewer than the number specified.
  int32 max_messages = 3;
}

// Response for the `Pull` method.
message PullResponse {
  // Received Pub/Sub messages. The Pub/Sub system will return zero messages if
  // there are no more available in the backlog. The Pub/Sub system may return
  // fewer than the `maxMessages` requested even if there are more messages
  // available in the backlog.
  repeated ReceivedMessage received_messages = 1;
}

// Request for the ModifyAckDeadline method.
message ModifyAckDeadlineRequest {
  // The name of the subscription.
  // Format is `projects/{project}/subscriptions/{sub}`.
  string subscription = 1;

  // List of acknowledgment IDs.
  repeated string ack_ids = 4;

  // The new ack deadline with respect to the time this request was sent to
  // the Pub/Sub system. For example, if the value is 10, the new
  // ack deadline will expire 10 seconds after the `ModifyAckDeadline` call
  // was made. Specifying zero may immediately make the message available for
  // another pull request.
  // The minimum deadline you can specify is 0 seconds.
  // The maximum deadline you can specify is 600 seconds (10 minutes).
  int32 ack_deadline_seconds = 3;
}

// Request for the Acknowledge method.
message AcknowledgeRequest {
  // The subscription whose message is being acknowledged.
  // Format is `projects/{project}/subscriptions/{sub}`.
  string subscription = 1;

  // The acknowledgment ID for the messages being acknowledged that was returned
  // by the Pub/Sub system in the `Pull` response. Must not be empty.
  repeated string ack_ids = 2;
}

// Request for the `StreamingPull` streaming RPC method. This request is used to
// establish the initial stream as well as to stream acknowledgements and ack
// deadline modifications from the client to the server.
message StreamingPullRequest {
  // The subscription for which to initialize the new stream. This must be
  // provided in the first request on the stream, and must not be set in
  // subsequent requests from client to server.
  // Format is `projects/{project}/subscriptions/{sub}`.
  string subscription = 1;

  // List of acknowledgement IDs for acknowledging previously received messages
  // (received on this stream or a different stream). If an ack ID has expired,
  // the corresponding message may be redelivered later. Acknowledging a message
  // more than once will not result in an error. If the acknowledgement ID is
  // malformed, the stream will be aborted with status `INVALID_ARGUMENT`.
  repeated string ack_ids = 2;

  // The list of new ack deadlines for the IDs listed in
  // `modify_deadline_ack_ids`. The size of this list must be the same as the
  // size of `modify_deadline_ack_ids`. If it differs the stream will be aborted
  // with `INVALID_ARGUMENT`. Each element in this list is applied to the
  // element in the same position in `modify_deadline_ack_ids`. The new ack
  // deadline is with respect to the time this request was sent to the Pub/Sub
  // system. Must be >= 0. For example, if the value is 10, the new ack deadline
  // will expire 10 seconds after this request is received. If the value is 0,
  // the message is immediately made available for another streaming or
  // non-streaming pull request. If the value is < 0 (an error), the stream will
  // be aborted with status `INVALID_ARGUMENT`.
  repeated int32 modify_deadline_seconds = 3;

  // List of acknowledgement IDs whose deadline will be modified based on the
  // corresponding element in `modify_deadline_seconds`. This field can be used
  // to indicate that more time is needed to process a message by the
  // subscriber, or to make the message available for redelivery if the
  // processing was interrupted.
  repeated string modify_deadline_ack_ids = 4;

  // The ack deadline to use for the stream. This must be provided in the
  // first request on the stream, but it can also be updated on subsequent
  // requests from client to server. The minimum deadline you can specify is 10
  // seconds. The maximum deadline you can specify is 600 seconds (10 minutes).
  int32 stream_ack_deadline_seconds = 5;
}

// Response for the `StreamingPull` method. This response is used to stream
// messages from the server to the client.
message StreamingPullResponse {
  // Received Pub/Sub messages. This will not be empty.
  repeated ReceivedMessage received_messages = 1;
}

// Request for the `CreateSnapshot` method.
message CreateSnapshotRequest {
  // Optional user-provided name for this snapshot.
  // If the name is not provided in the request, the server will assign a random
  // name for this snapshot on the same project as the subscription.
  // Note that for REST API requests, you must specify a name.
  // Format is `projects/{project}/snapshots/{snap}`.
  string name = 1;

  // The subscription whose backlog the snapshot retains.
  // Specifically, the created snapshot is guaranteed to retain:
  //  (a) The existing backlog on the subscription. More precisely, this is
  //      defined as the messages in the subscription's backlog that are
  //      unacknowledged upon the successful completion of the
  //      `CreateSnapshot` request; as well as:
  //  (b) Any messages published to the subscription's topic following the
  //      successful completion of the CreateSnapshot request.
  // Format is `projects/{project}/subscriptions/{sub}`.
  string subscription = 2;
}

// A snapshot resource.
message Snapshot {
  // The name of the snapshot.
  string name = 1;

  // The name of the topic from which this snapshot is retaining messages.
  string topic = 2;

  // The snapshot is guaranteed to exist up until this time.
  // A newly-created snapshot expires no later than 7 days from the time of its
  // creation. Its exact lifetime is determined at creation by the existing
  // backlog in the source subscription. Specifically, the lifetime of the
  // snapshot is `7 days - (age of oldest unacked message in the subscription)`.
  // For example, consider a subscription whose oldest unacked message is 3 days
  // old. If a snapshot is created from this subscription, the snapshot -- which
  // will always capture this 3-day-old backlog as long as the snapshot
  // exists -- will expire in 4 days.
  google.protobuf.Timestamp expire_time = 3;
}

// Request for the `ListSnapshots` method.
message ListSnapshotsRequest {
  // The name of the cloud project that snapshots belong to.
  // Format is `projects/{project}`.
  string project = 1;

  // Maximum number of snapshots to return.
  int32 page_size = 2;

  // The value returned by the last `ListSnapshotsResponse`; indicates that this
  // is a continuation of a prior `ListSnapshots` call, and that the system
  // should return the next page of data.
  string page_token = 3;
}

// Response for the `ListSnapshots` method.
message ListSnapshotsResponse {
  // The resulting snapshots.
  repeated Snapshot snapshots = 1;

  // If not empty, indicates that there may be more snapshot that match the
  // request; this value should be passed in a new `ListSnapshotsRequest`.
  string next_page_token = 2;
}

// Request for the `DeleteSnapshot` method.
message DeleteSnapshotRequest {
  // The name of the snapshot to delete.
  // Format is `projects/{project}/snapshots/{snap}`.
  string snapshot = 1;
}

// Request for the `Seek` method.
message SeekRequest {
  // The subscription to affect.
  string subscription = 1;

  oneof target {
    // The time to seek to.
    // Messages retained in the subscription that were published before this
    // time are marked as acknowledged, and messages retained in the
    // subscription that were published after this time are marked as
    // unacknowledged. Note that this operation affects only those messages
    // retained in the subscription (configured by the combination of
    // `message_retention_duration` and `retain_acked_messages`). For example,
    // if `time` corresponds to a point before the message retention
    // window (or to a point before the system's notion of the subscription
    // creation time), only retained messages will be marked as unacknowledged,
    // and already-expunged messages will not be restored.
    google.protobuf.Timestamp time = 2;

    // The snapshot to seek to. The snapshot's topic must be the same as that of
    // the provided subscription.
    // Format is `projects/{project}/snapshots/{snap}`.
    string snapshot = 3;
  }
}

message SeekResponse {

}
