Add Go support to GN

This change defines GN templates that allow building Go code as part of
Pigweed's build system. Go is also added as a supported language for the
proto_library template.

Change-Id: I3e639a12e6a8ba0a7a928c5d653c623cff58eb86
diff --git a/pw_protobuf_compiler/proto.gni b/pw_protobuf_compiler/proto.gni
index 208d816..c659a20 100644
--- a/pw_protobuf_compiler/proto.gni
+++ b/pw_protobuf_compiler/proto.gni
@@ -28,7 +28,7 @@
   _proto_gen_dir = "$root_gen_dir/protos"
   _outputs = process_file_template(
           invoker.protos,
-          "$root_gen_dir/protos/{{source_root_relative_dir}}/{{source_name_part}}.pb.h")
+          "$_proto_gen_dir/{{source_root_relative_dir}}/{{source_name_part}}.pb.h")
 
   _gen_target = "${target_name}_gen"
   pw_python_script(_gen_target) {
@@ -68,6 +68,35 @@
   }
 }
 
+# Generates Go code for proto files, listing the proto output directory in the
+# metadata variable GOPATH. Internal use only.
+#
+# Args:
+#  protos: List of input .proto files.
+template("_pw_go_proto_library") {
+  _proto_gopath = "$root_gen_dir/go"
+  _proto_gen_dir = "$_proto_gopath/src"
+  _rebased_gopath = rebase_path(_proto_gopath)
+
+  pw_python_script(target_name) {
+    metadata = {
+      gopath = [ "GOPATH+=$_rebased_gopath" ]
+    }
+    script = _gen_script_path
+    args = [
+             "--language",
+             "go",
+             "--module-path",
+             "//",
+             "--out-dir",
+             _proto_gen_dir,
+           ] + get_path_info(invoker.protos, "abspath")
+    inputs = invoker.protos
+    deps = invoker.deps
+    stamp = true
+  }
+}
+
 # Generates protobuf code from .proto definitions for various languages.
 #
 # The languages to generate are defined in the pw_protobuf_langs build variable.
@@ -120,6 +149,11 @@
           protoc_deps = [ "$dir_pw_protobuf:codegen_protoc_plugin" ]
         }
       }
+    } else if (lang == "go") {
+      _pw_go_proto_library(_lang_target) {
+        protos = invoker.sources
+        deps = _lang_deps
+      }
     } else {
       assert(false,
              string_join(