// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
syntax = "proto2";

package grpc.testing;

message Empty {}

// The type of payload that should be returned.
enum PayloadType {
  // Compressable text format.
  COMPRESSABLE = 0;

  // Uncompressable binary format.
  UNCOMPRESSABLE = 1;

  // Randomly chosen from all other formats defined in this enum.
  RANDOM = 2;
}

// A block of data, to simply increase gRPC message size.
message Payload {
  // The type of data in body.
  optional PayloadType type = 1;
  // Primary contents of payload.
  optional bytes body = 2;
}

// Unary request.
message SimpleRequest {
  // Desired payload type in the response from the server.
  // If response_type is RANDOM, server randomly chooses one from other formats.
  optional PayloadType response_type = 1;

  // Desired payload size in the response from the server.
  // If response_type is COMPRESSABLE, this denotes the size before compression.
  optional int32 response_size = 2;

  // Optional input payload sent along with the request.
  optional Payload payload = 3;

  // Whether SimpleResponse should include username.
  optional bool fill_username = 4;

  // Whether SimpleResponse should include OAuth scope.
  optional bool fill_oauth_scope = 5;
}

// Unary response, as configured by the request.
message SimpleResponse {
  // Payload to increase message size.
  optional Payload payload = 1;

  // The user the request came from, for verifying authentication was
  // successful when the client expected it.
  optional string username = 2;
  
  // OAuth scope.
  optional string oauth_scope = 3;
}

// Client-streaming request.
message StreamingInputCallRequest {
  // Optional input payload sent along with the request.
  optional Payload payload = 1;

  // Not expecting any payload from the response.
}

// Client-streaming response.
message StreamingInputCallResponse {
  // Aggregated size of payloads received from the client.
  optional int32 aggregated_payload_size = 1;
}

// Configuration for a particular response.
message ResponseParameters {
  // Desired payload sizes in responses from the server.
  // If response_type is COMPRESSABLE, this denotes the size before compression.
  optional int32 size = 1;

  // Desired interval between consecutive responses in the response stream in
  // microseconds.
  optional int32 interval_us = 2;
}

// Server-streaming request.
message StreamingOutputCallRequest {
  // Desired payload type in the response from the server.
  // If response_type is RANDOM, the payload from each response in the stream
  // might be of different types. This is to simulate a mixed type of payload
  // stream.
  optional PayloadType response_type = 1;

  // Configuration for each expected response message.
  repeated ResponseParameters response_parameters = 2;

  // Optional input payload sent along with the request.
  optional Payload payload = 3;
}

// Server-streaming response, as configured by the request and parameters.
message StreamingOutputCallResponse {
  // Payload to increase response size.
  optional Payload payload = 1;
}

// A simple service to test the various types of RPCs and experiment with
// performance with various types of payload.
service TestService {
  // One empty request followed by one empty response.
  rpc EmptyCall(Empty) returns (Empty);

  // One request followed by one response.
  // The server returns the client payload as-is.
  rpc UnaryCall(SimpleRequest) returns (SimpleResponse);

  // One request followed by a sequence of responses (streamed download).
  // The server returns the payload with client desired type and sizes.
  rpc StreamingOutputCall(StreamingOutputCallRequest)
      returns (stream StreamingOutputCallResponse);

  // A sequence of requests followed by one response (streamed upload).
  // The server returns the aggregated size of client payload as the result.
  rpc StreamingInputCall(stream StreamingInputCallRequest)
      returns (StreamingInputCallResponse);

  // A sequence of requests with each request served by the server immediately.
  // As one request could lead to multiple responses, this interface
  // demonstrates the idea of full duplexing.
  rpc FullDuplexCall(stream StreamingOutputCallRequest)
      returns (stream StreamingOutputCallResponse);

  // A sequence of requests followed by a sequence of responses.
  // The server buffers all the client requests and then serves them in order. A
  // stream of responses are returned to the client when the server starts with
  // first request.
  rpc HalfDuplexCall(stream StreamingOutputCallRequest)
      returns (stream StreamingOutputCallResponse);
}
