pw_protobuf_compiler: Abbreviated proto subtargets

- Create abbreviated aliases for proto subtargets for targets with the
  same name as the directory:
    //the/label:label.nanopb -> //the/label:nanopb
- Fix dependencies for the _includes subtarget, which were not properly
  handling abbreviated labels or labels with the toolchain.

Change-Id: I8c764933fcde103b0aeb109811884f8b06251764
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/39200
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Reviewed-by: Armando Montanez <amontanez@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
diff --git a/pw_protobuf_compiler/docs.rst b/pw_protobuf_compiler/docs.rst
index 8651c13..f1ea15a 100644
--- a/pw_protobuf_compiler/docs.rst
+++ b/pw_protobuf_compiler/docs.rst
@@ -55,6 +55,16 @@
 Protobuf code is only generated when a generator sub-target is listed as a
 dependency of another GN target.
 
+GN permits using abbreviated labels when the target name matches the directory
+name (e.g. ``//foo`` for ``//foo:foo``). For consistency with this, the
+sub-targets for each generator are aliased to the directory when the target name
+is the same. For example, these two labels are equivalent:
+
+.. code-block::
+
+  //path/to/my_protos:my_protos.pwpb
+  //path/to/my_protos:pwpb
+
 **Arguments**
 
 * ``sources``: List of input .proto files.
@@ -66,8 +76,7 @@
   compiled with protoc as ``"nested/foo.proto"``.
 * ``strip_prefix``: Remove this prefix from the source protos. All source and
   input files must be nested under this path.
-* ``python_package``: Label of Python package in which to nest the proto
-  modules.
+* ``python_package``: Label of Python package to which to add the proto modules.
 
 **Example**
 
@@ -188,7 +197,6 @@
 
   from foo import cool_module, hello_pb2
 
-
 Working with externally defined protos
 --------------------------------------
 ``pw_proto_library`` targets may be used to build ``.proto`` sources from
@@ -286,4 +294,4 @@
 
 .. code-block:: cpp
 
-  #include "my_other_protos/baz.pwpb"
+  #include "my_other_protos/baz.pwpb.h"
diff --git a/pw_protobuf_compiler/proto.gni b/pw_protobuf_compiler/proto.gni
index 1a74163..2195b3b 100644
--- a/pw_protobuf_compiler/proto.gni
+++ b/pw_protobuf_compiler/proto.gni
@@ -318,6 +318,14 @@
 #
 #   <target_name>.<generator>
 #
+# GN permits using abbreviated labels when the target name matches the directory
+# name (e.g. //foo for //foo:foo). For consistency with this, the sub-targets
+# for each generator are aliased to the directory when the target name is the
+# same. For example, these two labels are equivalent:
+#
+#   //path/to/my_protos:my_protos.pwpb
+#   //path/to/my_protos:pwpb
+#
 # pw_protobuf_library targets generate Python packages. As such, they must have
 # globally unique package names. The first directory of the prefix or the first
 # common directory of the sources is used as the Python package.
@@ -331,7 +339,7 @@
 #       compiled with protoc as "nested/foo.proto".
 #   strip_prefix: Remove this prefix from the source protos. All source and
 #       input files must be nested under this path.
-#   python_package: Label of Python package in which to nest the proto modules.
+#   python_package: Label of Python package to which to add the proto modules.
 #
 template("pw_proto_library") {
   assert(defined(invoker.sources) && invoker.sources != [],
@@ -443,7 +451,12 @@
   # all of its dependencies to list as include paths to protoc.
   generated_file("$target_name._includes") {
     # Collect metadata from the include path files of each dependency.
-    deps = process_file_template(_deps, "{{source}}._includes")
+
+    deps = []
+    foreach(dep, _deps) {
+      _base = get_label_info(dep, "label_no_toolchain")
+      deps += [ "$_base._includes(" + get_label_info(dep, "toolchain") + ")" ]
+    }
 
     data_keys = [ "protoc_includes" ]
     outputs = [ "${_common.base_out_dir}/includes.txt" ]
@@ -595,6 +608,17 @@
     "python",
   ]
 
+  # If the label matches the directory name, alias the subtargets to the
+  # directory (e.g. //foo:nanopb is an alias for //foo:foo.nanopb).
+  if (get_label_info(":$target_name", "name") ==
+      get_path_info(get_label_info(":$target_name", "dir"), "name")) {
+    foreach(_generator, _protobuf_generators) {
+      group("$_generator") {
+        public_deps = [ ":${invoker.target_name}.$_generator" ]
+      }
+    }
+  }
+
   # If the user attempts to use the target directly instead of one of the
   # generator targets, run a script which prints a nice error message.
   pw_python_action(target_name) {