• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 Google Inc. 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
15package java
16
17import (
18	"path/filepath"
19	"strconv"
20
21	"android/soong/android"
22	"android/soong/bazel"
23
24	"github.com/google/blueprint/proptools"
25)
26
27const (
28	protoTypeDefault = "lite"
29)
30
31func genProto(ctx android.ModuleContext, protoFiles android.Paths, flags android.ProtoFlags) android.Paths {
32	// Shard proto files into groups of 100 to avoid having to recompile all of them if one changes and to avoid
33	// hitting command line length limits.
34	shards := android.ShardPaths(protoFiles, 50)
35
36	srcJarFiles := make(android.Paths, 0, len(shards))
37
38	for i, shard := range shards {
39		srcJarFile := android.PathForModuleGen(ctx, "proto", "proto"+strconv.Itoa(i)+".srcjar")
40		srcJarFiles = append(srcJarFiles, srcJarFile)
41
42		outDir := srcJarFile.ReplaceExtension(ctx, "tmp")
43
44		rule := android.NewRuleBuilder(pctx, ctx)
45
46		rule.Command().Text("rm -rf").Flag(outDir.String())
47		rule.Command().Text("mkdir -p").Flag(outDir.String())
48
49		for _, protoFile := range shard {
50			depFile := srcJarFile.InSameDir(ctx, protoFile.String()+".d")
51			rule.Command().Text("mkdir -p").Flag(filepath.Dir(depFile.String()))
52			android.ProtoRule(rule, protoFile, flags, flags.Deps, outDir, depFile, nil)
53		}
54
55		// Proto generated java files have an unknown package name in the path, so package the entire output directory
56		// into a srcjar.
57		rule.Command().
58			BuiltTool("soong_zip").
59			Flag("-srcjar").
60			Flag("-write_if_changed").
61			FlagWithOutput("-o ", srcJarFile).
62			FlagWithArg("-C ", outDir.String()).
63			FlagWithArg("-D ", outDir.String())
64
65		rule.Command().Text("rm -rf").Flag(outDir.String())
66
67		rule.Restat()
68
69		ruleName := "protoc"
70		ruleDesc := "protoc"
71		if len(shards) > 1 {
72			ruleName += "_" + strconv.Itoa(i)
73			ruleDesc += " " + strconv.Itoa(i)
74		}
75
76		rule.Build(ruleName, ruleDesc)
77	}
78
79	return srcJarFiles
80}
81
82func protoDeps(ctx android.BottomUpMutatorContext, p *android.ProtoProperties) {
83	const unspecifiedProtobufPluginType = ""
84	if String(p.Proto.Plugin) == "" {
85		switch String(p.Proto.Type) {
86		case "stream": // does not require additional dependencies
87		case "micro":
88			ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-micro")
89		case "nano":
90			ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-nano")
91		case "lite", unspecifiedProtobufPluginType:
92			ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-lite")
93		case "full":
94			if ctx.Host() {
95				ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-full")
96			} else {
97				ctx.PropertyErrorf("proto.type", "full java protos only supported on the host")
98			}
99		default:
100			ctx.PropertyErrorf("proto.type", "unknown proto type %q",
101				String(p.Proto.Type))
102		}
103	}
104}
105
106func protoFlags(ctx android.ModuleContext, j *CommonProperties, p *android.ProtoProperties,
107	flags javaBuilderFlags) javaBuilderFlags {
108
109	flags.proto = android.GetProtoFlags(ctx, p)
110
111	if String(p.Proto.Plugin) == "" {
112		var typeToPlugin string
113		switch String(p.Proto.Type) {
114		case "stream":
115			flags.proto.OutTypeFlag = "--javastream_out"
116			typeToPlugin = "javastream"
117		case "micro":
118			flags.proto.OutTypeFlag = "--javamicro_out"
119			typeToPlugin = "javamicro"
120		case "nano":
121			flags.proto.OutTypeFlag = "--javanano_out"
122			typeToPlugin = "javanano"
123		case "lite", "":
124			flags.proto.OutTypeFlag = "--java_out"
125			flags.proto.OutParams = append(flags.proto.OutParams, "lite")
126		case "full":
127			flags.proto.OutTypeFlag = "--java_out"
128		default:
129			ctx.PropertyErrorf("proto.type", "unknown proto type %q",
130				String(p.Proto.Type))
131		}
132
133		if typeToPlugin != "" {
134			hostTool := ctx.Config().HostToolPath(ctx, "protoc-gen-"+typeToPlugin)
135			flags.proto.Deps = append(flags.proto.Deps, hostTool)
136			flags.proto.Flags = append(flags.proto.Flags, "--plugin=protoc-gen-"+typeToPlugin+"="+hostTool.String())
137		}
138	}
139
140	flags.proto.OutParams = append(flags.proto.OutParams, j.Proto.Output_params...)
141
142	return flags
143}
144
145type protoAttributes struct {
146	Deps         bazel.LabelListAttribute
147	Sdk_version  bazel.StringAttribute
148	Java_version bazel.StringAttribute
149}
150
151func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) *bazel.Label {
152	protoInfo, ok := android.Bp2buildProtoProperties(ctx, &m.ModuleBase, protoSrcs)
153	if !ok {
154		return nil
155	}
156
157	typ := proptools.StringDefault(protoInfo.Type, protoTypeDefault)
158	var rule_class string
159	suffix := "_java_proto"
160	switch typ {
161	case "nano":
162		suffix += "_nano"
163		rule_class = "java_nano_proto_library"
164	case "micro":
165		suffix += "_micro"
166		rule_class = "java_micro_proto_library"
167	case "lite":
168		suffix += "_lite"
169		rule_class = "java_lite_proto_library"
170	case "stream":
171		suffix += "_stream"
172		rule_class = "java_stream_proto_library"
173	case "full":
174		rule_class = "java_proto_library"
175	default:
176		ctx.PropertyErrorf("proto.type", "cannot handle conversion at this time: %q", typ)
177	}
178
179	protoLabel := bazel.Label{Label: ":" + m.Name() + "_proto"}
180	protoAttrs := &protoAttributes{
181		Deps:         bazel.MakeSingleLabelListAttribute(protoLabel),
182		Java_version: bazel.StringAttribute{Value: m.properties.Java_version},
183		Sdk_version:  bazel.StringAttribute{Value: m.deviceProperties.Sdk_version},
184	}
185
186	name := m.Name() + suffix
187
188	ctx.CreateBazelTargetModule(
189		bazel.BazelTargetModuleProperties{
190			Rule_class:        rule_class,
191			Bzl_load_location: "//build/bazel/rules/java:proto.bzl",
192		},
193		android.CommonAttributes{Name: name},
194		protoAttrs)
195
196	return &bazel.Label{Label: ":" + name}
197}
198