blob: f88ee2f56f1c5ac728c4510b1b5e8dc86a77fefd [file] [log] [blame]
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +02001"""Generates C++ grpc stubs from proto_library rules.
2
3This is an internal rule used by cc_grpc_library, and shouldn't be used
4directly.
5"""
6
7def generate_cc_impl(ctx):
Nicolas "Pixel" Noble799bd5e2016-10-21 01:54:32 +02008 """Implementation of the generate_cc rule."""
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +02009 protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources]
10 includes = [f for src in ctx.attr.srcs for f in src.proto.transitive_imports]
11 outs = []
Makarand Dharmapurikarc872a992017-04-17 16:36:00 -070012 # label_len is length of the path from WORKSPACE root to the location of this build file
13 label_len = len(ctx.label.package) + 1
Nicolas "Pixel" Noble799bd5e2016-10-21 01:54:32 +020014 if ctx.executable.plugin:
Makarand Dharmapurikarc872a992017-04-17 16:36:00 -070015 outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.h" for proto in protos]
16 outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.cc" for proto in protos]
Mahak Mukhi78f12e52017-04-16 21:24:16 -070017 if ctx.attr.generate_mock:
Makarand Dharmapurikar28079512017-04-25 09:39:33 -070018 outs += [proto.path[label_len:-len(".proto")] + "_mock.grpc.pb.h" for proto in protos]
Nicolas "Pixel" Noble799bd5e2016-10-21 01:54:32 +020019 else:
Makarand Dharmapurikarc872a992017-04-17 16:36:00 -070020 outs += [proto.path[label_len:-len(".proto")] + ".pb.h" for proto in protos]
21 outs += [proto.path[label_len:-len(".proto")] + ".pb.cc" for proto in protos]
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020022 out_files = [ctx.new_file(out) for out in outs]
Makarand Dharmapurikarc872a992017-04-17 16:36:00 -070023 dir_out = str(ctx.genfiles_dir.path)
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020024
25 arguments = []
Nicolas "Pixel" Noble799bd5e2016-10-21 01:54:32 +020026 if ctx.executable.plugin:
27 arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path]
Mahak Mukhi459da912017-04-16 20:44:04 -070028 flags = list(ctx.attr.flags)
Mahak Mukhi443a75d2017-04-14 15:33:55 -070029 if ctx.attr.generate_mock:
Mahak Mukhi459da912017-04-16 20:44:04 -070030 flags.append("generate_mock_code=true")
31 arguments += ["--PLUGIN_out=" + ",".join(flags) + ":" + dir_out]
Nicolas "Pixel" Noble24263c32017-01-11 01:03:09 +010032 additional_input = [ctx.executable.plugin]
Nicolas "Pixel" Noble799bd5e2016-10-21 01:54:32 +020033 else:
34 arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out]
Nicolas "Pixel" Noble24263c32017-01-11 01:03:09 +010035 additional_input = []
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020036 arguments += ["-I{0}={0}".format(include.path) for include in includes]
37 arguments += [proto.path for proto in protos]
38
Makarand Dharmapurikare3e3b2a2017-03-07 16:12:56 -080039 # create a list of well known proto files if the argument is non-None
40 well_known_proto_files = []
41 if ctx.attr.well_known_protos:
42 f = ctx.attr.well_known_protos.files.to_list()[0].dirname
Vijay Paif74eaa62017-04-14 17:19:52 -070043 if f != "external/com_google_protobuf/src/google/protobuf":
44 print("Error: Only @com_google_protobuf//:well_known_protos is supported")
Makarand Dharmapurikare3e3b2a2017-03-07 16:12:56 -080045 else:
Vijay Paif74eaa62017-04-14 17:19:52 -070046 # f points to "external/com_google_protobuf/src/google/protobuf"
Makarand Dharmapurikare3e3b2a2017-03-07 16:12:56 -080047 # add -I argument to protoc so it knows where to look for the proto files.
48 arguments += ["-I{0}".format(f + "/../..")]
49 well_known_proto_files = [f for f in ctx.attr.well_known_protos.files]
50
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020051 ctx.action(
Makarand Dharmapurikare3e3b2a2017-03-07 16:12:56 -080052 inputs = protos + includes + additional_input + well_known_proto_files,
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020053 outputs = out_files,
54 executable = ctx.executable._protoc,
55 arguments = arguments,
56 )
57
Vladimir Moskva759c7022017-09-14 15:40:27 +020058 return struct(files=depset(out_files))
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020059
Craig Tillera7533712017-05-16 13:09:33 -070060_generate_cc = rule(
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020061 attrs = {
62 "srcs": attr.label_list(
63 mandatory = True,
64 non_empty = True,
65 providers = ["proto"],
66 ),
67 "plugin": attr.label(
68 executable = True,
69 providers = ["files_to_run"],
Nicolas "Pixel" Noble799bd5e2016-10-21 01:54:32 +020070 cfg = "host",
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020071 ),
72 "flags": attr.string_list(
Nicolas "Pixel" Noble799bd5e2016-10-21 01:54:32 +020073 mandatory = False,
74 allow_empty = True,
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020075 ),
Makarand Dharmapurikare3e3b2a2017-03-07 16:12:56 -080076 "well_known_protos" : attr.label(
77 mandatory = False,
78 ),
Mahak Mukhi443a75d2017-04-14 15:33:55 -070079 "generate_mock" : attr.bool(
80 default = False,
81 mandatory = False,
82 ),
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020083 "_protoc": attr.label(
Nicolas "Pixel" Noble799bd5e2016-10-21 01:54:32 +020084 default = Label("//external:protocol_compiler"),
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020085 executable = True,
Nicolas "Pixel" Noble799bd5e2016-10-21 01:54:32 +020086 cfg = "host",
Nicolas "Pixel" Noble4dc64312016-10-20 23:07:37 +020087 ),
88 },
89 # We generate .h files, so we need to output to genfiles.
90 output_to_genfiles = True,
91 implementation = generate_cc_impl,
92)
Craig Tillera7533712017-05-16 13:09:33 -070093
94def generate_cc(well_known_protos, **kwargs):
95 if well_known_protos:
96 _generate_cc(well_known_protos="@com_google_protobuf//:well_known_protos", **kwargs)
97 else:
98 _generate_cc(**kwargs)