spanner: annotate spanner, database & instance protos
diff --git a/google/spanner/admin/database/v1/spanner_admin_database_gapic_v2.yaml b/google/spanner/admin/database/v1/spanner_admin_database_gapic_v2.yaml
new file mode 100644
index 0000000..f3f450a
--- /dev/null
+++ b/google/spanner/admin/database/v1/spanner_admin_database_gapic_v2.yaml
@@ -0,0 +1,92 @@
+type: com.google.api.codegen.ConfigProto
+config_schema_version: 1.0.0
+language_settings:
+  java:
+    package_name: com.google.cloud.spanner.admin.database.v1
+  python:
+    package_name: google.cloud.spanner_admin_database_v1.gapic
+  go:
+    package_name: cloud.google.com/go/spanner/admin/database/apiv1
+  csharp:
+    package_name: Google.Cloud.Spanner.Admin.Database.V1
+  ruby:
+    package_name: Google::Cloud::Spanner::Admin::Database::V1
+  php:
+    package_name: Google\Cloud\Spanner\Admin\Database\V1
+  nodejs:
+    package_name: spanner.v1
+    domain_layer_location: google-cloud
+interfaces:
+- name: google.spanner.admin.database.v1.DatabaseAdmin
+  collections:
+  - entity_name: instance
+    language_overrides:
+    - language: csharp
+      common_resource_name: Google.Cloud.Spanner.Common.V1.InstanceName
+  - entity_name: database
+    language_overrides:
+    - language: csharp
+      common_resource_name: Google.Cloud.Spanner.Common.V1.DatabaseName
+  retry_codes_def:
+  - name: idempotent
+    retry_codes:
+    - UNAVAILABLE
+    - DEADLINE_EXCEEDED
+  - name: non_idempotent
+    retry_codes: []
+  retry_params_def:
+  - name: default
+    initial_retry_delay_millis: 1000
+    retry_delay_multiplier: 1.3
+    max_retry_delay_millis: 32000
+    initial_rpc_timeout_millis: 60000
+    rpc_timeout_multiplier: 1
+    max_rpc_timeout_millis: 60000
+    total_timeout_millis: 600000
+  methods:
+  - name: ListDatabases
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: CreateDatabase
+    retry_codes_name: non_idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+    long_running:
+      initial_poll_delay_millis: 20000
+      poll_delay_multiplier: 1.5
+      max_poll_delay_millis: 45000
+      total_poll_timeout_millis: 86400000
+  - name: GetDatabase
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: UpdateDatabaseDdl
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+    long_running:
+      initial_poll_delay_millis: 20000
+      poll_delay_multiplier: 1.5
+      max_poll_delay_millis: 45000
+      total_poll_timeout_millis: 86400000
+  - name: DropDatabase
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: GetDatabaseDdl
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: SetIamPolicy
+    retry_codes_name: non_idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: GetIamPolicy
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: TestIamPermissions
+    retry_codes_name: non_idempotent
+    retry_params_name: default
+    timeout_millis: 30000
diff --git a/google/spanner/admin/database/v1/spanner_database_admin.proto b/google/spanner/admin/database/v1/spanner_database_admin.proto
index 491606e..30e8a75 100644
--- a/google/spanner/admin/database/v1/spanner_database_admin.proto
+++ b/google/spanner/admin/database/v1/spanner_database_admin.proto
@@ -17,6 +17,9 @@
 package google.spanner.admin.database.v1;
 
 import "google/api/annotations.proto";
+import "google/api/client.proto";
+import "google/api/field_behavior.proto";
+import "google/api/resource.proto";
 import "google/iam/v1/iam_policy.proto";
 import "google/iam/v1/policy.proto";
 import "google/longrunning/operations.proto";
@@ -36,11 +39,16 @@
 // list databases. It also enables updating the schema of pre-existing
 // databases.
 service DatabaseAdmin {
+  option (google.api.default_host) = "spanner.googleapis.com";
+  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/spanner.admin,"
+  "https://www.googleapis.com/auth/cloud-platform";
+
   // Lists Cloud Spanner databases.
   rpc ListDatabases(ListDatabasesRequest) returns (ListDatabasesResponse) {
     option (google.api.http) = {
       get: "/v1/{parent=projects/*/instances/*}/databases"
     };
+    option (google.api.method_signature) = "parent";
   }
 
   // Creates a new Cloud Spanner database and starts to prepare it for serving.
@@ -57,6 +65,11 @@
       post: "/v1/{parent=projects/*/instances/*}/databases"
       body: "*"
     };
+    option (google.longrunning.operation_info) = {
+      response_type: "google.spanner.admin.database.v1.Database"
+      metadata_type: "google.spanner.admin.database.v1.CreateDatabaseMetadata"
+    };
+    option (google.api.method_signature) = "parent,create_statement";
   }
 
   // Gets the state of a Cloud Spanner database.
@@ -64,6 +77,7 @@
     option (google.api.http) = {
       get: "/v1/{name=projects/*/instances/*/databases/*}"
     };
+    option (google.api.method_signature) = "name";
   }
 
   // Updates the schema of a Cloud Spanner database by
@@ -80,6 +94,11 @@
       patch: "/v1/{database=projects/*/instances/*/databases/*}/ddl"
       body: "*"
     };
+    option (google.longrunning.operation_info) = {
+      response_type: "google.protobuf.Empty"
+      metadata_type: "google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata"
+    };
+    option (google.api.method_signature) = "database,statements";
   }
 
   // Drops (aka deletes) a Cloud Spanner database.
@@ -87,6 +106,7 @@
     option (google.api.http) = {
       delete: "/v1/{database=projects/*/instances/*/databases/*}"
     };
+    option (google.api.method_signature) = "database";
   }
 
   // Returns the schema of a Cloud Spanner database as a list of formatted
@@ -96,6 +116,7 @@
     option (google.api.http) = {
       get: "/v1/{database=projects/*/instances/*/databases/*}/ddl"
     };
+    option (google.api.method_signature) = "database";
   }
 
   // Sets the access control policy on a database resource. Replaces any
@@ -109,6 +130,7 @@
       post: "/v1/{resource=projects/*/instances/*/databases/*}:setIamPolicy"
       body: "*"
     };
+    option (google.api.method_signature) = "resource,policy";
   }
 
   // Gets the access control policy for a database resource. Returns an empty
@@ -122,6 +144,7 @@
       post: "/v1/{resource=projects/*/instances/*/databases/*}:getIamPolicy"
       body: "*"
     };
+    option (google.api.method_signature) = "resource";
   }
 
   // Returns permissions that the caller has on the specified database resource.
@@ -136,11 +159,17 @@
       post: "/v1/{resource=projects/*/instances/*/databases/*}:testIamPermissions"
       body: "*"
     };
+    option (google.api.method_signature) = "resource,permissions";
   }
 }
 
 // A Cloud Spanner database.
 message Database {
+  option (google.api.resource) = {
+    type: "spanner.googleapis.com/Database"
+    pattern: "projects/{project}/instances/{instance}/databases/{database}"
+  };
+
   // Indicates the current state of the database.
   enum State {
     // Not specified.
@@ -170,7 +199,10 @@
 message ListDatabasesRequest {
   // Required. The instance whose databases should be listed.
   // Values are of the form `projects/<project>/instances/<instance>`.
-  string parent = 1;
+  string parent = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Instance"
+  ];
 
   // Number of databases to be returned in the response. If 0 or less,
   // defaults to the server's maximum allowed page size.
@@ -200,14 +232,17 @@
 message CreateDatabaseRequest {
   // Required. The name of the instance that will serve the new database.
   // Values are of the form `projects/<project>/instances/<instance>`.
-  string parent = 1;
+  string parent = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Instance"
+  ];
 
   // Required. A `CREATE DATABASE` statement, which specifies the ID of the
   // new database.  The database ID must conform to the regular expression
   // `[a-z][a-z0-9_\-]*[a-z0-9]` and be between 2 and 30 characters in length.
   // If the database ID is a reserved word or if it contains a hyphen, the
   // database ID must be enclosed in backticks (`` ` ``).
-  string create_statement = 2;
+  string create_statement = 2 [(google.api.field_behavior) = REQUIRED];
 
   // An optional list of DDL statements to run inside the newly created
   // database. Statements can create tables, indexes, etc. These
@@ -228,7 +263,10 @@
 message GetDatabaseRequest {
   // Required. The name of the requested database. Values are of the form
   // `projects/<project>/instances/<instance>/databases/<database>`.
-  string name = 1;
+  string name = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Database"
+  ];
 }
 
 // Enqueues the given DDL statements to be applied, in order but not
@@ -249,10 +287,13 @@
 // field for more details.
 message UpdateDatabaseDdlRequest {
   // Required. The database to update.
-  string database = 1;
+  string database = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Database"
+  ];
 
   // DDL statements to be applied to the database.
-  repeated string statements = 2;
+  repeated string statements = 2 [(google.api.field_behavior) = REQUIRED];
 
   // If empty, the new update request is assigned an
   // automatically-generated operation ID. Otherwise, `operation_id`
@@ -298,14 +339,20 @@
 // [DropDatabase][google.spanner.admin.database.v1.DatabaseAdmin.DropDatabase].
 message DropDatabaseRequest {
   // Required. The database to be dropped.
-  string database = 1;
+  string database = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Database"
+  ];
 }
 
 // The request for
 // [GetDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.GetDatabaseDdl].
 message GetDatabaseDdlRequest {
   // Required. The database whose schema we wish to get.
-  string database = 1;
+  string database = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Database"
+  ];
 }
 
 // The response for
diff --git a/google/spanner/admin/instance/v1/spanner_admin_instance_gapic_v2.yaml b/google/spanner/admin/instance/v1/spanner_admin_instance_gapic_v2.yaml
new file mode 100644
index 0000000..f4ea5c6
--- /dev/null
+++ b/google/spanner/admin/instance/v1/spanner_admin_instance_gapic_v2.yaml
@@ -0,0 +1,96 @@
+type: com.google.api.codegen.ConfigProto
+config_schema_version: 1.0.0
+language_settings:
+  java:
+    package_name: com.google.cloud.spanner.admin.instance.v1
+  python:
+    package_name: google.cloud.spanner_admin_instance_v1.gapic
+  go:
+    package_name: cloud.google.com/go/spanner/admin/instance/apiv1
+  csharp:
+    package_name: Google.Cloud.Spanner.Admin.Instance.V1
+  ruby:
+    package_name: Google::Cloud::Spanner::Admin::Instance::V1
+  php:
+    package_name: Google\Cloud\Spanner\Admin\Instance\V1
+  nodejs:
+    package_name: spanner.v1
+    domain_layer_location: google-cloud
+interfaces:
+- name: google.spanner.admin.instance.v1.InstanceAdmin
+  collections:
+  - entity_name: project
+    language_overrides:
+    - language: csharp
+      common_resource_name: Google.Api.Gax.ResourceNames.ProjectName
+  - entity_name: instance
+    language_overrides:
+    - language: csharp
+      common_resource_name: Google.Cloud.Spanner.Common.V1.InstanceName
+  retry_codes_def:
+  - name: idempotent
+    retry_codes:
+    - UNAVAILABLE
+    - DEADLINE_EXCEEDED
+  - name: non_idempotent
+    retry_codes: []
+  retry_params_def:
+  - name: default
+    initial_retry_delay_millis: 1000
+    retry_delay_multiplier: 1.3
+    max_retry_delay_millis: 32000
+    initial_rpc_timeout_millis: 60000
+    rpc_timeout_multiplier: 1
+    max_rpc_timeout_millis: 60000
+    total_timeout_millis: 600000
+  methods:
+  - name: ListInstanceConfigs
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: GetInstanceConfig
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: ListInstances
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: GetInstance
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: CreateInstance
+    retry_codes_name: non_idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+    long_running:
+      initial_poll_delay_millis: 20000
+      poll_delay_multiplier: 1.5
+      max_poll_delay_millis: 45000
+      total_poll_timeout_millis: 86400000
+  - name: UpdateInstance
+    retry_codes_name: non_idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+    long_running:
+      initial_poll_delay_millis: 20000
+      poll_delay_multiplier: 1.5
+      max_poll_delay_millis: 45000
+      total_poll_timeout_millis: 86400000
+  - name: DeleteInstance
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: SetIamPolicy
+    retry_codes_name: non_idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: GetIamPolicy
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: TestIamPermissions
+    retry_codes_name: non_idempotent
+    retry_params_name: default
+    timeout_millis: 30000
diff --git a/google/spanner/admin/instance/v1/spanner_instance_admin.proto b/google/spanner/admin/instance/v1/spanner_instance_admin.proto
index c6ca85c..d35ed8f 100644
--- a/google/spanner/admin/instance/v1/spanner_instance_admin.proto
+++ b/google/spanner/admin/instance/v1/spanner_instance_admin.proto
@@ -17,6 +17,9 @@
 package google.spanner.admin.instance.v1;
 
 import "google/api/annotations.proto";
+import "google/api/client.proto";
+import "google/api/field_behavior.proto";
+import "google/api/resource.proto";
 import "google/iam/v1/iam_policy.proto";
 import "google/iam/v1/policy.proto";
 import "google/longrunning/operations.proto";
@@ -53,12 +56,17 @@
 // instance resources, fewer resources are available for other
 // databases in that instance, and their performance may suffer.
 service InstanceAdmin {
+  option (google.api.default_host) = "spanner.googleapis.com";
+  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/spanner.admin,"
+  "https://www.googleapis.com/auth/cloud-platform";
+
   // Lists the supported instance configurations for a given project.
   rpc ListInstanceConfigs(ListInstanceConfigsRequest)
       returns (ListInstanceConfigsResponse) {
     option (google.api.http) = {
       get: "/v1/{parent=projects/*}/instanceConfigs"
     };
+    option (google.api.method_signature) = "parent";
   }
 
   // Gets information about a particular instance configuration.
@@ -66,6 +74,7 @@
     option (google.api.http) = {
       get: "/v1/{name=projects/*/instanceConfigs/*}"
     };
+    option (google.api.method_signature) = "name";
   }
 
   // Lists all instances in the given project.
@@ -73,6 +82,7 @@
     option (google.api.http) = {
       get: "/v1/{parent=projects/*}/instances"
     };
+    option (google.api.method_signature) = "parent";
   }
 
   // Gets information about a particular instance.
@@ -80,6 +90,7 @@
     option (google.api.http) = {
       get: "/v1/{name=projects/*/instances/*}"
     };
+    option (google.api.method_signature) = "name";
   }
 
   // Creates an instance and begins preparing it to begin serving. The
@@ -122,6 +133,11 @@
       post: "/v1/{parent=projects/*}/instances"
       body: "*"
     };
+    option (google.longrunning.operation_info) = {
+      response_type: "google.spanner.admin.instance.v1.Instance"
+      metadata_type: "google.spanner.admin.instance.v1.CreateInstanceMetadata"
+    };
+    option (google.api.method_signature) = "parent,instance_id,instance";
   }
 
   // Updates an instance, and begins allocating or releasing resources
@@ -170,6 +186,11 @@
       patch: "/v1/{instance.name=projects/*/instances/*}"
       body: "*"
     };
+    option (google.longrunning.operation_info) = {
+      response_type: "google.spanner.admin.instance.v1.Instance"
+      metadata_type: "google.spanner.admin.instance.v1.UpdateInstanceMetadata"
+    };
+    option (google.api.method_signature) = "instance,field_mask";
   }
 
   // Deletes an instance.
@@ -187,6 +208,7 @@
     option (google.api.http) = {
       delete: "/v1/{name=projects/*/instances/*}"
     };
+    option (google.api.method_signature) = "name";
   }
 
   // Sets the access control policy on an instance resource. Replaces any
@@ -200,6 +222,7 @@
       post: "/v1/{resource=projects/*/instances/*}:setIamPolicy"
       body: "*"
     };
+    option (google.api.method_signature) = "resource,policy";
   }
 
   // Gets the access control policy for an instance resource. Returns an empty
@@ -213,6 +236,7 @@
       post: "/v1/{resource=projects/*/instances/*}:getIamPolicy"
       body: "*"
     };
+    option (google.api.method_signature) = "resource";
   }
 
   // Returns permissions that the caller has on the specified instance resource.
@@ -227,12 +251,18 @@
       post: "/v1/{resource=projects/*/instances/*}:testIamPermissions"
       body: "*"
     };
+    option (google.api.method_signature) = "resource,permissions";
   }
 }
 
 // A possible configuration for a Cloud Spanner instance. Configurations
 // define the geographic placement of nodes and their replication.
 message InstanceConfig {
+  option (google.api.resource) = {
+    type: "spanner.googleapis.com/InstanceConfig"
+    pattern: "projects/{project}/instanceConfigs/{instance_config}"
+  };
+
   // A unique identifier for the instance configuration.  Values
   // are of the form
   // `projects/<project>/instanceConfigs/[a-z][-a-z0-9]*`
@@ -244,6 +274,11 @@
 
 // An isolated set of Cloud Spanner resources on which databases can be hosted.
 message Instance {
+  option (google.api.resource) = {
+    type: "spanner.googleapis.com/Instance"
+    pattern: "projects/{project}/instances/{instance}"
+  };
+
   // Indicates the current state of the instance.
   enum State {
     // Not specified.
@@ -320,7 +355,10 @@
   // Required. The name of the project for which a list of supported instance
   // configurations is requested. Values are of the form
   // `projects/<project>`.
-  string parent = 1;
+  string parent = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "cloudresourcemanager.googleapis.com/Project"
+  ];
 
   // Number of instance configurations to be returned in the response. If 0 or
   // less, defaults to the server's maximum allowed page size.
@@ -350,7 +388,10 @@
 message GetInstanceConfigRequest {
   // Required. The name of the requested instance configuration. Values are of
   // the form `projects/<project>/instanceConfigs/<config>`.
-  string name = 1;
+  string name = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/InstanceConfig"
+  ];
 }
 
 // The request for
@@ -358,7 +399,10 @@
 message GetInstanceRequest {
   // Required. The name of the requested instance. Values are of the form
   // `projects/<project>/instances/<instance>`.
-  string name = 1;
+  string name = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Instance"
+  ];
 }
 
 // The request for
@@ -366,16 +410,19 @@
 message CreateInstanceRequest {
   // Required. The name of the project in which to create the instance. Values
   // are of the form `projects/<project>`.
-  string parent = 1;
+  string parent = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "cloudresourcemanager.googleapis.com/Project"
+  ];
 
   // Required. The ID of the instance to create.  Valid identifiers are of the
   // form `[a-z][-a-z0-9]*[a-z0-9]` and must be between 6 and 30 characters in
   // length.
-  string instance_id = 2;
+  string instance_id = 2 [(google.api.field_behavior) = REQUIRED];
 
   // Required. The instance to create.  The name may be omitted, but if
   // specified must be `<parent>/instances/<instance_id>`.
-  Instance instance = 3;
+  Instance instance = 3 [(google.api.field_behavior) = REQUIRED];
 }
 
 // The request for
@@ -383,7 +430,10 @@
 message ListInstancesRequest {
   // Required. The name of the project for which a list of instances is
   // requested. Values are of the form `projects/<project>`.
-  string parent = 1;
+  string parent = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "cloudresourcemanager.googleapis.com/Project"
+  ];
 
   // Number of instances to be returned in the response. If 0 or less, defaults
   // to the server's maximum allowed page size.
@@ -436,7 +486,7 @@
   // name.  Otherwise, only fields mentioned in
   // [][google.spanner.admin.instance.v1.UpdateInstanceRequest.field_mask] need
   // be included.
-  Instance instance = 1;
+  Instance instance = 1 [(google.api.field_behavior) = REQUIRED];
 
   // Required. A mask specifying which fields in
   // [][google.spanner.admin.instance.v1.UpdateInstanceRequest.instance] should
@@ -444,7 +494,7 @@
   // future fields in
   // [][google.spanner.admin.instance.v1.Instance] from being erased
   // accidentally by clients that do not know about them.
-  google.protobuf.FieldMask field_mask = 2;
+  google.protobuf.FieldMask field_mask = 2 [(google.api.field_behavior) = REQUIRED];
 }
 
 // The request for
@@ -452,7 +502,10 @@
 message DeleteInstanceRequest {
   // Required. The name of the instance to be deleted. Values are of the form
   // `projects/<project>/instances/<instance>`
-  string name = 1;
+  string name = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Instance"
+  ];
 }
 
 // Metadata type for the operation returned by
diff --git a/google/spanner/v1/spanner.proto b/google/spanner/v1/spanner.proto
index b2091c9..26bcc7f 100644
--- a/google/spanner/v1/spanner.proto
+++ b/google/spanner/v1/spanner.proto
@@ -18,6 +18,9 @@
 package google.spanner.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/struct.proto";
 import "google/protobuf/timestamp.proto";
@@ -40,6 +43,10 @@
 // The Cloud Spanner API can be used to manage sessions and execute
 // transactions on data stored in Cloud Spanner databases.
 service Spanner {
+  option (google.api.default_host) = "spanner.googleapis.com";
+  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/spanner.data,"
+  "https://www.googleapis.com/auth/cloud-platform";
+  
   // Creates a new session. A session can be used to perform
   // transactions that read and/or modify data in a Cloud Spanner database.
   // Sessions are meant to be reused for many consecutive
@@ -64,6 +71,7 @@
       post: "/v1/{database=projects/*/instances/*/databases/*}/sessions"
       body: "*"
     };
+    option (google.api.method_signature) = "database";
   }
 
   // Gets a session. Returns `NOT_FOUND` if the session does not exist.
@@ -73,6 +81,7 @@
     option (google.api.http) = {
       get: "/v1/{name=projects/*/instances/*/databases/*/sessions/*}"
     };
+    option (google.api.method_signature) = "name";
   }
 
   // Lists all sessions in a given database.
@@ -80,6 +89,7 @@
     option (google.api.http) = {
       get: "/v1/{database=projects/*/instances/*/databases/*}/sessions"
     };
+    option (google.api.method_signature) = "database";
   }
 
   // Ends a session, releasing server resources associated with it. This will
@@ -89,6 +99,7 @@
     option (google.api.http) = {
       delete: "/v1/{name=projects/*/instances/*/databases/*/sessions/*}"
     };
+    option (google.api.method_signature) = "name";
   }
 
   // Executes an SQL statement, returning all results in a single reply. This
@@ -192,6 +203,7 @@
       post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:beginTransaction"
       body: "*"
     };
+    option (google.api.method_signature) = "session,options";
   }
 
   // Commits a transaction. The request includes the mutations to be
@@ -207,6 +219,8 @@
       post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:commit"
       body: "*"
     };
+    option (google.api.method_signature) = "session,transaction_id,mutations";
+    option (google.api.method_signature) = "session,single_use_transaction,mutations";
   }
 
   // Rolls back a transaction, releasing any locks it holds. It is a good
@@ -223,6 +237,7 @@
       post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:rollback"
       body: "*"
     };
+    option (google.api.method_signature) = "session,transaction_id";
   }
 
   // Creates a set of partition tokens that can be used to execute a query
@@ -269,7 +284,10 @@
 // The request for [CreateSession][google.spanner.v1.Spanner.CreateSession].
 message CreateSessionRequest {
   // Required. The database in which the new session is created.
-  string database = 1;
+  string database = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Database"
+  ];
 
   // The session to create.
   Session session = 2;
@@ -277,6 +295,11 @@
 
 // A session in the Cloud Spanner API.
 message Session {
+  option (google.api.resource) = {
+    type: "spanner.googleapis.com/Session"
+    pattern: "projects/{project}/instances/{instance}/databases/{database}/sessions/{session}"
+  };
+
   // The name of the session. This is always system-assigned; values provided
   // when creating a session are ignored.
   string name = 1;
@@ -303,13 +326,19 @@
 // The request for [GetSession][google.spanner.v1.Spanner.GetSession].
 message GetSessionRequest {
   // Required. The name of the session to retrieve.
-  string name = 1;
+  string name = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 }
 
 // The request for [ListSessions][google.spanner.v1.Spanner.ListSessions].
 message ListSessionsRequest {
   // Required. The database in which to list sessions.
-  string database = 1;
+  string database = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 
   // Number of sessions to be returned in the response. If 0 or less, defaults
   // to the server's maximum allowed page size.
@@ -337,7 +366,10 @@
 // The response for [ListSessions][google.spanner.v1.Spanner.ListSessions].
 message ListSessionsResponse {
   // The list of requested sessions.
-  repeated Session sessions = 1;
+  repeated Session sessions = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 
   // `next_page_token` can be sent in a subsequent
   // [ListSessions][google.spanner.v1.Spanner.ListSessions] call to fetch more
@@ -348,7 +380,10 @@
 // The request for [DeleteSession][google.spanner.v1.Spanner.DeleteSession].
 message DeleteSessionRequest {
   // Required. The name of the session to delete.
-  string name = 1;
+  string name = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 }
 
 // The request for [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and
@@ -369,7 +404,10 @@
   }
 
   // Required. The session in which the SQL query should be performed.
-  string session = 1;
+  string session = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 
   // The transaction to use. If none is provided, the default is a
   // temporary read-only transaction with strong concurrency.
@@ -387,7 +425,7 @@
   TransactionSelector transaction = 2;
 
   // Required. The SQL string.
-  string sql = 3;
+  string sql = 3 [(google.api.field_behavior) = REQUIRED];
 
   // The SQL string can contain parameter placeholders. A parameter
   // placeholder consists of `'@'` followed by the parameter
@@ -486,12 +524,15 @@
   }
 
   // Required. The session in which the DML statements should be performed.
-  string session = 1;
+  string session = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 
   // The transaction to use. A ReadWrite transaction is required. Single-use
   // transactions are not supported (to avoid replay).  The caller must either
   // supply an existing transaction ID or begin a new transaction.
-  TransactionSelector transaction = 2;
+  TransactionSelector transaction = 2 [(google.api.field_behavior) = REQUIRED];
 
   // The list of statements to execute in this batch. Statements are executed
   // serially, such that the effects of statement i are visible to statement
@@ -499,13 +540,13 @@
   // first failed statement; the remaining statements will not run.
   //
   // REQUIRES: statements_size() > 0.
-  repeated Statement statements = 3;
+  repeated Statement statements = 3 [(google.api.field_behavior) = REQUIRED];
 
   // A per-transaction sequence number used to identify this request. This is
   // used in the same space as the seqno in
   // [ExecuteSqlRequest][Spanner.ExecuteSqlRequest]. See more details
   // in [ExecuteSqlRequest][Spanner.ExecuteSqlRequest].
-  int64 seqno = 4;
+  int64 seqno = 4 [(google.api.field_behavior) = REQUIRED];
 }
 
 // The response for [ExecuteBatchDml][google.spanner.v1.Spanner.ExecuteBatchDml]. Contains a list
@@ -567,7 +608,10 @@
 // The request for [PartitionQuery][google.spanner.v1.Spanner.PartitionQuery]
 message PartitionQueryRequest {
   // Required. The session used to create the partitions.
-  string session = 1;
+  string session = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 
   // Read only snapshot transactions are supported, read/write and single use
   // transactions are not.
@@ -584,7 +628,7 @@
   // DELETE. Use
   // [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] with a
   // PartitionedDml transaction for large, partition-friendly DML operations.
-  string sql = 3;
+  string sql = 3 [(google.api.field_behavior) = REQUIRED];
 
   // The SQL query string can contain parameter placeholders. A parameter
   // placeholder consists of `'@'` followed by the parameter
@@ -620,14 +664,17 @@
 // The request for [PartitionRead][google.spanner.v1.Spanner.PartitionRead]
 message PartitionReadRequest {
   // Required. The session used to create the partitions.
-  string session = 1;
+  string session = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 
   // Read only snapshot transactions are supported, read/write and single use
   // transactions are not.
   TransactionSelector transaction = 2;
 
   // Required. The name of the table in the database to be read.
-  string table = 3;
+  string table = 3 [(google.api.field_behavior) = REQUIRED];
 
   // If non-empty, the name of an index on
   // [table][google.spanner.v1.PartitionReadRequest.table]. This index is used
@@ -651,7 +698,7 @@
   //
   // It is not an error for the `key_set` to name rows that do not
   // exist in the database. Read yields nothing for nonexistent rows.
-  KeySet key_set = 6;
+  KeySet key_set = 6 [(google.api.field_behavior) = REQUIRED];
 
   // Additional options that affect how many partitions are created.
   PartitionOptions partition_options = 9;
@@ -680,14 +727,17 @@
 // [StreamingRead][google.spanner.v1.Spanner.StreamingRead].
 message ReadRequest {
   // Required. The session in which the read should be performed.
-  string session = 1;
+  string session = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 
   // The transaction to use. If none is provided, the default is a
   // temporary read-only transaction with strong concurrency.
   TransactionSelector transaction = 2;
 
   // Required. The name of the table in the database to be read.
-  string table = 3;
+  string table = 3 [(google.api.field_behavior) = REQUIRED];
 
   // If non-empty, the name of an index on
   // [table][google.spanner.v1.ReadRequest.table]. This index is used instead of
@@ -699,7 +749,7 @@
 
   // The columns of [table][google.spanner.v1.ReadRequest.table] to be returned
   // for each row matching this request.
-  repeated string columns = 5;
+  repeated string columns = 5 [(google.api.field_behavior) = REQUIRED];
 
   // Required. `key_set` identifies the rows to be yielded. `key_set` names the
   // primary keys of the rows in [table][google.spanner.v1.ReadRequest.table] to
@@ -717,7 +767,7 @@
   //
   // It is not an error for the `key_set` to name rows that do not
   // exist in the database. Read yields nothing for nonexistent rows.
-  KeySet key_set = 6;
+  KeySet key_set = 6 [(google.api.field_behavior) = REQUIRED];
 
   // If greater than zero, only the first `limit` rows are yielded. If `limit`
   // is zero, the default is no limit. A limit cannot be specified if
@@ -743,16 +793,22 @@
 // [BeginTransaction][google.spanner.v1.Spanner.BeginTransaction].
 message BeginTransactionRequest {
   // Required. The session in which the transaction runs.
-  string session = 1;
+  string session = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 
   // Required. Options for the new transaction.
-  TransactionOptions options = 2;
+  TransactionOptions options = 2 [(google.api.field_behavior) = REQUIRED];
 }
 
 // The request for [Commit][google.spanner.v1.Spanner.Commit].
 message CommitRequest {
   // Required. The session in which the transaction to be committed is running.
-  string session = 1;
+  string session = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 
   // Required. The transaction in which to commit.
   oneof transaction {
@@ -774,7 +830,7 @@
   // The mutations to be executed when this transaction commits. All
   // mutations are applied atomically, in the order they appear in
   // this list.
-  repeated Mutation mutations = 4;
+  repeated Mutation mutations = 4 [(google.api.field_behavior) = REQUIRED];
 }
 
 // The response for [Commit][google.spanner.v1.Spanner.Commit].
@@ -786,8 +842,11 @@
 // The request for [Rollback][google.spanner.v1.Spanner.Rollback].
 message RollbackRequest {
   // Required. The session in which the transaction to roll back is running.
-  string session = 1;
+  string session = 1 [
+    (google.api.field_behavior) = REQUIRED,
+    (google.api.resource_reference).type = "spanner.googleapis.com/Session"
+  ];
 
   // Required. The transaction to roll back.
-  bytes transaction_id = 2;
+  bytes transaction_id = 2 [(google.api.field_behavior) = REQUIRED];
 }
diff --git a/google/spanner/v1/spanner_gapic_v2.yaml b/google/spanner/v1/spanner_gapic_v2.yaml
new file mode 100644
index 0000000..e32bfbf
--- /dev/null
+++ b/google/spanner/v1/spanner_gapic_v2.yaml
@@ -0,0 +1,125 @@
+type: com.google.api.codegen.ConfigProto
+config_schema_version: 1.0.0
+language_settings:
+  java:
+    package_name: com.google.cloud.spanner.v1
+    release_level: GA
+  python:
+    package_name: google.cloud.spanner_v1.gapic
+    release_level: GA
+  go:
+    package_name: cloud.google.com/go/spanner/apiv1
+    domain_layer_location: cloud.google.com/go/spanner
+    release_level: GA
+  csharp:
+    package_name: Google.Cloud.Spanner.V1
+    release_level: GA
+  ruby:
+    package_name: Google::Cloud::Spanner::V1
+    release_level: GA
+  php:
+    package_name: Google\Cloud\Spanner\V1
+    release_level: GA
+  nodejs:
+    package_name: spanner.v1
+    domain_layer_location: google-cloud
+    release_level: GA
+interfaces:
+- name: google.spanner.v1.Spanner
+  collections:
+  - entity_name: database
+    language_overrides:
+    - language: csharp
+      common_resource_name: Google.Cloud.Spanner.Common.V1.DatabaseName
+  retry_codes_def:
+  - name: idempotent
+    retry_codes:
+    - UNAVAILABLE
+    - DEADLINE_EXCEEDED
+  - name: non_idempotent
+    retry_codes: []
+  - name: long_running
+    retry_codes:
+    - UNAVAILABLE
+  retry_params_def:
+  - name: default
+    initial_retry_delay_millis: 1000
+    retry_delay_multiplier: 1.3
+    max_retry_delay_millis: 32000
+    initial_rpc_timeout_millis: 60000
+    rpc_timeout_multiplier: 1
+    max_rpc_timeout_millis: 60000
+    total_timeout_millis: 600000
+  - name: streaming
+    initial_retry_delay_millis: 1000
+    retry_delay_multiplier: 1.3
+    max_retry_delay_millis: 32000
+    initial_rpc_timeout_millis: 120000
+    rpc_timeout_multiplier: 1
+    max_rpc_timeout_millis: 120000
+    total_timeout_millis: 1200000
+  - name: long_running
+    initial_retry_delay_millis: 1000
+    retry_delay_multiplier: 1.3
+    max_retry_delay_millis: 32000
+    initial_rpc_timeout_millis: 3600000
+    rpc_timeout_multiplier: 1
+    max_rpc_timeout_millis: 3600000
+    total_timeout_millis: 3600000
+  methods:
+  - name: CreateSession
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: GetSession
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: ListSessions
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: DeleteSession
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: ExecuteSql
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: ExecuteStreamingSql
+    retry_codes_name: non_idempotent
+    retry_params_name: streaming
+    timeout_millis: 3600000
+  - name: ExecuteBatchDml
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: Read
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: StreamingRead
+    retry_codes_name: non_idempotent
+    retry_params_name: streaming
+    timeout_millis: 3600000
+  - name: BeginTransaction
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: Commit
+    retry_codes_name: long_running
+    retry_params_name: long_running
+    timeout_millis: 3600000
+  - name: Rollback
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: PartitionQuery
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000
+  - name: PartitionRead
+    retry_codes_name: idempotent
+    retry_params_name: default
+    timeout_millis: 30000