// Copyright 2018 Google LLC.
//
// 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.devtools.build.v1;

import "google/api/annotations.proto";
import "google/devtools/build/v1/build_events.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/empty.proto";

option cc_enable_arenas = true;
option go_package = "google.golang.org/genproto/googleapis/devtools/build/v1;build";
option java_multiple_files = true;
option java_outer_classname = "BackendProto";
option java_package = "com.google.devtools.build.v1";


// A service for publishing BuildEvents. BuildEvents are generated by Build
// Systems to record actions taken during a Build. Events occur in streams,
// are identified by a StreamId, and ordered by sequence number in a stream.
//
// A Build may contain several streams of BuildEvents, depending on the systems
// that are involved in the Build. Some BuildEvents are used to declare the
// beginning and end of major portions of a Build; these are called
// LifecycleEvents, and are used (for example) to indicate the beginning or end
// of a Build, and the beginning or end of an Invocation attempt (there can be
// more than 1 Invocation in a Build if, for example, a failure occurs somewhere
// and it needs to be retried).
//
// Other, build-tool events represent actions taken by the Build tool, such as
// target objects produced via compilation, tests run, et cetera. There could be
// more than one build tool stream for an invocation attempt of a build.
service PublishBuildEvent {
  // Publish a build event stating the new state of a build (typically from the
  // build queue). The BuildEnqueued event must be publishd before all other
  // events for the same build ID.
  //
  // The backend will persist the event and deliver it to registered frontend
  // jobs immediately without batching.
  //
  // The commit status of the request is reported by the RPC's util_status()
  // function. The error code is the canoncial error code defined in
  // //util/task/codes.proto.
  rpc PublishLifecycleEvent(PublishLifecycleEventRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/v1/projects/{project_id=*}/lifecycleEvents:publish"
      body: "*"
      additional_bindings { post: "/v1/lifecycleEvents:publish" body: "*" }
    };
  }

  // Publish build tool events belonging to the same stream to a backend job
  // using bidirectional streaming.
  rpc PublishBuildToolEventStream(stream PublishBuildToolEventStreamRequest)
      returns (stream PublishBuildToolEventStreamResponse) {
    option (google.api.http) = {
      post: "/v1/projects/{project_id=*}/events:publish"
      body: "*"
      additional_bindings { post: "/v1/events:publish" body: "*" }
    };
  }
}

// Publishes 'lifecycle events' that update the high-level state of a build:
// - BuildEnqueued: When a build is scheduled.
// - InvocationAttemptStarted: When work for a build starts; there can be
//     multiple invocations for a build (e.g. retries).
// - InvocationAttemptCompleted: When work for a build finishes.
// - BuildFinished: When a build is finished.
message PublishLifecycleEventRequest {
  // The service level of the build request. Backends only uses this value when
  // the BuildEnqueued event is published to determine what level of service
  // this build should receive.
  enum ServiceLevel {
    // Non-interactive builds can tolerate longer event latencies. This is the
    // default ServiceLevel if callers do not specify one.
    NONINTERACTIVE = 0;

    // The events of an interactive build should be delivered with low latency.
    INTERACTIVE = 1;
  }

  // The interactivity of this build.
  ServiceLevel service_level = 1;

  // The lifecycle build event. If this is a build tool event, the RPC will fail
  // with INVALID_REQUEST.
  OrderedBuildEvent build_event = 2;

  // If the next event for this build or invocation (depending on the event
  // type) hasn't been published after this duration from when {build_event}
  // is written to BES, consider this stream expired. If this field is not set,
  // BES backend will use its own default value.
  google.protobuf.Duration stream_timeout = 3;

  // Additional information about a build request. These are define by the event
  // publishers, and the Build Event Service does not validate or interpret
  // them. They are used while notifying internal systems of new builds and
  // invocations if the OrderedBuildEvent.event type is
  // BuildEnqueued/InvocationAttemptStarted.
  repeated string notification_keywords = 4;

  // The project this build is associated with.
  // This should match the project used for the initial call to
  // PublishLifecycleEvent (containing a BuildEnqueued message).
  string project_id = 6;
}

// States which event has been committed. Any failure to commit will cause
// RPC errors, hence not recorded by this proto.
message PublishBuildToolEventStreamResponse {
  // The stream that contains this event.
  StreamId stream_id = 1;

  // The sequence number of this event that has been committed.
  int64 sequence_number = 2;
}

// Build event with contextual information about the stream it belongs to and
// its position in that stream.
message OrderedBuildEvent {
  // Which build event stream this event belongs to.
  StreamId stream_id = 1;

  // The position of this event in the stream. The sequence numbers for a build
  // event stream should be a sequence of consecutive natural numbers starting
  // from one. (1, 2, 3, ...)
  int64 sequence_number = 2;

  // The actual event.
  BuildEvent event = 3;
}

// Streaming request message for PublishBuildToolEventStream.
message PublishBuildToolEventStreamRequest {
  // The build event with position info.
  // New publishing clients should use this field rather than the 3 above.
  OrderedBuildEvent ordered_build_event = 4;

  // The keywords to be attached to the notification which notifies the start
  // of a new build event stream. BES only reads this field when sequence_number
  // or ordered_build_event.sequence_number is 1 in this message. If this field
  // is empty, BES will not publish notification messages for this stream.
  repeated string notification_keywords = 5;

  // The project this build is associated with.
  // This should match the project used for the initial call to
  // PublishLifecycleEvent (containing a BuildEnqueued message).
  string project_id = 6;
}
