• 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 
15 package java
16 
17 import (
18 	"path/filepath"
19 	"strconv"
20 
21 	"android/soong/android"
22 	"android/soong/bazel"
23 
24 	"github.com/google/blueprint/proptools"
25 )
26 
27 const (
28 	protoTypeDefault = "lite"
29 )
30 
31 func 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 
82 func 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() || ctx.BazelConversionMode() {
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 
106 func 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 
145 type protoAttributes struct {
146 	Deps bazel.LabelListAttribute
147 }
148 
149 func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) *bazel.Label {
150 	protoInfo, ok := android.Bp2buildProtoProperties(ctx, &m.ModuleBase, protoSrcs)
151 	if !ok {
152 		return nil
153 	}
154 
155 	typ := proptools.StringDefault(protoInfo.Type, protoTypeDefault)
156 	var rule_class string
157 	suffix := "_java_proto"
158 	switch typ {
159 	case "nano":
160 		suffix += "_nano"
161 		rule_class = "java_nano_proto_library"
162 	case "micro":
163 		suffix += "_micro"
164 		rule_class = "java_micro_proto_library"
165 	case "lite":
166 		suffix += "_lite"
167 		rule_class = "java_lite_proto_library"
168 	case "stream":
169 		suffix += "_stream"
170 		rule_class = "java_stream_proto_library"
171 	case "full":
172 		rule_class = "java_proto_library"
173 	default:
174 		ctx.PropertyErrorf("proto.type", "cannot handle conversion at this time: %q", typ)
175 	}
176 
177 	protoLabel := bazel.Label{Label: ":" + m.Name() + "_proto"}
178 	var protoAttrs protoAttributes
179 	protoAttrs.Deps.SetValue(bazel.LabelList{Includes: []bazel.Label{protoLabel}})
180 
181 	name := m.Name() + suffix
182 
183 	ctx.CreateBazelTargetModule(
184 		bazel.BazelTargetModuleProperties{
185 			Rule_class:        rule_class,
186 			Bzl_load_location: "//build/bazel/rules/java:proto.bzl",
187 		},
188 		android.CommonAttributes{Name: name},
189 		&protoAttrs)
190 
191 	return &bazel.Label{Label: ":" + name}
192 }
193