1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 2*7594170eSAndroid Build Coastguard Worker# 3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*7594170eSAndroid Build Coastguard Worker# 7*7594170eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*7594170eSAndroid Build Coastguard Worker# 9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*7594170eSAndroid Build Coastguard Worker# limitations under the License. 14*7594170eSAndroid Build Coastguard Worker 15*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths") 16*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules:proto_file_utils.bzl", "proto_file_utils") 17*7594170eSAndroid Build Coastguard Worker 18*7594170eSAndroid Build Coastguard Worker_TYPE_DICTIONARY = {".py": "_pb2.py"} 19*7594170eSAndroid Build Coastguard Worker 20*7594170eSAndroid Build Coastguard Workerdef _py_proto_sources_gen_rule_impl(ctx): 21*7594170eSAndroid Build Coastguard Worker out_files_map = proto_file_utils.generate_proto_action( 22*7594170eSAndroid Build Coastguard Worker proto_infos = [dep[ProtoInfo] for dep in ctx.attr.deps], 23*7594170eSAndroid Build Coastguard Worker protoc = ctx.executable._protoc, 24*7594170eSAndroid Build Coastguard Worker ctx = ctx, 25*7594170eSAndroid Build Coastguard Worker type_dictionary = _TYPE_DICTIONARY, 26*7594170eSAndroid Build Coastguard Worker out_flags = [], 27*7594170eSAndroid Build Coastguard Worker plugin_executable = None, 28*7594170eSAndroid Build Coastguard Worker out_arg = "--python_out", 29*7594170eSAndroid Build Coastguard Worker mnemonic = "PyProtoGen", 30*7594170eSAndroid Build Coastguard Worker transitive_proto_infos = [dep[ProtoInfo] for dep in ctx.attr.transitive_deps], 31*7594170eSAndroid Build Coastguard Worker ) 32*7594170eSAndroid Build Coastguard Worker 33*7594170eSAndroid Build Coastguard Worker # proto_file_utils generates the files at <package>/<label> 34*7594170eSAndroid Build Coastguard Worker # interesting examples 35*7594170eSAndroid Build Coastguard Worker # 1. foo.proto will be generated in <package>/<label>/foo_pb2.py 36*7594170eSAndroid Build Coastguard Worker # 2. foo.proto with an import prefix in proto_library will be generated in <package>/<label>/<import_prefix>/foo_pb2.py 37*7594170eSAndroid Build Coastguard Worker imports = [paths.join("__main__", ctx.label.package, ctx.label.name)] 38*7594170eSAndroid Build Coastguard Worker 39*7594170eSAndroid Build Coastguard Worker output_depset = depset(direct = out_files_map[".py"]) 40*7594170eSAndroid Build Coastguard Worker 41*7594170eSAndroid Build Coastguard Worker return [ 42*7594170eSAndroid Build Coastguard Worker DefaultInfo(files = output_depset), 43*7594170eSAndroid Build Coastguard Worker PyInfo( 44*7594170eSAndroid Build Coastguard Worker transitive_sources = output_depset, 45*7594170eSAndroid Build Coastguard Worker imports = depset(direct = imports), 46*7594170eSAndroid Build Coastguard Worker ), 47*7594170eSAndroid Build Coastguard Worker ] 48*7594170eSAndroid Build Coastguard Worker 49*7594170eSAndroid Build Coastguard Worker_py_proto_sources_gen = rule( 50*7594170eSAndroid Build Coastguard Worker implementation = _py_proto_sources_gen_rule_impl, 51*7594170eSAndroid Build Coastguard Worker attrs = { 52*7594170eSAndroid Build Coastguard Worker "deps": attr.label_list( 53*7594170eSAndroid Build Coastguard Worker providers = [ProtoInfo], 54*7594170eSAndroid Build Coastguard Worker doc = "proto_library or any other target exposing ProtoInfo provider with *.proto files", 55*7594170eSAndroid Build Coastguard Worker mandatory = True, 56*7594170eSAndroid Build Coastguard Worker ), 57*7594170eSAndroid Build Coastguard Worker "transitive_deps": attr.label_list( 58*7594170eSAndroid Build Coastguard Worker providers = [ProtoInfo], 59*7594170eSAndroid Build Coastguard Worker doc = """ 60*7594170eSAndroid Build Coastguard Workerproto_library that will be added to aprotoc -I when compiling the direct .proto sources. 61*7594170eSAndroid Build Coastguard WorkerWARNING: This is an experimental attribute and is expected to be deprecated in the future. 62*7594170eSAndroid Build Coastguard Worker""", 63*7594170eSAndroid Build Coastguard Worker ), 64*7594170eSAndroid Build Coastguard Worker "_protoc": attr.label( 65*7594170eSAndroid Build Coastguard Worker default = Label("//external/protobuf:aprotoc"), 66*7594170eSAndroid Build Coastguard Worker executable = True, 67*7594170eSAndroid Build Coastguard Worker cfg = "exec", 68*7594170eSAndroid Build Coastguard Worker ), 69*7594170eSAndroid Build Coastguard Worker }, 70*7594170eSAndroid Build Coastguard Worker) 71*7594170eSAndroid Build Coastguard Worker 72*7594170eSAndroid Build Coastguard Workerdef py_proto_library( 73*7594170eSAndroid Build Coastguard Worker name, 74*7594170eSAndroid Build Coastguard Worker deps = [], 75*7594170eSAndroid Build Coastguard Worker transitive_deps = [], 76*7594170eSAndroid Build Coastguard Worker target_compatible_with = [], 77*7594170eSAndroid Build Coastguard Worker data = [], 78*7594170eSAndroid Build Coastguard Worker **kwargs): 79*7594170eSAndroid Build Coastguard Worker proto_lib_name = name + "_proto_gen" 80*7594170eSAndroid Build Coastguard Worker 81*7594170eSAndroid Build Coastguard Worker _py_proto_sources_gen( 82*7594170eSAndroid Build Coastguard Worker name = proto_lib_name, 83*7594170eSAndroid Build Coastguard Worker deps = deps, 84*7594170eSAndroid Build Coastguard Worker transitive_deps = transitive_deps, 85*7594170eSAndroid Build Coastguard Worker **kwargs 86*7594170eSAndroid Build Coastguard Worker ) 87*7594170eSAndroid Build Coastguard Worker 88*7594170eSAndroid Build Coastguard Worker # There may be a better way to do this, but proto_lib_name appears in both srcs 89*7594170eSAndroid Build Coastguard Worker # and deps because it must appear in srcs to cause the protobuf files to 90*7594170eSAndroid Build Coastguard Worker # actually be compiled, and it must appear in deps for the PyInfo provider to 91*7594170eSAndroid Build Coastguard Worker # be respected and the "imports" path to be included in this library. 92*7594170eSAndroid Build Coastguard Worker native.py_library( 93*7594170eSAndroid Build Coastguard Worker name = name, 94*7594170eSAndroid Build Coastguard Worker srcs = [":" + proto_lib_name], 95*7594170eSAndroid Build Coastguard Worker deps = [":" + proto_lib_name] + (["//external/protobuf:libprotobuf-python"] if "libprotobuf-python" not in name else []), 96*7594170eSAndroid Build Coastguard Worker data = data, 97*7594170eSAndroid Build Coastguard Worker target_compatible_with = target_compatible_with, 98*7594170eSAndroid Build Coastguard Worker **kwargs 99*7594170eSAndroid Build Coastguard Worker ) 100