...

Text file src/github.com/bazelbuild/rules_go/proto/def.bzl

Documentation: github.com/bazelbuild/rules_go/proto

     1# Copyright 2017 The Bazel Authors. All rights reserved.
     2#
     3# Licensed under the Apache License, Version 2.0 (the "License");
     4# you may not use this file except in compliance with the License.
     5# You may obtain a copy of the License at
     6#
     7#    http://www.apache.org/licenses/LICENSE-2.0
     8#
     9# Unless required by applicable law or agreed to in writing, software
    10# distributed under the License is distributed on an "AS IS" BASIS,
    11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12# See the License for the specific language governing permissions and
    13# limitations under the License.
    14
    15load(
    16    "//go:def.bzl",
    17    "GoLibrary",
    18    "GoSource",
    19    "go_context",
    20)
    21load(
    22    "@bazel_skylib//lib:types.bzl",
    23    "types",
    24)
    25load(
    26    "//proto:compiler.bzl",
    27    "GoProtoCompiler",
    28    "proto_path",
    29)
    30load(
    31    "//go/private:common.bzl",
    32    "GO_TOOLCHAIN",
    33)
    34load(
    35    "//go/private/rules:transition.bzl",
    36    "non_go_tool_transition",
    37)
    38load(
    39    "@rules_proto//proto:defs.bzl",
    40    "ProtoInfo",
    41)
    42
    43GoProtoImports = provider()
    44
    45def get_imports(attr, importpath):
    46    proto_deps = []
    47
    48    # ctx.attr.proto is a one-element array since there is a Starlark transition attached to it.
    49    if hasattr(attr, "proto") and attr.proto and types.is_list(attr.proto) and ProtoInfo in attr.proto[0]:
    50        proto_deps = [attr.proto[0]]
    51    elif hasattr(attr, "protos"):
    52        proto_deps = [d for d in attr.protos if ProtoInfo in d]
    53    else:
    54        proto_deps = []
    55
    56    direct = dict()
    57    for dep in proto_deps:
    58        for src in dep[ProtoInfo].check_deps_sources.to_list():
    59            direct["{}={}".format(proto_path(src, dep[ProtoInfo]), importpath)] = True
    60
    61    deps = getattr(attr, "deps", []) + getattr(attr, "embed", [])
    62    transitive = [
    63        dep[GoProtoImports].imports
    64        for dep in deps
    65        if GoProtoImports in dep
    66    ]
    67    return depset(direct = direct.keys(), transitive = transitive)
    68
    69def _go_proto_aspect_impl(_target, ctx):
    70    go = go_context(ctx, ctx.rule.attr)
    71    imports = get_imports(ctx.rule.attr, go.importpath)
    72    return [GoProtoImports(imports = imports)]
    73
    74_go_proto_aspect = aspect(
    75    _go_proto_aspect_impl,
    76    attr_aspects = [
    77        "deps",
    78        "embed",
    79    ],
    80    toolchains = [GO_TOOLCHAIN],
    81)
    82
    83def _proto_library_to_source(_go, attr, source, merge):
    84    if attr.compiler:
    85        compilers = [attr.compiler]
    86    else:
    87        compilers = attr.compilers
    88    for compiler in compilers:
    89        if GoSource in compiler:
    90            merge(source, compiler[GoSource])
    91
    92def _go_proto_library_impl(ctx):
    93    go = go_context(ctx)
    94    if ctx.attr.compiler:
    95        #TODO: print("DEPRECATED: compiler attribute on {}, use compilers instead".format(ctx.label))
    96        compilers = [ctx.attr.compiler]
    97    else:
    98        compilers = ctx.attr.compilers
    99
   100    if ctx.attr.proto:
   101        #TODO: print("DEPRECATED: proto attribute on {}, use protos instead".format(ctx.label))
   102        if ctx.attr.protos:
   103            fail("Either proto or protos (non-empty) argument must be specified, but not both")
   104
   105        # ctx.attr.proto is a one-element array since there is a Starlark transition attached to it.
   106        proto_deps = [ctx.attr.proto[0]]
   107    else:
   108        if not ctx.attr.protos:
   109            fail("Either proto or protos (non-empty) argument must be specified")
   110        proto_deps = ctx.attr.protos
   111
   112    go_srcs = []
   113    valid_archive = False
   114
   115    for c in compilers:
   116        compiler = c[GoProtoCompiler]
   117        if compiler.valid_archive:
   118            valid_archive = True
   119        go_srcs.extend(compiler.compile(
   120            go,
   121            compiler = compiler,
   122            protos = [d[ProtoInfo] for d in proto_deps],
   123            imports = get_imports(ctx.attr, go.importpath),
   124            importpath = go.importpath,
   125        ))
   126    library = go.new_library(
   127        go,
   128        resolver = _proto_library_to_source,
   129        srcs = go_srcs,
   130    )
   131    source = go.library_to_source(go, ctx.attr, library, False)
   132    providers = [library, source]
   133    output_groups = {
   134        "go_generated_srcs": go_srcs,
   135    }
   136    if valid_archive:
   137        archive = go.archive(go, source)
   138        output_groups["compilation_outputs"] = [archive.data.file]
   139        providers.extend([
   140            archive,
   141            DefaultInfo(
   142                files = depset([archive.data.file]),
   143                runfiles = archive.runfiles,
   144            ),
   145        ])
   146    return providers + [OutputGroupInfo(**output_groups)]
   147
   148go_proto_library = rule(
   149    implementation = _go_proto_library_impl,
   150    attrs = {
   151        "proto": attr.label(
   152            cfg = non_go_tool_transition,
   153            providers = [ProtoInfo],
   154        ),
   155        "protos": attr.label_list(
   156            cfg = non_go_tool_transition,
   157            providers = [ProtoInfo],
   158            default = [],
   159        ),
   160        "deps": attr.label_list(
   161            providers = [GoLibrary],
   162            aspects = [_go_proto_aspect],
   163        ),
   164        "importpath": attr.string(),
   165        "importmap": attr.string(),
   166        "importpath_aliases": attr.string_list(),  # experimental, undocumented
   167        "embed": attr.label_list(providers = [GoLibrary]),
   168        "gc_goopts": attr.string_list(),
   169        "compiler": attr.label(providers = [GoProtoCompiler]),
   170        "compilers": attr.label_list(
   171            providers = [GoProtoCompiler],
   172            default = ["//proto:go_proto"],
   173        ),
   174        "_go_context_data": attr.label(
   175            default = "//:go_context_data",
   176        ),
   177        "_allowlist_function_transition": attr.label(
   178            default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
   179        ),
   180    },
   181    toolchains = [GO_TOOLCHAIN],
   182)
   183# go_proto_library is a rule that takes a proto_library (in the proto
   184# attribute) and produces a go library for it.
   185
   186def go_grpc_library(name, **kwargs):
   187    if "compilers" not in kwargs:
   188        kwargs["compilers"] = [
   189            Label("//proto:go_proto"),
   190            Label("//proto:go_grpc_v2"),
   191        ]
   192    go_proto_library(
   193        name = name,
   194        **kwargs
   195    )
   196
   197def proto_register_toolchains():
   198    print("You no longer need to call proto_register_toolchains(), it does nothing")

View as plain text