
_protoc_prefix = "protoc-gen-"

def _emit_proto_compile(ctx, proto_toolchain, go_proto_toolchain, lib, importpath):
  go_srcs = []
  outpath = None
  for proto in lib.proto.direct_sources:
    out = ctx.actions.declare_file(ctx.label.name + "/" + importpath + "/" + proto.basename[:-len(".proto")] + ".pb.go")
    go_srcs += [out]
    if outpath == None:
        outpath = out.dirname[:-len(importpath)]
  plugin_base_name = go_proto_toolchain.plugin.basename
  if plugin_base_name.startswith(_protoc_prefix):
    plugin_base_name = plugin_base_name[len(_protoc_prefix):]
  args= [
      "--{}_out={}:{}".format(plugin_base_name, ",".join(go_proto_toolchain.options), outpath),
      "--plugin={}={}".format(go_proto_toolchain.plugin.basename, go_proto_toolchain.plugin.path),
      "--descriptor_set_in", ":".join(
          [s.path for s in lib.proto.transitive_descriptor_sets])
  ]
  args += [_proto_path(proto) for proto in lib.proto.direct_sources]
  ctx.actions.run(
      inputs = [
          proto_toolchain.protoc,
          go_proto_toolchain.plugin,
      ] + lib.proto.transitive_descriptor_sets.to_list(),
      outputs = go_srcs,
      progress_message = "Generating into %s" % go_srcs[0].dirname,
      mnemonic = "GoProtocGen",
      executable = proto_toolchain.protoc,
      arguments = args,
  )
  return go_srcs

def _proto_path(proto):
  """
  The proto path is not really a file path
  It's the path to the proto that was seen when the descriptor file was generated.
  """
  path = proto.path
  root = proto.root.path
  ws = proto.owner.workspace_root
  if path.startswith(root): path = path[len(root):]
  if path.startswith("/"): path = path[1:]
  if path.startswith(ws): path = path[len(ws):]
  if path.startswith("/"): path = path[1:]
  return path

def _proto_toolchain_impl(ctx):
  return [platform_common.ToolchainInfo(
      protoc = ctx.file._protoc,
  )]

proto_toolchain = rule(
    _proto_toolchain_impl,
    attrs = {
        "_protoc": attr.label(allow_files = True, single_file = True, executable = True, cfg = "host", default=Label("@com_github_google_protobuf//:protoc")),
    },
)

def _go_proto_toolchain_impl(ctx):
  return [platform_common.ToolchainInfo(
      plugin = ctx.file.plugin,
      deps = ctx.attr.deps,
      options = ctx.attr.options,
      compile = _emit_proto_compile,
  )]

go_proto_toolchain = rule(
    _go_proto_toolchain_impl,
    attrs = {
        "deps": attr.label_list(),
        "options": attr.string_list(),
        "plugin": attr.label(allow_files = True, single_file = True, executable = True, cfg = "host", default=Label("@com_github_golang_protobuf//protoc-gen-go")),
    },
)

@@ -1,9 +1,8 @@
-%0A
 _protoc_
@@ -297,16 +297,33 @@
 %5D + 
-%22.pb.go%22
+go_proto_toolchain.suffix
 )%0A  
@@ -1985,32 +1985,45 @@
 oc%22: attr.label(
+%0A            
 allow_files = Tr
@@ -2017,32 +2017,44 @@
 ow_files = True,
+%0A           
  single_file = T
@@ -2049,32 +2049,44 @@
 gle_file = True,
+%0A           
  executable = Tr
@@ -2080,32 +2080,44 @@
 ecutable = True,
+%0A           
  cfg = %22host%22, d
@@ -2110,32 +2110,44 @@
 fg = %22host%22,
+%0A           
  default
 =Label(%22@com
@@ -2126,33 +2126,35 @@
          default
-=
+ = 
 Label(%22@com_gith
@@ -2182,16 +2182,26 @@
 protoc%22)
+,%0A        
 ),%0A    %7D
@@ -2375,16 +2375,48 @@
 ptions,%0A
+      suffix = ctx.attr.suffix,%0A
       co
@@ -2587,32 +2587,83 @@
 .string_list(),%0A
+        %22suffix%22: attr.string(default = %22.pb.go%22),%0A
         %22plugin%22
@@ -2675,16 +2675,29 @@
 r.label(
+%0A            
 allow_fi
@@ -2707,16 +2707,28 @@
  = True,
+%0A           
  single_
@@ -2739,16 +2739,28 @@
  = True,
+%0A           
  executa
@@ -2770,16 +2770,28 @@
  = True,
+%0A           
  cfg = %22
@@ -2796,24 +2796,36 @@
  %22host%22,
+%0A           
  default
 =Label(%22
@@ -2816,17 +2816,19 @@
  default
-=
+ = 
 Label(%22@
@@ -2870,16 +2870,26 @@
 gen-go%22)
+,%0A        
 ),%0A    %7D

Make go_proto_toolchain's suffix configurable (#1000)