1load("@bazel_skylib//lib:paths.bzl", "paths") 2 3# Generic support code ######################################################### 4 5_is_bazel = not hasattr(native, "genmpm") 6 7def _get_real_short_path(file): 8 # For some reason, files from other archives have short paths that look like: 9 # ../com_google_protobuf/google/protobuf/descriptor.proto 10 short_path = file.short_path 11 if short_path.startswith("../"): 12 second_slash = short_path.index("/", 3) 13 short_path = short_path[second_slash + 1:] 14 15 # Sometimes it has another few prefixes like: 16 # _virtual_imports/any_proto/google/protobuf/any.proto 17 # We want just google/protobuf/any.proto. 18 if short_path.startswith("_virtual_imports"): 19 short_path = short_path.split("/", 2)[-1] 20 return short_path 21 22def _get_real_root(file): 23 real_short_path = _get_real_short_path(file) 24 return file.path[:-len(real_short_path) - 1] 25 26def _generate_output_file(ctx, src, extension): 27 real_short_path = _get_real_short_path(src) 28 real_short_path = paths.relativize(real_short_path, ctx.label.package) 29 output_filename = paths.replace_extension(real_short_path, extension) 30 ret = ctx.actions.declare_file(output_filename) 31 return ret 32 33# upb_proto_library / upb_proto_reflection_library shared code ################# 34 35_LuaFiles = provider(fields = ["files"]) 36 37def _compile_upb_protos(ctx, proto_info, proto_sources): 38 files = [_generate_output_file(ctx, name, "_pb.lua") for name in proto_sources] 39 transitive_sets = proto_info.transitive_descriptor_sets.to_list() 40 ctx.actions.run( 41 inputs = depset( 42 direct = [proto_info.direct_descriptor_set], 43 transitive = [proto_info.transitive_descriptor_sets], 44 ), 45 tools = [ctx.executable._upbc], 46 outputs = files, 47 executable = ctx.executable._protoc, 48 arguments = [ 49 "--lua_out=" + _get_real_root(files[0]), 50 "--plugin=protoc-gen-lua=" + ctx.executable._upbc.path, 51 "--descriptor_set_in=" + ctx.configuration.host_path_separator.join([f.path for f in transitive_sets]), 52 ] + 53 [_get_real_short_path(file) for file in proto_sources], 54 progress_message = "Generating Lua protos for :" + ctx.label.name, 55 ) 56 return files 57 58def _lua_proto_rule_impl(ctx): 59 if len(ctx.attr.deps) != 1: 60 fail("only one deps dependency allowed.") 61 dep = ctx.attr.deps[0] 62 if _LuaFiles not in dep: 63 fail("proto_library rule must generate _LuaFiles (aspect should have handled this).") 64 files = dep[_LuaFiles].files 65 return [ 66 DefaultInfo( 67 files = files, 68 data_runfiles = ctx.runfiles(files = files.to_list()), 69 ), 70 ] 71 72def _lua_proto_library_aspect_impl(target, ctx): 73 proto_info = target[ProtoInfo] 74 files = _compile_upb_protos(ctx, proto_info, proto_info.direct_sources) 75 deps = ctx.rule.attr.deps 76 transitive = [dep[_LuaFiles].files for dep in deps if _LuaFiles in dep] 77 return [_LuaFiles(files = depset(direct = files, transitive = transitive))] 78 79# lua_proto_library() ########################################################## 80 81_lua_proto_library_aspect = aspect( 82 attrs = { 83 "_upbc": attr.label( 84 executable = True, 85 cfg = "host", 86 default = "//upb/bindings/lua:protoc-gen-lua", 87 ), 88 "_protoc": attr.label( 89 executable = True, 90 cfg = "host", 91 default = "@com_google_protobuf//:protoc", 92 ), 93 }, 94 implementation = _lua_proto_library_aspect_impl, 95 provides = [_LuaFiles], 96 attr_aspects = ["deps"], 97 fragments = ["cpp"], 98) 99 100lua_proto_library = rule( 101 output_to_genfiles = True, 102 implementation = _lua_proto_rule_impl, 103 attrs = { 104 "deps": attr.label_list( 105 aspects = [_lua_proto_library_aspect], 106 allow_rules = ["proto_library"], 107 providers = [ProtoInfo], 108 ), 109 }, 110) 111