syntax = "proto3";

package tests.testdata.v1;

option java_multiple_files = true;
option java_outer_classname = "GoldenProto";
option java_package = "tests.testdata.v1";

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";

// TODO: describe this service.
service TestService {
  // Methods for Foos.
  // Creates a new Foo.
  rpc CreateFoo(CreateFooRequest) returns (Foo) {
    option (google.api.http) = {
      post : "/v1/foos"
      body: "foo"
    };
    option (google.api.method_signature) = "foo,foo_id"; 
  }
  // Retrieves a Foo.
  rpc GetFoo(GetFooRequest) returns (Foo) {
    option (google.api.http) = {
      get : "/v1/{name=foos/*}"
    };
    option (google.api.method_signature) = "name"; 
  }
  // Lists Foos.
  rpc ListFoos(ListFoosRequest) returns (ListFoosResponse) {
    option (google.api.http) = {
      get : "/v1/foos"
    };
    option (google.api.method_signature) = ""; 
  }
  // Updates a Foo.
  rpc UpdateFoo(UpdateFooRequest) returns (Foo) {
    option (google.api.http) = {
      patch : "/v1/{foo.name=foos/*}"
      body: "foo"
    };
    option (google.api.method_signature) = "foo,update_mask"; 
  }
  // Deletes a Foo.
  rpc DeleteFoo(DeleteFooRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete : "/v1/{name=foos/*}"
    };
    option (google.api.method_signature) = "name"; 
  }
  
  // Methods for BarBazs.
  // Creates a new BarBaz.
  rpc CreateBarBaz(CreateBarBazRequest) returns (BarBaz) {
    option (google.api.http) = {
      post : "/v1/{parent=foos/*}/barBazs"
      body: "bar_baz"
    };
    option (google.api.method_signature) = "parent,bar_baz,bar_baz_id"; 
  }
  // Retrieves a BarBaz.
  rpc GetBarBaz(GetBarBazRequest) returns (BarBaz) {
    option (google.api.http) = {
      get : "/v1/{name=foos/*/barBazs/*}"
    };
    option (google.api.method_signature) = "name"; 
  }
  // Lists BarBazs.
  rpc ListBarBazs(ListBarBazsRequest) returns (ListBarBazsResponse) {
    option (google.api.http) = {
      get : "/v1/{parent=foos/*}/barBazs"
    };
    option (google.api.method_signature) = "parent"; 
  }
  // Updates a BarBaz.
  rpc UpdateBarBaz(UpdateBarBazRequest) returns (BarBaz) {
    option (google.api.http) = {
      patch : "/v1/{bar_baz.name=foos/*/barBazs/*}"
      body: "bar_baz"
    };
    option (google.api.method_signature) = "bar_baz,update_mask"; 
  }
  // Deletes a BarBaz.
  rpc DeleteBarBaz(DeleteBarBazRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete : "/v1/{name=foos/*/barBazs/*}"
    };
    option (google.api.method_signature) = "name"; 
  }
  
}

//////////////////////////////////////////////////////////
//                                                      //
//                  Resource Types                      //
//                                                      //
//////////////////////////////////////////////////////////
// TODO: Describe the Foo type.
message Foo {
  option (google.api.resource) = {
    type: "foo.bar.com/Foo"
    pattern: "foos/{foo}"
    singular: "foo"
    plural: "foos"
  };

  // The name of the Foo.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];
}

// TODO: Describe the BarBaz type.
message BarBaz {
  option (google.api.resource) = {
    type: "foo.bar.com/BarBaz"
    pattern: "foos/{foo}/barBazs/{bar_baz}"
    singular: "barBaz"
    plural: "barBazs"
  };

  // The name of the BarBaz.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];
}

//////////////////////////////////////////////////////////
//                                                      //
//               Requests & Responses                   //
//                                                      //
//////////////////////////////////////////////////////////
// Request message for retrieving a Foo.
message GetFooRequest {
  // The name of the Foo to retrieve.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "foo.bar.com/Foo"
    }
  ];
}

// Request message for listing Foos.
message ListFoosRequest {
  // The maximum number of Foo to return.
  int32 page_size = 1 [
    (google.api.field_behavior) = OPTIONAL
  ];
  // The page token to use for the next page of results.
  string page_token = 2 [
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Response message for listing Foos.
message ListFoosResponse {
  // The list of Foos in the collection.
  repeated Foo foos = 1;
  // The token to use for the next page of results.
  string next_page_token = 2;
}

// Request message for creating a Foo.
message CreateFooRequest {
  // The ID to use for the Foo being created.
  string foo_id = 1 [
    (google.api.field_behavior) = OPTIONAL
  ];
  // The Foo being created.
  Foo foo = 2 [
    (google.api.field_behavior) = REQUIRED
  ];
}

// Request message for updating a Foo.
message UpdateFooRequest {
  // The Foo being updated.
  Foo foo = 1 [
    (google.api.field_behavior) = REQUIRED
  ];
  // The set of fields to update.
  google.protobuf.FieldMask update_mask = 2 [
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Request message for deleting a Foo.
message DeleteFooRequest {
  // The name of the Foo to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "foo.bar.com/Foo"
    }
  ];
  // If set, deletes the Foo and all of its children.
  bool force = 2 [
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Request message for retrieving a BarBaz.
message GetBarBazRequest {
  // The name of the BarBaz to retrieve.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "foo.bar.com/BarBaz"
    }
  ];
}

// Request message for listing BarBazs.
message ListBarBazsRequest {
  // The parent that owns this collection of BarBaz.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "foo.bar.com/BarBaz"
    }
  ];
  // The maximum number of BarBaz to return.
  int32 page_size = 2 [
    (google.api.field_behavior) = OPTIONAL
  ];
  // The page token to use for the next page of results.
  string page_token = 3 [
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Response message for listing BarBazs.
message ListBarBazsResponse {
  // The list of BarBazs in the collection.
  repeated BarBaz bar_bazs = 1;
  // The token to use for the next page of results.
  string next_page_token = 2;
}

// Request message for creating a BarBaz.
message CreateBarBazRequest {
  // The parent that owns this BarBaz.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "foo.bar.com/BarBaz"
    }
  ];
  // The ID to use for the BarBaz being created.
  string bar_baz_id = 2 [
    (google.api.field_behavior) = OPTIONAL
  ];
  // The BarBaz being created.
  BarBaz bar_baz = 3 [
    (google.api.field_behavior) = REQUIRED
  ];
}

// Request message for updating a BarBaz.
message UpdateBarBazRequest {
  // The BarBaz being updated.
  BarBaz bar_baz = 1 [
    (google.api.field_behavior) = REQUIRED
  ];
  // The set of fields to update.
  google.protobuf.FieldMask update_mask = 2 [
    (google.api.field_behavior) = OPTIONAL
  ];
}

// Request message for deleting a BarBaz.
message DeleteBarBazRequest {
  // The name of the BarBaz to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "foo.bar.com/BarBaz"
    }
  ];
}
