blob: be6fb3d06ebf037ae18b1d90720c60d1a96e91f6 [file] [log] [blame]
# Copyright 2017 The Bazel Authors. All rights reserved.
#
# 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.
load("@io_bazel_rules_go//go:def.bzl",
"go_context",
"GoLibrary",
)
load("@io_bazel_rules_go//go/private:common.bzl", # TODO: @skylib?
"sets",
)
GoProtoCompiler = provider()
def go_proto_compile(go, compiler, proto, imports, importpath):
go_srcs = []
outpath = None
for src in proto.direct_sources:
out = go.declare_file(go, path=importpath+"/"+src.basename[:-len(".proto")], ext=compiler.suffix)
go_srcs.append(out)
if outpath == None:
outpath = out.dirname[:-len(importpath)]
args = go.actions.args()
args.add([
"--protoc", compiler.protoc,
"--importpath", importpath,
"--out_path", outpath,
"--plugin", compiler.plugin,
])
args.add(compiler.options, before_each = "--option")
args.add(proto.transitive_descriptor_sets, before_each = "--descriptor_set")
args.add(go_srcs, before_each = "--expected")
args.add(imports, before_each = "--import")
args.add(proto.direct_sources, map_fn=_all_proto_paths)
go.actions.run(
inputs = sets.union([
compiler.go_protoc,
compiler.protoc,
compiler.plugin,
], proto.transitive_descriptor_sets),
outputs = go_srcs,
progress_message = "Generating into %s" % go_srcs[0].dirname,
mnemonic = "GoProtocGen",
executable = compiler.go_protoc,
arguments = [args],
)
return go_srcs
def _all_proto_paths(protos):
return [_proto_path(proto) for proto in protos]
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 _go_proto_compiler_impl(ctx):
go = go_context(ctx)
library = go.new_library(go)
source = go.library_to_source(go, ctx.attr, library, ctx.coverage_instrumented())
return [
GoProtoCompiler(
deps = ctx.attr.deps,
compile = go_proto_compile,
options = ctx.attr.options,
suffix = ctx.attr.suffix,
go_protoc = ctx.file._go_protoc,
protoc = ctx.file._protoc,
plugin = ctx.file.plugin,
),
library, source,
]
go_proto_compiler = rule(
_go_proto_compiler_impl,
attrs = {
"deps": attr.label_list(providers = [GoLibrary]),
"options": attr.string_list(),
"suffix": attr.string(default = ".pb.go"),
"plugin": attr.label(
allow_files = True,
single_file = True,
executable = True,
cfg = "host",
default = Label("@com_github_golang_protobuf//protoc-gen-go"),
),
"_go_protoc": attr.label(
allow_files=True,
single_file=True,
executable = True,
cfg = "host",
default=Label("@io_bazel_rules_go//go/tools/builders:go-protoc"),
),
"_protoc": attr.label(
allow_files = True,
single_file = True,
executable = True,
cfg = "host",
default = Label("@com_github_google_protobuf//:protoc"),
),
"_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = [
"@io_bazel_rules_go//go:toolchain",
],
)