// 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.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). If the event is a BuildEnqueued event, also register the new
  // build request ID and its build type to BES.
  //
  // 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/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/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;

  // This field identifies which project (if any) the build is associated with.
  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;
}

message PublishBuildToolEventStreamRequest {
  // The fist 3 fields are identical to OrderedBuildEvent so we can have wire-
  // compatibility when migrating BES publishers.

  // Which build event stream this event belongs to.
  google.devtools.build.v1.StreamId stream_id = 1 [deprecated = true];

  // 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 [deprecated = true];

  // The actual event.
  google.devtools.build.v1.BuildEvent event = 3 [deprecated = true];

  // 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;
}
