| # 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") |