Project import generated by Copybara.

GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/api/v3/api_proto/issues.proto b/api/v3/api_proto/issues.proto
new file mode 100644
index 0000000..988f958
--- /dev/null
+++ b/api/v3/api_proto/issues.proto
@@ -0,0 +1,461 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+syntax = "proto3";
+
+package monorail.v3;
+
+option go_package = "api/v3/api_proto";
+
+import "google/protobuf/field_mask.proto";
+import "google/api/field_behavior.proto";
+import "google/api/resource.proto";
+import "api/v3/api_proto/issue_objects.proto";
+
+// ***ONLY CALL rpcs WITH `status: {ALPHA|STABLE}`***
+// rpcs without `status` are not ready.
+
+// Issues service includes all methods needed for managing Issues.
+service Issues {
+  // status: ALPHA
+  // Returns the requested Issue.
+  //
+  // Raises:
+  //   INVALID_ARGUMENT if `name` is formatted incorrectly.
+  //   NOT_FOUND if the issue does not exist.
+  //   PERMISSION_DENIED if the requester is not allowed to view the issue.
+  rpc GetIssue (GetIssueRequest) returns (Issue) {}
+
+  // status: ALPHA
+  // Returns the requested Issues.
+  //
+  // Raises:
+  //   INVALID_ARGUMENT if `names` is formatted incorrectly. Or if a parent
+  //       collection in `names` does not match the value in `parent`.
+  //   NOT_FOUND if any of the given issues do not exist.
+  //   PERMISSION_DENIED if the requester does not have permission to view one
+  //       (or more) of the given issues.
+  rpc BatchGetIssues(BatchGetIssuesRequest) returns (BatchGetIssuesResponse) {}
+
+  // status: ALPHA
+  // Searches over issues within the specified projects.
+  //
+  // Raises:
+  //   INVALID_ARGUMENT if project names or search query are invalid.
+  rpc SearchIssues (SearchIssuesRequest) returns (SearchIssuesResponse) {}
+
+  // status: ALPHA
+  // Lists comments for an issue.
+  //
+  // Raises:
+  //   INVALID_ARGUMENT if `parent` is formatted incorrectly or `page_size` < 0.
+  //   NOT_FOUND if `parent` does not exist.
+  //   PERMISSION_DENIED if the requester is not allowed to view `parent`.
+  rpc ListComments (ListCommentsRequest) returns (ListCommentsResponse) {}
+
+  // status: ALPHA
+  // Modifies Issues and creates a new Comment for each.
+  // Issues with NOOP changes and no comment_content will not be updated
+  // and will not be included in the response.
+  // We do not offer a standard UpdateIssue because every issue change
+  // must result in the side-effect of creating a new Comment, and may result in
+  // the side effect of sending a notification. We also want to allow for any
+  // combination of issue changes to be made at once in a monolithic method.
+  //
+  // Raises:
+  //   INVALID_ARGUMENT required fields are missing or fields are formatted
+  //     incorrectly.
+  //   NOT_FOUND if any specified issues are not found.
+  //   PERMISSION_DENIED if the requester is not allowed to make the
+  //     requested change.
+  rpc ModifyIssues (ModifyIssuesRequest) returns (ModifyIssuesResponse) {}
+
+  // status: ALPHA
+  // Modifies ApprovalValues and creates a new Comment for each delta.
+  // We do not offer a standard UpdateApprovalValue because changes result
+  // in creating Comments on the parent Issue, and may have the side effect of
+  // sending notifications. We also want to allow for any combination of
+  // approval changes to be made at once in a monolithic method.
+  // To modify owner add 'owner' to update_mask, though 'owner.user' works too.
+  //
+  // Raises:
+  //   INVALID_ARGUMENT required fields are missing or fields are formatted
+  //     incorrectly.
+  //   NOT_FOUND if any specified ApprovalValues are not found.
+  //   PERMISSION_DENIED if the requester is not allowed to make any of the
+  //     requested changes.
+  rpc ModifyIssueApprovalValues (ModifyIssueApprovalValuesRequest) returns
+      (ModifyIssueApprovalValuesResponse) {}
+
+  // status: ALPHA
+  // Lists approval values for an issue.
+  //
+  // Raises:
+  //   INVALID_ARGUMENT if request `parent` is formatted incorrectly.
+  //   NOT_FOUND if the parent issue does not exist.
+  //   PERMISSION_DENIED if the requester is not allowed to view parent issue.
+  rpc ListApprovalValues (ListApprovalValuesRequest) returns
+      (ListApprovalValuesResponse) {}
+
+  // status: NOT READY
+  // Changes state for a comment. Supported state transitions:
+  //   - ACTIVE -> DELETED
+  //   - ACTIVE -> SPAM
+  //   - DELETED -> ACTIVE
+  //   - SPAM -> ACTIVE
+  //
+  // Raises:
+  //   TODO(crbug/monorail/7867): Document errors when implemented
+  rpc ModifyCommentState (ModifyCommentStateRequest) returns
+      (ModifyCommentStateResponse) {}
+
+  // status: NOT READY
+  // Makes an issue from an IssueTemplate and deltas.
+  //
+  // Raises:
+  //   TODO(crbug/monorail/7197): Document errors when implemented
+  rpc MakeIssueFromTemplate (MakeIssueFromTemplateRequest) returns (Issue) {}
+
+  // status: ALPHA
+  // Makes a basic issue, does not support phases, approvals, or approval
+  // fields.
+  // We do not offer a standard CreateIssue because Issue descriptions are
+  // required, but not included in the Issue proto.
+  //
+  // Raises:
+  //   INVALID_ARGUMENT if any given names does not have a valid format, if any
+  //     fields in the requested issue were invalid, or if proposed values
+  //     violates filter rules that should error.
+  //   NOT_FOUND if no project exists with the given name.
+  //   PERMISSION_DENIED if user lacks sufficient permissions.
+  rpc MakeIssue (MakeIssueRequest) returns (Issue) {}
+}
+
+
+// The request message for Issues.GetIssue.
+// Next available tag: 2
+message GetIssueRequest {
+  // The name of the issue to request.
+  string name = 1 [
+      (google.api.resource_reference) = {type: "api.crbug.com/Issue"},
+      (google.api.field_behavior) = REQUIRED ];
+}
+
+// The request message for Issues.BatchGetIssues.
+// Next available tag: 3
+message BatchGetIssuesRequest {
+  // The project name from which to batch get issues. If included, the parent
+  // of all the issues specified in `names` must match this field.
+  string parent = 1 [
+    (google.api.resource_reference) = {type: "api.crbug.com/Project"} ];
+  // The issues to request. Maximum of 100 can be retrieved.
+  repeated string names = 2 [
+      (google.api.resource_reference) = {type: "api.crbug.com/Issue"} ];
+}
+
+// The response message for Issues.BatchGetIssues.
+// Next available tag: 2
+message BatchGetIssuesResponse {
+  // Issues matching the given request.
+  repeated Issue issues = 1;
+}
+
+// The request message for Issues.SearchIssues.
+// Next available tag: 6
+message SearchIssuesRequest {
+  // The names of Projects in which to search issues.
+  repeated string projects = 1 [
+    (google.api.resource_reference) = {type: "api.crbug.com/Project"},
+    (google.api.field_behavior) = REQUIRED ];
+  // The query string can contain any number of free text and
+  // field search expressions.
+  // Please see https://bugs.chromium.org/p/chromium/issues/searchtips for more
+  // details of how the query string works.
+  //
+  // Canned queries have been deprecated in v3 in favor of search scoping using
+  // parentheses support.
+  // For clients who previously used canned queries, we're providing the
+  // mapping of legacy canned query IDs to Monorail search syntax:
+  //   - Format: (can_id, description, query_string)
+  //   - (1, 'All issues', '')
+  //   - (2, 'Open issues', 'is:open')
+  //   - (3, 'Open and owned by me', 'is:open owner:me')
+  //   - (4, 'Open and reported by me', 'is:open reporter:me')
+  //   - (5, 'Open and starred by me', 'is:open is:starred')
+  //   - (6, 'New issues', 'status:new')
+  //   - (7, 'Issues to verify', 'status=fixed,done')
+  //   - (8, 'Open with comment by me', 'is:open commentby:me')
+  string query = 2;
+  // The maximum number of items to return. The service may return fewer than
+  // this value.
+  // If unspecified, at most 100 items will be returned.
+  // The maximum value is 100; values above 100 will be coerced to 100.
+  int32 page_size = 3;
+  // A page token, received from a previous `SearchIssues` call.
+  // Provide this to retrieve the subsequent page.
+  //
+  // When paginating, all other parameters provided to `SearchIssues` must match
+  // the call that provided the page token.
+  string page_token = 4;
+  // The string of comma separated field names used to order the items.
+  // Adding '-' before a field, reverses the sort order.
+  // E.g. 'stars,-status' sorts the items by number of stars, high to low,
+  // then by status, low to high.
+  string order_by = 5;
+}
+
+// The response message for Issues.SearchIssues.
+// Next available tag: 3
+message SearchIssuesResponse {
+  // Issues matching the given request.
+  repeated Issue issues = 1;
+  // A token, which can be sent as `page_token` to retrieve the next page.
+  // If this field is omitted, there are no subsequent pages.
+  string next_page_token = 2;
+}
+
+// The request message for Issues.ListComments.
+// Next available tag: 5
+message ListCommentsRequest {
+  // The name of the issue for which to list comments.
+  string parent = 1 [
+    (google.api.resource_reference) = {type: "api.crbug.com/Issue"},
+    (google.api.field_behavior) = REQUIRED ];
+  // The maximum number of items to return. The service may return fewer than
+  // this value.
+  // If unspecified, at most 100 items will be returned.
+  // The maximum value is 100; values above 100 will be coerced to 100.
+  int32 page_size = 2;
+  // A page token, received from a previous `ListComments` call.
+  // Provide this to retrieve the subsequent page.
+  //
+  // When paginating, all other parameters provided to `ListComments` must
+  // match the call that provided the page token.
+  string page_token = 3;
+  // For our initial release this filter only supports filtering to comments
+  // related to a specific approval.
+  // For example `approval = "projects/monorail/approvalDefs/1"`,
+  // Note that no further logical or comparison operators are supported
+  string filter = 4;
+}
+
+// The response message for Issues.ListComments
+// Next available tag: 3
+message ListCommentsResponse {
+  // The comments from the specified issue.
+  repeated Comment comments = 1;
+  // A token, which can be sent as `page_token` to retrieve the next page.
+  // If this field is omitted, there are no subsequent pages.
+  string next_page_token = 2;
+}
+
+// An attachment to upload to a comment or description.
+// Next available tag: 3
+message AttachmentUpload {
+  string filename = 1 [ (google.api.field_behavior) = REQUIRED ];
+  bytes content = 2 [ (google.api.field_behavior) = REQUIRED ];
+}
+
+// Holds changes to one issue, used in ModifyIssuesRequest.
+// Next available tag: 9
+message IssueDelta {
+  // The issue's `name` field is used to identify the issue to be
+  // updated. `issue.name` must always be filled.
+  //
+  // Values with rule-based Derivation within `issue` and in `field_vals_remove`
+  // will be ignored.
+  Issue issue = 1 [
+      (google.api.field_behavior) = REQUIRED ];
+  // The list of fields in `issue` to be updated.
+  //
+  // Repeated fields set on `issue` will be appended to.
+  //
+  // Non-repeated fields (e.g. `owner`) can be set with `issue.owner` set and
+  // either 'owner' or 'owner.user' added to `update_mask`.
+  // To unset non-repeated fields back to their default value, `issue.owner`
+  // must contain the default value and `update_mask` must include 'owner.user'
+  // NOT 'owner'.
+  //
+  // Its `field_values`, however, are a special case. Fields can be specified as
+  // single-value or multi-value in their FieldDef.
+  //
+  // Single-value Field: if there is preexisting FieldValue with the same
+  // `field` and `phase`, it will be REPLACED.
+  //
+  // Multi-value Field: a new value will be appended, unless the same `field`,
+  // `phase`, `value` combination already exists. In that case, the FieldValue
+  // will be ignored. In other words, duplicate values are ignored.
+  // (With the exception of crbug.com/monorail/8137 until it is fixed).
+  google.protobuf.FieldMask update_mask = 2 [
+      (google.api.field_behavior) = REQUIRED ];
+
+  // Values to remove from the repeated fields of the issue.
+
+  // Cc's to remove.
+  repeated string ccs_remove = 3 [
+      (google.api.resource_reference) = {type: "api.crbug.com/User"}];
+  // Blocked_on issues to remove.
+  repeated IssueRef blocked_on_issues_remove = 4;
+  // Blocking issues to remove.
+  repeated IssueRef blocking_issues_remove = 5;
+  // Components to remove.
+  repeated string components_remove = 6 [
+      (google.api.resource_reference) = {type: "api.crbug.com/ComponentDef"}];
+  // Labels to remove.
+  repeated string labels_remove = 7;
+  // FieldValues to remove. Any values that did not already exist will be
+  // ignored e.g. if you append a FieldValue in issue and remove it here, it
+  // will still be added.
+  repeated FieldValue field_vals_remove = 8;
+
+  // TODO(crbug.com/monorail/8019): add Attachment uploading and removing.
+}
+
+// Changes to make to an ApprovalValue. Used to ModifyIssueApprovalValues or
+// to MakeIssueFromTemplate.
+//
+// NOTE: The same handling of FieldValues discussed in IssueDelta applies here.
+// Next available tag: 6
+message ApprovalDelta {
+  // The ApprovalValue we want to update. `approval_value.name` must always be
+  // set.
+  ApprovalValue approval_value = 1;
+  // Repeated fields found in `update_mask` will be appended to.
+  google.protobuf.FieldMask update_mask = 2 [
+      (google.api.field_behavior) = REQUIRED ];
+  // Resource names of the approvers we want to remove.
+  repeated string approvers_remove = 3 [
+      (google.api.resource_reference) = { type: "api.crbug.com/User" }
+  ];
+  // FieldValues that do not belong to `approval_value` will trigger error.
+  repeated FieldValue field_vals_remove = 5;
+  // TODO(crbug.com/monorail/8019): add Attachment uploading and removing.
+}
+
+
+// The type of notification a change should trigger.
+// See monorail/doc/userguide/email.md
+// Next available tag: 2
+enum NotifyType {
+  // The default value. This value is unused.
+  NOTIFY_TYPE_UNSPECIFIED = 0;
+  // An email notification should be sent.
+  EMAIL = 1;
+  // No notifcation should be triggered at all.
+  NO_NOTIFICATION = 2;
+}
+
+
+// The request message for Issues.ModifyIssues.
+// Next available tag: 5
+message ModifyIssuesRequest {
+  // The issue changes to make. A maximum of 100 issue changes can be requested.
+  // There is also a constraint of 50 additional 'impacted issues' per
+  // ModifyIssuesRequest. 'Impacted issues' are issues that are adding/removing
+  // `blocked_on`, `blocking`, or `merge`
+  // If you encounter this error, consider significantly smaller batches.
+  repeated IssueDelta deltas = 1;
+  // The type of notification the modifications should trigger.
+  NotifyType notify_type = 2;
+  // The comment text that should be added to each issue in delta.
+  // Max length is 51200 characters.
+  string comment_content = 3;
+  // The attachment that will be to each comment for each issue in delta.
+  repeated AttachmentUpload uploads = 4;
+}
+
+
+// The response message for Issues.ModifyIssues.
+// Next available tag: 2
+message ModifyIssuesResponse {
+  // The updated issues.
+  repeated Issue issues = 1;
+}
+
+// The request message for Issues.ModifyIssueApprovalValues.
+// Next available tag: 4
+message ModifyIssueApprovalValuesRequest {
+  // The ApprovalValue changes to make. Maximum of 100 deltas can be requested.
+  repeated ApprovalDelta deltas = 1;
+  // The type of notification the modifications should trigger.
+  NotifyType notify_type = 2;
+  // The `content` of the Comment created for each change in `deltas`.
+  // Max length is 51200 characters.
+  string comment_content = 3;
+}
+
+// The response message for Issues.ModifyIssueApprovalValuesRequest.
+// Next available tag: 2
+message ModifyIssueApprovalValuesResponse {
+  // The updated ApprovalValues.
+  repeated ApprovalValue approval_values = 1;
+}
+
+// The request message for Issue.ListApprovalValues.
+// Next available tag: 2
+message ListApprovalValuesRequest {
+  // The name of the issue for which to list approval values.
+  string parent = 1 [
+    (google.api.resource_reference) = {type: "api.crbug.com/Issue"},
+    (google.api.field_behavior) = REQUIRED ];
+}
+
+// The response message for Issues.ListApprovalValues.
+// Next available tag: 2
+message ListApprovalValuesResponse {
+  // The approval values from the specified issue.
+  repeated ApprovalValue approval_values = 1;
+}
+
+// The request message for Issues.ModifyCommentState.
+// Next available tag: 3
+message ModifyCommentStateRequest {
+  // Resource name of the comment to modify state.
+  string name = 1 [
+    (google.api.resource_reference) = {type: "api.crbug.com/Comment"},
+    (google.api.field_behavior) = REQUIRED ];
+  // Requested state.
+  IssueContentState state = 2;
+}
+
+// The response message for Issues.ModifyCommentState.
+// Next available tag: 2
+message ModifyCommentStateResponse {
+  // The updated comment after modifying state.
+  Comment comment = 1;
+}
+
+// The request message for MakeIssueFromTemplate.
+// Next available tag: 5
+message MakeIssueFromTemplateRequest {
+  // Resource name of the template to use for filling in default values
+  // and adding approvals and phases.
+  string template = 1 [
+      (google.api.resource_reference) = { type: "api.crbug.com/Template" }
+  ];
+  // The issue differences relative to the `template.issue` default.
+  IssueDelta template_issue_delta = 2;
+  // Changes to fields belonging to approvals relative to template default.
+  // While ApprovalDelta can hold additional information, this method only
+  // allows adding and removing field values, all other deltas will be ignored.
+  repeated ApprovalDelta template_approval_deltas = 3;
+  // The issue description, will be saved as the first comment.
+  string description = 4;
+}
+
+// The request message for MakeIssue.
+// Next available tag: 5
+message MakeIssueRequest {
+  // The name of the project the issue should belong to.
+  string parent = 1 [
+    (google.api.resource_reference) = {type: "api.crbug.com/Project"},
+    (google.api.field_behavior) = REQUIRED ];
+  // The issue to be created.
+  Issue issue = 2;
+  // The issue description.
+  string description = 3;
+  // The type of notification the creation should trigger.
+  NotifyType notify_type = 4;
+}