blob: 3fa11ee4615c34b7a9a6b398e326659f48a699ed [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",
"GoLibrary",
"go_context",
)
load(
"@io_bazel_rules_go//go/private:skylib/lib/sets.bzl",
"sets",
)
load(
"@io_bazel_rules_go//proto:compiler.bzl",
"GoProtoCompiler",
"proto_path",
)
load(
"@io_bazel_rules_go//go/private:rules/rule.bzl",
"go_rule",
)
load(
"@io_bazel_rules_go//go/private:providers.bzl",
"INFERRED_PATH",
)
load(
"@io_bazel_rules_go_compat//:compat.bzl",
"PROTO_PROVIDER_NAME",
"get_proto",
"has_proto",
"proto_check_deps_sources",
)
GoProtoImports = provider()
def get_imports(attr):
proto_deps = []
if hasattr(attr, "proto") and attr.proto and has_proto(attr.proto):
proto_deps = [attr.proto]
elif hasattr(attr, "protos"):
proto_deps = [d for d in attr.protos if has_proto(d)]
else:
proto_deps = []
direct = dict()
for dep in proto_deps:
for src in proto_check_deps_sources(dep).to_list():
direct["{}={}".format(proto_path(src, get_proto(dep)), attr.importpath)] = True
deps = getattr(attr, "deps", []) + getattr(attr, "embed", [])
transitive = [
dep[GoProtoImports].imports
for dep in deps
if GoProtoImports in dep
]
return depset(direct = direct.keys(), transitive = transitive)
def _go_proto_aspect_impl(target, ctx):
imports = get_imports(ctx.rule.attr)
return [GoProtoImports(imports = imports)]
_go_proto_aspect = aspect(
_go_proto_aspect_impl,
attr_aspects = [
"deps",
"embed",
],
)
def _proto_library_to_source(go, attr, source, merge):
if attr.compiler:
merge(source, attr.compiler)
return
for compiler in attr.compilers:
merge(source, compiler)
def _go_proto_library_impl(ctx):
go = go_context(ctx)
if go.pathtype == INFERRED_PATH:
fail("importpath must be specified in this library or one of its embedded libraries")
if ctx.attr.compiler:
#TODO: print("DEPRECATED: compiler attribute on {}, use compilers instead".format(ctx.label))
compilers = [ctx.attr.compiler]
else:
compilers = ctx.attr.compilers
if ctx.attr.proto:
#TODO: print("DEPRECATED: proto attribute on {}, use protos instead".format(ctx.label))
if ctx.attr.protos:
fail("Either proto or protos (non-empty) argument must be specified, but not both")
proto_deps = [ctx.attr.proto]
else:
if not ctx.attr.protos:
fail("Either proto or protos (non-empty) argument must be specified")
proto_deps = ctx.attr.protos
go_srcs = []
valid_archive = False
for c in compilers:
compiler = c[GoProtoCompiler]
if compiler.valid_archive:
valid_archive = True
go_srcs.extend(compiler.compile(
go,
compiler = compiler,
protos = [get_proto(d) for d in proto_deps],
imports = get_imports(ctx.attr),
importpath = go.importpath,
))
library = go.new_library(
go,
resolver = _proto_library_to_source,
srcs = go_srcs,
)
source = go.library_to_source(go, ctx.attr, library, False)
providers = [library, source]
output_groups = {
"go_generated_srcs": go_srcs,
}
if valid_archive:
archive = go.archive(go, source)
output_groups["compilation_outputs"] = [archive.data.file]
providers.extend([
archive,
DefaultInfo(
files = depset([archive.data.file]),
runfiles = archive.runfiles,
),
])
return providers + [OutputGroupInfo(**output_groups)]
go_proto_library = go_rule(
_go_proto_library_impl,
attrs = {
"proto": attr.label(providers = [PROTO_PROVIDER_NAME]),
"protos": attr.label_list(
providers = [PROTO_PROVIDER_NAME],
default = [],
),
"deps": attr.label_list(
providers = [GoLibrary],
aspects = [_go_proto_aspect],
),
"importpath": attr.string(),
"importmap": attr.string(),
"embed": attr.label_list(providers = [GoLibrary]),
"gc_goopts": attr.string_list(),
"compiler": attr.label(providers = [GoProtoCompiler]),
"compilers": attr.label_list(
providers = [GoProtoCompiler],
default = ["@io_bazel_rules_go//proto:go_proto"],
),
},
)
"""
go_proto_library is a rule that takes a proto_library (in the proto
attribute) and produces a go library for it.
"""
def go_grpc_library(**kwargs):
# TODO: Deprecate once gazelle generates just go_proto_library
go_proto_library(compilers = ["@io_bazel_rules_go//proto:go_grpc"], **kwargs)
def proto_register_toolchains():
print("You no longer need to call proto_register_toolchains(), it does nothing")