From 6375cd86b7cdbb66ba3b6093d27dbc0d21c1b079 Mon Sep 17 00:00:00 2001
From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com>
Date: Fri, 12 Nov 2021 17:04:13 +0000
Subject: [PATCH] chore(python): add .github/CODEOWNERS as a templated file
 (#74)

---
 .github/.OwlBot.lock.yaml |   2 +-
 .github/CODEOWNERS        |   9 +-
 google/api/routing.proto  | 461 ++++++++++++++++++++++++++++++++++++++
 google/api/routing_pb2.py | 198 ++++++++++++++++
 4 files changed, 665 insertions(+), 5 deletions(-)
 create mode 100644 google/api/routing.proto
 create mode 100644 google/api/routing_pb2.py

diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml
index 7d98291..7519fa3 100644
--- a/.github/.OwlBot.lock.yaml
+++ b/.github/.OwlBot.lock.yaml
@@ -1,3 +1,3 @@
 docker:
   image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest
-  digest: sha256:58f73ba196b5414782605236dd0712a73541b44ff2ff4d3a36ec41092dd6fa5b
+  digest: sha256:0e18b9475fbeb12d9ad4302283171edebb6baf2dfca1bd215ee3b34ed79d95d7
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 30c3973..44cc868 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -3,9 +3,10 @@
 #
 # For syntax help see:
 # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax
+# Note: This file is autogenerated. To make changes to the codeowner team, please update .repo-metadata.json.
 
-# The @googleapis/yoshi-python is the default owner for changes in this repo
-*               @googleapis/yoshi-python
+# @googleapis/yoshi-python is the default owner for changes in this repo
+*     @googleapis/yoshi-python
 
-# The python-samples-reviewers team is the default owner for samples changes
-/samples/  @googleapis/python-samples-owners
\ No newline at end of file
+# @googleapis/python-samples-owners is the default owner for samples changes
+/samples/   @googleapis/python-samples-owners
diff --git a/google/api/routing.proto b/google/api/routing.proto
new file mode 100644
index 0000000..0138283
--- /dev/null
+++ b/google/api/routing.proto
@@ -0,0 +1,461 @@
+// Copyright 2021 Google LLC
+//
+// 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.api;
+
+import "google/protobuf/descriptor.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
+option java_multiple_files = true;
+option java_outer_classname = "RoutingProto";
+option java_package = "com.google.api";
+option objc_class_prefix = "GAPI";
+
+extend google.protobuf.MethodOptions {
+  // See RoutingRule.
+  google.api.RoutingRule routing = 72295729;
+}
+
+// Specifies the routing information that should be sent along with the request
+// in the form of routing header.
+// **NOTE:** All service configuration rules follow the "last one wins" order.
+//
+// The examples below will apply to an RPC which has the following request type:
+//
+// Message Definition:
+//
+//     message Request {
+//       // The name of the Table
+//       // Values can be of the following formats:
+//       // - `projects/<project>/tables/<table>`
+//       // - `projects/<project>/instances/<instance>/tables/<table>`
+//       // - `region/<region>/zones/<zone>/tables/<table>`
+//       string table_name = 1;
+//
+//       // This value specifies routing for replication.
+//       // It can be in the following formats:
+//       // - `profiles/<profile_id>`
+//       // - a legacy `profile_id` that can be any string
+//       string app_profile_id = 2;
+//     }
+//
+// Example message:
+//
+//     {
+//       table_name: projects/proj_foo/instances/instance_bar/table/table_baz,
+//       app_profile_id: profiles/prof_qux
+//     }
+//
+// The routing header consists of one or multiple key-value pairs. Every key
+// and value must be percent-encoded, and joined together in the format of
+// `key1=value1&key2=value2`.
+// In the examples below I am skipping the percent-encoding for readablity.
+//
+// Example 1
+//
+// Extracting a field from the request to put into the routing header
+// unchanged, with the key equal to the field name.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // Take the `app_profile_id`.
+//       routing_parameters {
+//         field: "app_profile_id"
+//       }
+//     };
+//
+// result:
+//
+//     x-goog-request-params: app_profile_id=profiles/prof_qux
+//
+// Example 2
+//
+// Extracting a field from the request to put into the routing header
+// unchanged, with the key different from the field name.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // Take the `app_profile_id`, but name it `routing_id` in the header.
+//       routing_parameters {
+//         field: "app_profile_id"
+//         path_template: "{routing_id=**}"
+//       }
+//     };
+//
+// result:
+//
+//     x-goog-request-params: routing_id=profiles/prof_qux
+//
+// Example 3
+//
+// Extracting a field from the request to put into the routing
+// header, while matching a path template syntax on the field's value.
+//
+// NB: it is more useful to send nothing than to send garbage for the purpose
+// of dynamic routing, since garbage pollutes cache. Thus the matching.
+//
+// Sub-example 3a
+//
+// The field matches the template.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // Take the `table_name`, if it's well-formed (with project-based
+//       // syntax).
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{table_name=projects/*/instances/*/**}"
+//       }
+//     };
+//
+// result:
+//
+//     x-goog-request-params:
+//     table_name=projects/proj_foo/instances/instance_bar/table/table_baz
+//
+// Sub-example 3b
+//
+// The field does not match the template.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // Take the `table_name`, if it's well-formed (with region-based
+//       // syntax).
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{table_name=regions/*/zones/*/**}"
+//       }
+//     };
+//
+// result:
+//
+//     <no routing header will be sent>
+//
+// Sub-example 3c
+//
+// Multiple alternative conflictingly named path templates are
+// specified. The one that matches is used to construct the header.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // Take the `table_name`, if it's well-formed, whether
+//       // using the region- or projects-based syntax.
+//
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{table_name=regions/*/zones/*/**}"
+//       }
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{table_name=projects/*/instances/*/**}"
+//       }
+//     };
+//
+// result:
+//
+//     x-goog-request-params:
+//     table_name=projects/proj_foo/instances/instance_bar/table/table_baz
+//
+// Example 4
+//
+// Extracting a single routing header key-value pair by matching a
+// template syntax on (a part of) a single request field.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // Take just the project id from the `table_name` field.
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{routing_id=projects/*}/**"
+//       }
+//     };
+//
+// result:
+//
+//     x-goog-request-params: routing_id=projects/proj_foo
+//
+// Example 5
+//
+// Extracting a single routing header key-value pair by matching
+// several conflictingly named path templates on (parts of) a single request
+// field. The last template to match "wins" the conflict.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // If the `table_name` does not have instances information,
+//       // take just the project id for routing.
+//       // Otherwise take project + instance.
+//
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{routing_id=projects/*}/**"
+//       }
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{routing_id=projects/*/instances/*}/**"
+//       }
+//     };
+//
+// result:
+//
+//     x-goog-request-params:
+//     routing_id=projects/proj_foo/instances/instance_bar
+//
+// Example 6
+//
+// Extracting multiple routing header key-value pairs by matching
+// several non-conflicting path templates on (parts of) a single request field.
+//
+// Sub-example 6a
+//
+// Make the templates strict, so that if the `table_name` does not
+// have an instance information, nothing is sent.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // The routing code needs two keys instead of one composite
+//       // but works only for the tables with the "project-instance" name
+//       // syntax.
+//
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{project_id=projects/*}/instances/*/**"
+//       }
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "projects/*/{instance_id=instances/*}/**"
+//       }
+//     };
+//
+// result:
+//
+//     x-goog-request-params:
+//     project_id=projects/proj_foo&instance_id=instances/instance_bar
+//
+// Sub-example 6b
+//
+// Make the templates loose, so that if the `table_name` does not
+// have an instance information, just the project id part is sent.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // The routing code wants two keys instead of one composite
+//       // but will work with just the `project_id` for tables without
+//       // an instance in the `table_name`.
+//
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{project_id=projects/*}/**"
+//       }
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "projects/*/{instance_id=instances/*}/**"
+//       }
+//     };
+//
+// result (is the same as 6a for our example message because it has the instance
+// information):
+//
+//     x-goog-request-params:
+//     project_id=projects/proj_foo&instance_id=instances/instance_bar
+//
+// Example 7
+//
+// Extracting multiple routing header key-value pairs by matching
+// several path templates on multiple request fields.
+//
+// NB: note that here there is no way to specify sending nothing if one of the
+// fields does not match its template. E.g. if the `table_name` is in the wrong
+// format, the `project_id` will not be sent, but the `routing_id` will be.
+// The backend routing code has to be aware of that and be prepared to not
+// receive a full complement of keys if it expects multiple.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // The routing needs both `project_id` and `routing_id`
+//       // (from the `app_profile_id` field) for routing.
+//
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{project_id=projects/*}/**"
+//       }
+//       routing_parameters {
+//         field: "app_profile_id"
+//         path_template: "{routing_id=**}"
+//       }
+//     };
+//
+// result:
+//
+//     x-goog-request-params:
+//     project_id=projects/proj_foo&routing_id=profiles/prof_qux
+//
+// Example 8
+//
+// Extracting a single routing header key-value pair by matching
+// several conflictingly named path templates on several request fields. The
+// last template to match "wins" the conflict.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // The `routing_id` can be a project id or a region id depending on
+//       // the table name format, but only if the `app_profile_id` is not set.
+//       // If `app_profile_id` is set it should be used instead.
+//
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{routing_id=projects/*}/**"
+//       }
+//       routing_parameters {
+//          field: "table_name"
+//          path_template: "{routing_id=regions/*}/**"
+//       }
+//       routing_parameters {
+//         field: "app_profile_id"
+//         path_template: "{routing_id=**}"
+//       }
+//     };
+//
+// result:
+//
+//     x-goog-request-params: routing_id=profiles/prof_qux
+//
+// Example 9
+//
+// Bringing it all together.
+//
+// annotation:
+//
+//     option (google.api.routing) = {
+//       // For routing both `table_location` and a `routing_id` are needed.
+//       //
+//       // table_location can be either an instance id or a region+zone id.
+//       //
+//       // For `routing_id`, take the value of `app_profile_id`
+//       // - If it's in the format `profiles/<profile_id>`, send
+//       // just the `<profile_id>` part.
+//       // - If it's any other literal, send it as is.
+//       // If the `app_profile_id` is empty, and the `table_name` starts with
+//       // the project_id, send that instead.
+//
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "projects/*/{table_location=instances/*}/tables/*"
+//       }
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{table_location=regions/*/zones/*}/tables/*"
+//       }
+//       routing_parameters {
+//         field: "table_name"
+//         path_template: "{routing_id=projects/*}/**"
+//       }
+//       routing_parameters {
+//         field: "app_profile_id"
+//         path_template: "{routing_id=**}"
+//       }
+//       routing_parameters {
+//         field: "app_profile_id"
+//         path_template: "profiles/{routing_id=*}"
+//       }
+//     };
+//
+// result:
+//
+//     x-goog-request-params:
+//     table_location=instances/instance_bar&routing_id=prof_qux
+message RoutingRule {
+  // A collection of Routing Parameter specifications.
+  // **NOTE:** If multiple Routing Parameters describe the same key
+  // (via the `path_template` field or via the `field` field when
+  // `path_template` is not provided), "last one wins" rule
+  // determines which Parameter gets used.
+  // See the examples for more details.
+  repeated RoutingParameter routing_parameters = 2;
+}
+
+// A projection from an input message to the GRPC or REST header.
+message RoutingParameter {
+  // A request field to extract the header key-value pair from.
+  string field = 1;
+
+  // A pattern matching the key-value field. Optional.
+  // If not specified, the whole field specified in the `field` field will be
+  // taken as value, and its name used as key. If specified, it MUST contain
+  // exactly one named segment (along with any number of unnamed segments) The
+  // pattern will be matched over the field specified in the `field` field, then
+  // if the match is successful:
+  // - the name of the single named segment will be used as a header name,
+  // - the match value of the segment will be used as a header value;
+  // if the match is NOT successful, nothing will be sent.
+  //
+  // Example:
+  //
+  //               -- This is a field in the request message
+  //              |   that the header value will be extracted from.
+  //              |
+  //              |                     -- This is the key name in the
+  //              |                    |   routing header.
+  //              V                    |
+  //     field: "table_name"           v
+  //     path_template: "projects/*/{table_location=instances/*}/tables/*"
+  //                                                ^            ^
+  //                                                |            |
+  //       In the {} brackets is the pattern that --             |
+  //       specifies what to extract from the                    |
+  //       field as a value to be sent.                          |
+  //                                                             |
+  //      The string in the field must match the whole pattern --
+  //      before brackets, inside brackets, after brackets.
+  //
+  // When looking at this specific example, we can see that:
+  // - A key-value pair with the key `table_location`
+  //   and the value matching `instances/*` should be added
+  //   to the x-goog-request-params routing header.
+  // - The value is extracted from the request message's `table_name` field
+  //   if it matches the full pattern specified:
+  //   `projects/*/instances/*/tables/*`.
+  //
+  // **NB:** If the `path_template` field is not provided, the key name is
+  // equal to the field name, and the whole field should be sent as a value.
+  // This makes the pattern for the field and the value functionally equivalent
+  // to `**`, and the configuration
+  //
+  //     {
+  //       field: "table_name"
+  //     }
+  //
+  // is a functionally equivalent shorthand to:
+  //
+  //     {
+  //       field: "table_name"
+  //       path_template: "{table_name=**}"
+  //     }
+  //
+  // See Example 1 for more details.
+  string path_template = 2;
+}
diff --git a/google/api/routing_pb2.py b/google/api/routing_pb2.py
new file mode 100644
index 0000000..367a84b
--- /dev/null
+++ b/google/api/routing_pb2.py
@@ -0,0 +1,198 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2020 Google LLC
+#
+# 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.
+
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/api/routing.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+    name="google/api/routing.proto",
+    package="google.api",
+    syntax="proto3",
+    serialized_options=b"\n\016com.google.apiB\014RoutingProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI",
+    create_key=_descriptor._internal_create_key,
+    serialized_pb=b'\n\x18google/api/routing.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto"G\n\x0bRoutingRule\x12\x38\n\x12routing_parameters\x18\x02 \x03(\x0b\x32\x1c.google.api.RoutingParameter"8\n\x10RoutingParameter\x12\r\n\x05\x66ield\x18\x01 \x01(\t\x12\x15\n\rpath_template\x18\x02 \x01(\t:K\n\x07routing\x12\x1e.google.protobuf.MethodOptions\x18\xb1\xca\xbc" \x01(\x0b\x32\x17.google.api.RoutingRuleBj\n\x0e\x63om.google.apiB\x0cRoutingProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3',
+    dependencies=[google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR],
+)
+
+
+ROUTING_FIELD_NUMBER = 72295729
+routing = _descriptor.FieldDescriptor(
+    name="routing",
+    full_name="google.api.routing",
+    index=0,
+    number=72295729,
+    type=11,
+    cpp_type=10,
+    label=1,
+    has_default_value=False,
+    default_value=None,
+    message_type=None,
+    enum_type=None,
+    containing_type=None,
+    is_extension=True,
+    extension_scope=None,
+    serialized_options=None,
+    file=DESCRIPTOR,
+    create_key=_descriptor._internal_create_key,
+)
+
+
+_ROUTINGRULE = _descriptor.Descriptor(
+    name="RoutingRule",
+    full_name="google.api.RoutingRule",
+    filename=None,
+    file=DESCRIPTOR,
+    containing_type=None,
+    create_key=_descriptor._internal_create_key,
+    fields=[
+        _descriptor.FieldDescriptor(
+            name="routing_parameters",
+            full_name="google.api.RoutingRule.routing_parameters",
+            index=0,
+            number=2,
+            type=11,
+            cpp_type=10,
+            label=3,
+            has_default_value=False,
+            default_value=[],
+            message_type=None,
+            enum_type=None,
+            containing_type=None,
+            is_extension=False,
+            extension_scope=None,
+            serialized_options=None,
+            file=DESCRIPTOR,
+            create_key=_descriptor._internal_create_key,
+        )
+    ],
+    extensions=[],
+    nested_types=[],
+    enum_types=[],
+    serialized_options=None,
+    is_extendable=False,
+    syntax="proto3",
+    extension_ranges=[],
+    oneofs=[],
+    serialized_start=74,
+    serialized_end=145,
+)
+
+
+_ROUTINGPARAMETER = _descriptor.Descriptor(
+    name="RoutingParameter",
+    full_name="google.api.RoutingParameter",
+    filename=None,
+    file=DESCRIPTOR,
+    containing_type=None,
+    create_key=_descriptor._internal_create_key,
+    fields=[
+        _descriptor.FieldDescriptor(
+            name="field",
+            full_name="google.api.RoutingParameter.field",
+            index=0,
+            number=1,
+            type=9,
+            cpp_type=9,
+            label=1,
+            has_default_value=False,
+            default_value=b"".decode("utf-8"),
+            message_type=None,
+            enum_type=None,
+            containing_type=None,
+            is_extension=False,
+            extension_scope=None,
+            serialized_options=None,
+            file=DESCRIPTOR,
+            create_key=_descriptor._internal_create_key,
+        ),
+        _descriptor.FieldDescriptor(
+            name="path_template",
+            full_name="google.api.RoutingParameter.path_template",
+            index=1,
+            number=2,
+            type=9,
+            cpp_type=9,
+            label=1,
+            has_default_value=False,
+            default_value=b"".decode("utf-8"),
+            message_type=None,
+            enum_type=None,
+            containing_type=None,
+            is_extension=False,
+            extension_scope=None,
+            serialized_options=None,
+            file=DESCRIPTOR,
+            create_key=_descriptor._internal_create_key,
+        ),
+    ],
+    extensions=[],
+    nested_types=[],
+    enum_types=[],
+    serialized_options=None,
+    is_extendable=False,
+    syntax="proto3",
+    extension_ranges=[],
+    oneofs=[],
+    serialized_start=147,
+    serialized_end=203,
+)
+
+_ROUTINGRULE.fields_by_name["routing_parameters"].message_type = _ROUTINGPARAMETER
+DESCRIPTOR.message_types_by_name["RoutingRule"] = _ROUTINGRULE
+DESCRIPTOR.message_types_by_name["RoutingParameter"] = _ROUTINGPARAMETER
+DESCRIPTOR.extensions_by_name["routing"] = routing
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+RoutingRule = _reflection.GeneratedProtocolMessageType(
+    "RoutingRule",
+    (_message.Message,),
+    {
+        "DESCRIPTOR": _ROUTINGRULE,
+        "__module__": "google.api.routing_pb2"
+        # @@protoc_insertion_point(class_scope:google.api.RoutingRule)
+    },
+)
+_sym_db.RegisterMessage(RoutingRule)
+
+RoutingParameter = _reflection.GeneratedProtocolMessageType(
+    "RoutingParameter",
+    (_message.Message,),
+    {
+        "DESCRIPTOR": _ROUTINGPARAMETER,
+        "__module__": "google.api.routing_pb2"
+        # @@protoc_insertion_point(class_scope:google.api.RoutingParameter)
+    },
+)
+_sym_db.RegisterMessage(RoutingParameter)
+
+routing.message_type = _ROUTINGRULE
+google_dot_protobuf_dot_descriptor__pb2.MethodOptions.RegisterExtension(routing)
+
+DESCRIPTOR._options = None
+# @@protoc_insertion_point(module_scope)