1 """Utility functions for generating protobuf code."""
3 _PROTO_EXTENSION = ".proto"
5 def well_known_proto_libs():
7 "@com_google_protobuf//:any_proto",
8 "@com_google_protobuf//:api_proto",
9 "@com_google_protobuf//:compiler_plugin_proto",
10 "@com_google_protobuf//:descriptor_proto",
11 "@com_google_protobuf//:duration_proto",
12 "@com_google_protobuf//:empty_proto",
13 "@com_google_protobuf//:field_mask_proto",
14 "@com_google_protobuf//:source_context_proto",
15 "@com_google_protobuf//:struct_proto",
16 "@com_google_protobuf//:timestamp_proto",
17 "@com_google_protobuf//:type_proto",
18 "@com_google_protobuf//:wrappers_proto",
21 def get_proto_root(workspace_root):
22 """Gets the root protobuf directory.
25 workspace_root: context.label.workspace_root
28 The directory relative to which generated include paths should be.
31 return "/{}".format(workspace_root)
35 def _strip_proto_extension(proto_filename):
36 if not proto_filename.endswith(_PROTO_EXTENSION):
37 fail('"{}" does not end with "{}"'.format(
41 return proto_filename[:-len(_PROTO_EXTENSION)]
43 def proto_path_to_generated_filename(proto_path, fmt_str):
44 """Calculates the name of a generated file for a protobuf path.
46 For example, "examples/protos/helloworld.proto" might map to
50 proto_path: The path to the .proto file.
51 fmt_str: A format string used to calculate the generated filename. For
52 example, "{}.pb.h" might be used to calculate a C++ header filename.
55 The generated filename.
57 return fmt_str.format(_strip_proto_extension(proto_path))
59 def _get_include_directory(include):
60 directory = include.path
62 if not include.is_source and directory.startswith(include.root.path):
63 prefix_len = len(include.root.path) + 1
65 if directory.startswith("external", prefix_len):
66 external_separator = directory.find("/", prefix_len)
67 repository_separator = directory.find("/", external_separator + 1)
68 return directory[:repository_separator]
70 return include.root.path if include.root.path else "."
72 def get_include_protoc_args(includes):
73 """Returns protoc args that imports protos relative to their import root.
76 includes: A list of included proto files.
79 A list of arguments to be passed to protoc. For example, ["--proto_path=."].
82 "--proto_path={}".format(_get_include_directory(include))
83 for include in includes
86 def get_plugin_args(plugin, flags, dir_out, generate_mocks):
87 """Returns arguments configuring protoc to use a plugin for a language.
90 plugin: An executable file to run as the protoc plugin.
91 flags: The plugin flags to be passed to protoc.
92 dir_out: The output directory for the plugin.
93 generate_mocks: A bool indicating whether to generate mocks.
96 A list of protoc arguments configuring the plugin.
98 augmented_flags = list(flags)
100 augmented_flags.append("generate_mock_code=true")
102 "--plugin=protoc-gen-PLUGIN=" + plugin.path,
103 "--PLUGIN_out=" + ",".join(augmented_flags) + ":" + dir_out,