// Copyright 2017 gRPC authors.
//
// 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.

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

option go_package = "google.golang.org/grpc/test/grpc_testing";

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.
  PayloadType type = 1;
  // Primary contents of payload.
  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.
  PayloadType response_type = 1;

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

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

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

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

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

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

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

  // Not expecting any payload from the response.
}

// Client-streaming response.
message StreamingInputCallResponse {
  // Aggregated size of payloads received from the client.
  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.
  int32 size = 1;

  // Desired interval between consecutive responses in the response stream in
  // microseconds.
  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.
  PayloadType response_type = 1;

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

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

// Server-streaming response, as configured by the request and parameters.
message StreamingOutputCallResponse {
  // Payload to increase response size.
  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);
}
