xref: /aosp_15_r20/build/soong/java/droiddoc.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2018 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage java
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
20*333d2b36SAndroid Build Coastguard Worker	"strings"
21*333d2b36SAndroid Build Coastguard Worker
22*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
25*333d2b36SAndroid Build Coastguard Worker	"android/soong/java/config"
26*333d2b36SAndroid Build Coastguard Worker)
27*333d2b36SAndroid Build Coastguard Worker
28*333d2b36SAndroid Build Coastguard Workerfunc init() {
29*333d2b36SAndroid Build Coastguard Worker	RegisterDocsBuildComponents(android.InitRegistrationContext)
30*333d2b36SAndroid Build Coastguard Worker}
31*333d2b36SAndroid Build Coastguard Worker
32*333d2b36SAndroid Build Coastguard Workerfunc RegisterDocsBuildComponents(ctx android.RegistrationContext) {
33*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("doc_defaults", DocDefaultsFactory)
34*333d2b36SAndroid Build Coastguard Worker
35*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("droiddoc", DroiddocFactory)
36*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
37*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
38*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("javadoc", JavadocFactory)
39*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("javadoc_host", JavadocHostFactory)
40*333d2b36SAndroid Build Coastguard Worker}
41*333d2b36SAndroid Build Coastguard Worker
42*333d2b36SAndroid Build Coastguard Workertype JavadocProperties struct {
43*333d2b36SAndroid Build Coastguard Worker	// list of source files used to compile the Java module.  May be .java, .logtags, .proto,
44*333d2b36SAndroid Build Coastguard Worker	// or .aidl files.
45*333d2b36SAndroid Build Coastguard Worker	Srcs []string `android:"path,arch_variant"`
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Worker	// list of source files that should not be used to build the Java module.
48*333d2b36SAndroid Build Coastguard Worker	// This is most useful in the arch/multilib variants to remove non-common files
49*333d2b36SAndroid Build Coastguard Worker	// filegroup or genrule can be included within this property.
50*333d2b36SAndroid Build Coastguard Worker	Exclude_srcs []string `android:"path,arch_variant"`
51*333d2b36SAndroid Build Coastguard Worker
52*333d2b36SAndroid Build Coastguard Worker	// list of package names that should actually be used. If this property is left unspecified,
53*333d2b36SAndroid Build Coastguard Worker	// all the sources from the srcs property is used.
54*333d2b36SAndroid Build Coastguard Worker	Filter_packages []string
55*333d2b36SAndroid Build Coastguard Worker
56*333d2b36SAndroid Build Coastguard Worker	// list of java libraries that will be in the classpath.
57*333d2b36SAndroid Build Coastguard Worker	Libs proptools.Configurable[[]string] `android:"arch_variant"`
58*333d2b36SAndroid Build Coastguard Worker
59*333d2b36SAndroid Build Coastguard Worker	// If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
60*333d2b36SAndroid Build Coastguard Worker	Installable *bool
61*333d2b36SAndroid Build Coastguard Worker
62*333d2b36SAndroid Build Coastguard Worker	// if not blank, set to the version of the sdk to compile against.
63*333d2b36SAndroid Build Coastguard Worker	// Defaults to compiling against the current platform.
64*333d2b36SAndroid Build Coastguard Worker	Sdk_version *string `android:"arch_variant"`
65*333d2b36SAndroid Build Coastguard Worker
66*333d2b36SAndroid Build Coastguard Worker	// When targeting 1.9 and above, override the modules to use with --system,
67*333d2b36SAndroid Build Coastguard Worker	// otherwise provides defaults libraries to add to the bootclasspath.
68*333d2b36SAndroid Build Coastguard Worker	// Defaults to "none"
69*333d2b36SAndroid Build Coastguard Worker	System_modules *string
70*333d2b36SAndroid Build Coastguard Worker
71*333d2b36SAndroid Build Coastguard Worker	Aidl struct {
72*333d2b36SAndroid Build Coastguard Worker		// Top level directories to pass to aidl tool
73*333d2b36SAndroid Build Coastguard Worker		Include_dirs []string
74*333d2b36SAndroid Build Coastguard Worker
75*333d2b36SAndroid Build Coastguard Worker		// Directories rooted at the Android.bp file to pass to aidl tool
76*333d2b36SAndroid Build Coastguard Worker		Local_include_dirs []string
77*333d2b36SAndroid Build Coastguard Worker	}
78*333d2b36SAndroid Build Coastguard Worker
79*333d2b36SAndroid Build Coastguard Worker	// If not blank, set the java version passed to javadoc as -source
80*333d2b36SAndroid Build Coastguard Worker	Java_version *string
81*333d2b36SAndroid Build Coastguard Worker
82*333d2b36SAndroid Build Coastguard Worker	// local files that are used within user customized droiddoc options.
83*333d2b36SAndroid Build Coastguard Worker	Arg_files []string `android:"path"`
84*333d2b36SAndroid Build Coastguard Worker
85*333d2b36SAndroid Build Coastguard Worker	// user customized droiddoc args. Deprecated, use flags instead.
86*333d2b36SAndroid Build Coastguard Worker	// Available variables for substitution:
87*333d2b36SAndroid Build Coastguard Worker	//
88*333d2b36SAndroid Build Coastguard Worker	//  $(location <label>): the path to the arg_files with name <label>
89*333d2b36SAndroid Build Coastguard Worker	//  $$: a literal $
90*333d2b36SAndroid Build Coastguard Worker	Args *string
91*333d2b36SAndroid Build Coastguard Worker
92*333d2b36SAndroid Build Coastguard Worker	// user customized droiddoc args. Not compatible with property args.
93*333d2b36SAndroid Build Coastguard Worker	// Available variables for substitution:
94*333d2b36SAndroid Build Coastguard Worker	//
95*333d2b36SAndroid Build Coastguard Worker	//  $(location <label>): the path to the arg_files with name <label>
96*333d2b36SAndroid Build Coastguard Worker	//  $$: a literal $
97*333d2b36SAndroid Build Coastguard Worker	Flags []string
98*333d2b36SAndroid Build Coastguard Worker
99*333d2b36SAndroid Build Coastguard Worker	// names of the output files used in args that will be generated
100*333d2b36SAndroid Build Coastguard Worker	Out []string
101*333d2b36SAndroid Build Coastguard Worker}
102*333d2b36SAndroid Build Coastguard Worker
103*333d2b36SAndroid Build Coastguard Workertype ApiToCheck struct {
104*333d2b36SAndroid Build Coastguard Worker	// path to the API txt file that the new API extracted from source code is checked
105*333d2b36SAndroid Build Coastguard Worker	// against. The path can be local to the module or from other module (via :module syntax).
106*333d2b36SAndroid Build Coastguard Worker	Api_file *string `android:"path"`
107*333d2b36SAndroid Build Coastguard Worker
108*333d2b36SAndroid Build Coastguard Worker	// path to the API txt file that the new @removed API extractd from source code is
109*333d2b36SAndroid Build Coastguard Worker	// checked against. The path can be local to the module or from other module (via
110*333d2b36SAndroid Build Coastguard Worker	// :module syntax).
111*333d2b36SAndroid Build Coastguard Worker	Removed_api_file *string `android:"path"`
112*333d2b36SAndroid Build Coastguard Worker
113*333d2b36SAndroid Build Coastguard Worker	// If not blank, path to the baseline txt file for approved API check violations.
114*333d2b36SAndroid Build Coastguard Worker	Baseline_file *string `android:"path"`
115*333d2b36SAndroid Build Coastguard Worker
116*333d2b36SAndroid Build Coastguard Worker	// Arguments to the apicheck tool.
117*333d2b36SAndroid Build Coastguard Worker	Args *string
118*333d2b36SAndroid Build Coastguard Worker}
119*333d2b36SAndroid Build Coastguard Worker
120*333d2b36SAndroid Build Coastguard Workertype DroiddocProperties struct {
121*333d2b36SAndroid Build Coastguard Worker	// directory relative to top of the source tree that contains doc templates files.
122*333d2b36SAndroid Build Coastguard Worker	Custom_template *string
123*333d2b36SAndroid Build Coastguard Worker
124*333d2b36SAndroid Build Coastguard Worker	// directories under current module source which contains html/jd files.
125*333d2b36SAndroid Build Coastguard Worker	Html_dirs []string
126*333d2b36SAndroid Build Coastguard Worker
127*333d2b36SAndroid Build Coastguard Worker	// set a value in the Clearsilver hdf namespace.
128*333d2b36SAndroid Build Coastguard Worker	Hdf []string
129*333d2b36SAndroid Build Coastguard Worker
130*333d2b36SAndroid Build Coastguard Worker	// proofread file contains all of the text content of the javadocs concatenated into one file,
131*333d2b36SAndroid Build Coastguard Worker	// suitable for spell-checking and other goodness.
132*333d2b36SAndroid Build Coastguard Worker	Proofread_file *string
133*333d2b36SAndroid Build Coastguard Worker
134*333d2b36SAndroid Build Coastguard Worker	// a todo file lists the program elements that are missing documentation.
135*333d2b36SAndroid Build Coastguard Worker	// At some point, this might be improved to show more warnings.
136*333d2b36SAndroid Build Coastguard Worker	Todo_file *string `android:"path"`
137*333d2b36SAndroid Build Coastguard Worker
138*333d2b36SAndroid Build Coastguard Worker	// A file containing a baseline for allowed lint errors.
139*333d2b36SAndroid Build Coastguard Worker	Lint_baseline *string `android:"path"`
140*333d2b36SAndroid Build Coastguard Worker
141*333d2b36SAndroid Build Coastguard Worker	// directory under current module source that provide additional resources (images).
142*333d2b36SAndroid Build Coastguard Worker	Resourcesdir *string
143*333d2b36SAndroid Build Coastguard Worker
144*333d2b36SAndroid Build Coastguard Worker	// resources output directory under out/soong/.intermediates.
145*333d2b36SAndroid Build Coastguard Worker	Resourcesoutdir *string
146*333d2b36SAndroid Build Coastguard Worker
147*333d2b36SAndroid Build Coastguard Worker	// index.html under current module will be copied to docs out dir, if not null.
148*333d2b36SAndroid Build Coastguard Worker	Static_doc_index_redirect *string `android:"path"`
149*333d2b36SAndroid Build Coastguard Worker
150*333d2b36SAndroid Build Coastguard Worker	// source.properties under current module will be copied to docs out dir, if not null.
151*333d2b36SAndroid Build Coastguard Worker	Static_doc_properties *string `android:"path"`
152*333d2b36SAndroid Build Coastguard Worker
153*333d2b36SAndroid Build Coastguard Worker	// a list of files under current module source dir which contains known tags in Java sources.
154*333d2b36SAndroid Build Coastguard Worker	// filegroup or genrule can be included within this property.
155*333d2b36SAndroid Build Coastguard Worker	Knowntags []string `android:"path"`
156*333d2b36SAndroid Build Coastguard Worker
157*333d2b36SAndroid Build Coastguard Worker	// if set to true, generate docs through Dokka instead of Doclava.
158*333d2b36SAndroid Build Coastguard Worker	Dokka_enabled *bool
159*333d2b36SAndroid Build Coastguard Worker
160*333d2b36SAndroid Build Coastguard Worker	// Compat config XML. Generates compat change documentation if set.
161*333d2b36SAndroid Build Coastguard Worker	Compat_config *string `android:"path"`
162*333d2b36SAndroid Build Coastguard Worker}
163*333d2b36SAndroid Build Coastguard Worker
164*333d2b36SAndroid Build Coastguard Worker// Common flags passed down to build rule
165*333d2b36SAndroid Build Coastguard Workertype droiddocBuilderFlags struct {
166*333d2b36SAndroid Build Coastguard Worker	bootClasspathArgs  string
167*333d2b36SAndroid Build Coastguard Worker	classpathArgs      string
168*333d2b36SAndroid Build Coastguard Worker	sourcepathArgs     string
169*333d2b36SAndroid Build Coastguard Worker	dokkaClasspathArgs string
170*333d2b36SAndroid Build Coastguard Worker	aidlFlags          string
171*333d2b36SAndroid Build Coastguard Worker	aidlDeps           android.Paths
172*333d2b36SAndroid Build Coastguard Worker
173*333d2b36SAndroid Build Coastguard Worker	doclavaStubsFlags string
174*333d2b36SAndroid Build Coastguard Worker	doclavaDocsFlags  string
175*333d2b36SAndroid Build Coastguard Worker	postDoclavaCmds   string
176*333d2b36SAndroid Build Coastguard Worker}
177*333d2b36SAndroid Build Coastguard Worker
178*333d2b36SAndroid Build Coastguard Workerfunc InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
179*333d2b36SAndroid Build Coastguard Worker	android.InitAndroidArchModule(module, hod, android.MultilibCommon)
180*333d2b36SAndroid Build Coastguard Worker	android.InitDefaultableModule(module)
181*333d2b36SAndroid Build Coastguard Worker}
182*333d2b36SAndroid Build Coastguard Worker
183*333d2b36SAndroid Build Coastguard Workerfunc apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
184*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
185*333d2b36SAndroid Build Coastguard Worker		if ctx.Config().BuildFromTextStub() {
186*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("Generating stubs from api signature files is not available " +
187*333d2b36SAndroid Build Coastguard Worker				"with WITHOUT_CHECK_API=true, as sync between the source Java files and the " +
188*333d2b36SAndroid Build Coastguard Worker				"api signature files is not guaranteed.\n" +
189*333d2b36SAndroid Build Coastguard Worker				"In order to utilize WITHOUT_CHECK_API, generate stubs from the source Java " +
190*333d2b36SAndroid Build Coastguard Worker				"files with BUILD_FROM_SOURCE_STUB=true.\n" +
191*333d2b36SAndroid Build Coastguard Worker				"However, the usage of WITHOUT_CHECK_API is not preferred as the incremental " +
192*333d2b36SAndroid Build Coastguard Worker				"build is slower when generating stubs from the source Java files.\n" +
193*333d2b36SAndroid Build Coastguard Worker				"Consider updating the api signature files and generating the stubs from " +
194*333d2b36SAndroid Build Coastguard Worker				"them instead.")
195*333d2b36SAndroid Build Coastguard Worker		}
196*333d2b36SAndroid Build Coastguard Worker		return false
197*333d2b36SAndroid Build Coastguard Worker	} else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
198*333d2b36SAndroid Build Coastguard Worker		return true
199*333d2b36SAndroid Build Coastguard Worker	} else if String(apiToCheck.Api_file) != "" {
200*333d2b36SAndroid Build Coastguard Worker		panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
201*333d2b36SAndroid Build Coastguard Worker	} else if String(apiToCheck.Removed_api_file) != "" {
202*333d2b36SAndroid Build Coastguard Worker		panic("for " + apiVersionTag + " api_file has to be non-empty!")
203*333d2b36SAndroid Build Coastguard Worker	}
204*333d2b36SAndroid Build Coastguard Worker
205*333d2b36SAndroid Build Coastguard Worker	return false
206*333d2b36SAndroid Build Coastguard Worker}
207*333d2b36SAndroid Build Coastguard Worker
208*333d2b36SAndroid Build Coastguard Worker// Javadoc
209*333d2b36SAndroid Build Coastguard Workertype Javadoc struct {
210*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
211*333d2b36SAndroid Build Coastguard Worker	android.DefaultableModuleBase
212*333d2b36SAndroid Build Coastguard Worker
213*333d2b36SAndroid Build Coastguard Worker	properties JavadocProperties
214*333d2b36SAndroid Build Coastguard Worker
215*333d2b36SAndroid Build Coastguard Worker	srcJars     android.Paths
216*333d2b36SAndroid Build Coastguard Worker	srcFiles    android.Paths
217*333d2b36SAndroid Build Coastguard Worker	sourcepaths android.Paths
218*333d2b36SAndroid Build Coastguard Worker	implicits   android.Paths
219*333d2b36SAndroid Build Coastguard Worker
220*333d2b36SAndroid Build Coastguard Worker	docZip      android.WritablePath
221*333d2b36SAndroid Build Coastguard Worker	stubsSrcJar android.WritablePath
222*333d2b36SAndroid Build Coastguard Worker
223*333d2b36SAndroid Build Coastguard Worker	exportableStubsSrcJar android.WritablePath
224*333d2b36SAndroid Build Coastguard Worker}
225*333d2b36SAndroid Build Coastguard Worker
226*333d2b36SAndroid Build Coastguard Worker// javadoc converts .java source files to documentation using javadoc.
227*333d2b36SAndroid Build Coastguard Workerfunc JavadocFactory() android.Module {
228*333d2b36SAndroid Build Coastguard Worker	module := &Javadoc{}
229*333d2b36SAndroid Build Coastguard Worker
230*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties)
231*333d2b36SAndroid Build Coastguard Worker
232*333d2b36SAndroid Build Coastguard Worker	InitDroiddocModule(module, android.HostAndDeviceSupported)
233*333d2b36SAndroid Build Coastguard Worker	return module
234*333d2b36SAndroid Build Coastguard Worker}
235*333d2b36SAndroid Build Coastguard Worker
236*333d2b36SAndroid Build Coastguard Worker// javadoc_host converts .java source files to documentation using javadoc.
237*333d2b36SAndroid Build Coastguard Workerfunc JavadocHostFactory() android.Module {
238*333d2b36SAndroid Build Coastguard Worker	module := &Javadoc{}
239*333d2b36SAndroid Build Coastguard Worker
240*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties)
241*333d2b36SAndroid Build Coastguard Worker
242*333d2b36SAndroid Build Coastguard Worker	InitDroiddocModule(module, android.HostSupported)
243*333d2b36SAndroid Build Coastguard Worker	return module
244*333d2b36SAndroid Build Coastguard Worker}
245*333d2b36SAndroid Build Coastguard Worker
246*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
247*333d2b36SAndroid Build Coastguard Worker	return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version))
248*333d2b36SAndroid Build Coastguard Worker}
249*333d2b36SAndroid Build Coastguard Worker
250*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) SystemModules() string {
251*333d2b36SAndroid Build Coastguard Worker	return proptools.String(j.properties.System_modules)
252*333d2b36SAndroid Build Coastguard Worker}
253*333d2b36SAndroid Build Coastguard Worker
254*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
255*333d2b36SAndroid Build Coastguard Worker	return j.SdkVersion(ctx).ApiLevel
256*333d2b36SAndroid Build Coastguard Worker}
257*333d2b36SAndroid Build Coastguard Worker
258*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
259*333d2b36SAndroid Build Coastguard Worker	return j.SdkVersion(ctx).ApiLevel
260*333d2b36SAndroid Build Coastguard Worker}
261*333d2b36SAndroid Build Coastguard Worker
262*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
263*333d2b36SAndroid Build Coastguard Worker	return j.SdkVersion(ctx).ApiLevel
264*333d2b36SAndroid Build Coastguard Worker}
265*333d2b36SAndroid Build Coastguard Worker
266*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
267*333d2b36SAndroid Build Coastguard Worker	if ctx.Device() {
268*333d2b36SAndroid Build Coastguard Worker		sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
269*333d2b36SAndroid Build Coastguard Worker		if sdkDep.useModule {
270*333d2b36SAndroid Build Coastguard Worker			ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
271*333d2b36SAndroid Build Coastguard Worker			ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
272*333d2b36SAndroid Build Coastguard Worker			ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
273*333d2b36SAndroid Build Coastguard Worker			ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...)
274*333d2b36SAndroid Build Coastguard Worker		}
275*333d2b36SAndroid Build Coastguard Worker	}
276*333d2b36SAndroid Build Coastguard Worker
277*333d2b36SAndroid Build Coastguard Worker	ctx.AddVariationDependencies(nil, libTag, j.properties.Libs.GetOrDefault(ctx, nil)...)
278*333d2b36SAndroid Build Coastguard Worker}
279*333d2b36SAndroid Build Coastguard Worker
280*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
281*333d2b36SAndroid Build Coastguard Worker	var flags droiddocBuilderFlags
282*333d2b36SAndroid Build Coastguard Worker
283*333d2b36SAndroid Build Coastguard Worker	flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
284*333d2b36SAndroid Build Coastguard Worker
285*333d2b36SAndroid Build Coastguard Worker	return flags
286*333d2b36SAndroid Build Coastguard Worker}
287*333d2b36SAndroid Build Coastguard Worker
288*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
289*333d2b36SAndroid Build Coastguard Worker	aidlIncludeDirs android.Paths) (string, android.Paths) {
290*333d2b36SAndroid Build Coastguard Worker
291*333d2b36SAndroid Build Coastguard Worker	aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
292*333d2b36SAndroid Build Coastguard Worker	aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
293*333d2b36SAndroid Build Coastguard Worker
294*333d2b36SAndroid Build Coastguard Worker	var flags []string
295*333d2b36SAndroid Build Coastguard Worker	var deps android.Paths
296*333d2b36SAndroid Build Coastguard Worker
297*333d2b36SAndroid Build Coastguard Worker	if aidlPreprocess.Valid() {
298*333d2b36SAndroid Build Coastguard Worker		flags = append(flags, "-p"+aidlPreprocess.String())
299*333d2b36SAndroid Build Coastguard Worker		deps = append(deps, aidlPreprocess.Path())
300*333d2b36SAndroid Build Coastguard Worker	} else {
301*333d2b36SAndroid Build Coastguard Worker		flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
302*333d2b36SAndroid Build Coastguard Worker	}
303*333d2b36SAndroid Build Coastguard Worker
304*333d2b36SAndroid Build Coastguard Worker	flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
305*333d2b36SAndroid Build Coastguard Worker	flags = append(flags, "-I"+ctx.ModuleDir())
306*333d2b36SAndroid Build Coastguard Worker	if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
307*333d2b36SAndroid Build Coastguard Worker		flags = append(flags, "-I"+src.String())
308*333d2b36SAndroid Build Coastguard Worker	}
309*333d2b36SAndroid Build Coastguard Worker
310*333d2b36SAndroid Build Coastguard Worker	minSdkVersion := j.MinSdkVersion(ctx).FinalOrFutureInt()
311*333d2b36SAndroid Build Coastguard Worker	flags = append(flags, fmt.Sprintf("--min_sdk_version=%v", minSdkVersion))
312*333d2b36SAndroid Build Coastguard Worker
313*333d2b36SAndroid Build Coastguard Worker	return strings.Join(flags, " "), deps
314*333d2b36SAndroid Build Coastguard Worker}
315*333d2b36SAndroid Build Coastguard Worker
316*333d2b36SAndroid Build Coastguard Worker// TODO: remove the duplication between this and the one in gen.go
317*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
318*333d2b36SAndroid Build Coastguard Worker	flags droiddocBuilderFlags) android.Paths {
319*333d2b36SAndroid Build Coastguard Worker
320*333d2b36SAndroid Build Coastguard Worker	outSrcFiles := make(android.Paths, 0, len(srcFiles))
321*333d2b36SAndroid Build Coastguard Worker	var aidlSrcs android.Paths
322*333d2b36SAndroid Build Coastguard Worker
323*333d2b36SAndroid Build Coastguard Worker	aidlIncludeFlags := genAidlIncludeFlags(ctx, srcFiles, android.Paths{})
324*333d2b36SAndroid Build Coastguard Worker
325*333d2b36SAndroid Build Coastguard Worker	for _, srcFile := range srcFiles {
326*333d2b36SAndroid Build Coastguard Worker		switch srcFile.Ext() {
327*333d2b36SAndroid Build Coastguard Worker		case ".aidl":
328*333d2b36SAndroid Build Coastguard Worker			aidlSrcs = append(aidlSrcs, srcFile)
329*333d2b36SAndroid Build Coastguard Worker		case ".logtags":
330*333d2b36SAndroid Build Coastguard Worker			javaFile := genLogtags(ctx, srcFile)
331*333d2b36SAndroid Build Coastguard Worker			outSrcFiles = append(outSrcFiles, javaFile)
332*333d2b36SAndroid Build Coastguard Worker		default:
333*333d2b36SAndroid Build Coastguard Worker			outSrcFiles = append(outSrcFiles, srcFile)
334*333d2b36SAndroid Build Coastguard Worker		}
335*333d2b36SAndroid Build Coastguard Worker	}
336*333d2b36SAndroid Build Coastguard Worker
337*333d2b36SAndroid Build Coastguard Worker	// Process all aidl files together to support sharding them into one or more rules that produce srcjars.
338*333d2b36SAndroid Build Coastguard Worker	if len(aidlSrcs) > 0 {
339*333d2b36SAndroid Build Coastguard Worker		srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, nil, flags.aidlDeps)
340*333d2b36SAndroid Build Coastguard Worker		outSrcFiles = append(outSrcFiles, srcJarFiles...)
341*333d2b36SAndroid Build Coastguard Worker	}
342*333d2b36SAndroid Build Coastguard Worker
343*333d2b36SAndroid Build Coastguard Worker	return outSrcFiles
344*333d2b36SAndroid Build Coastguard Worker}
345*333d2b36SAndroid Build Coastguard Worker
346*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
347*333d2b36SAndroid Build Coastguard Worker	var deps deps
348*333d2b36SAndroid Build Coastguard Worker
349*333d2b36SAndroid Build Coastguard Worker	sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
350*333d2b36SAndroid Build Coastguard Worker	if sdkDep.invalidVersion {
351*333d2b36SAndroid Build Coastguard Worker		ctx.AddMissingDependencies(sdkDep.bootclasspath)
352*333d2b36SAndroid Build Coastguard Worker		ctx.AddMissingDependencies(sdkDep.java9Classpath)
353*333d2b36SAndroid Build Coastguard Worker	} else if sdkDep.useFiles {
354*333d2b36SAndroid Build Coastguard Worker		deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
355*333d2b36SAndroid Build Coastguard Worker		deps.aidlPreprocess = sdkDep.aidl
356*333d2b36SAndroid Build Coastguard Worker	} else {
357*333d2b36SAndroid Build Coastguard Worker		deps.aidlPreprocess = sdkDep.aidl
358*333d2b36SAndroid Build Coastguard Worker	}
359*333d2b36SAndroid Build Coastguard Worker
360*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDeps(func(module android.Module) {
361*333d2b36SAndroid Build Coastguard Worker		otherName := ctx.OtherModuleName(module)
362*333d2b36SAndroid Build Coastguard Worker		tag := ctx.OtherModuleDependencyTag(module)
363*333d2b36SAndroid Build Coastguard Worker
364*333d2b36SAndroid Build Coastguard Worker		switch tag {
365*333d2b36SAndroid Build Coastguard Worker		case bootClasspathTag:
366*333d2b36SAndroid Build Coastguard Worker			if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
367*333d2b36SAndroid Build Coastguard Worker				deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars...)
368*333d2b36SAndroid Build Coastguard Worker			} else if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
369*333d2b36SAndroid Build Coastguard Worker				// A system modules dependency has been added to the bootclasspath
370*333d2b36SAndroid Build Coastguard Worker				// so add its libs to the bootclasspath.
371*333d2b36SAndroid Build Coastguard Worker				deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars...)
372*333d2b36SAndroid Build Coastguard Worker			} else {
373*333d2b36SAndroid Build Coastguard Worker				panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
374*333d2b36SAndroid Build Coastguard Worker			}
375*333d2b36SAndroid Build Coastguard Worker		case libTag, sdkLibTag:
376*333d2b36SAndroid Build Coastguard Worker			if sdkInfo, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
377*333d2b36SAndroid Build Coastguard Worker				generatingLibsString := android.PrettyConcat(
378*333d2b36SAndroid Build Coastguard Worker					getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or")
379*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString)
380*333d2b36SAndroid Build Coastguard Worker			} else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
381*333d2b36SAndroid Build Coastguard Worker				deps.classpath = append(deps.classpath, dep.HeaderJars...)
382*333d2b36SAndroid Build Coastguard Worker				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
383*333d2b36SAndroid Build Coastguard Worker				deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
384*333d2b36SAndroid Build Coastguard Worker			} else if dep, ok := module.(android.SourceFileProducer); ok {
385*333d2b36SAndroid Build Coastguard Worker				checkProducesJars(ctx, dep)
386*333d2b36SAndroid Build Coastguard Worker				deps.classpath = append(deps.classpath, dep.Srcs()...)
387*333d2b36SAndroid Build Coastguard Worker			} else {
388*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("depends on non-java module %q", otherName)
389*333d2b36SAndroid Build Coastguard Worker			}
390*333d2b36SAndroid Build Coastguard Worker
391*333d2b36SAndroid Build Coastguard Worker		case java9LibTag:
392*333d2b36SAndroid Build Coastguard Worker			if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
393*333d2b36SAndroid Build Coastguard Worker				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
394*333d2b36SAndroid Build Coastguard Worker			} else {
395*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("depends on non-java module %q", otherName)
396*333d2b36SAndroid Build Coastguard Worker			}
397*333d2b36SAndroid Build Coastguard Worker		case systemModulesTag:
398*333d2b36SAndroid Build Coastguard Worker			if deps.systemModules != nil {
399*333d2b36SAndroid Build Coastguard Worker				panic("Found two system module dependencies")
400*333d2b36SAndroid Build Coastguard Worker			}
401*333d2b36SAndroid Build Coastguard Worker			if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
402*333d2b36SAndroid Build Coastguard Worker				deps.systemModules = &systemModules{sm.OutputDir, sm.OutputDirDeps}
403*333d2b36SAndroid Build Coastguard Worker			} else {
404*333d2b36SAndroid Build Coastguard Worker				ctx.PropertyErrorf("boot classpath dependency %q does not provide SystemModulesProvider",
405*333d2b36SAndroid Build Coastguard Worker					ctx.OtherModuleName(module))
406*333d2b36SAndroid Build Coastguard Worker			}
407*333d2b36SAndroid Build Coastguard Worker		case aconfigDeclarationTag:
408*333d2b36SAndroid Build Coastguard Worker			if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey); ok {
409*333d2b36SAndroid Build Coastguard Worker				deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPath)
410*333d2b36SAndroid Build Coastguard Worker			} else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
411*333d2b36SAndroid Build Coastguard Worker				deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
412*333d2b36SAndroid Build Coastguard Worker			} else {
413*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
414*333d2b36SAndroid Build Coastguard Worker					"module type is allowed for flags_packages property, but %s is neither "+
415*333d2b36SAndroid Build Coastguard Worker					"of these supported module types",
416*333d2b36SAndroid Build Coastguard Worker					module.Name(),
417*333d2b36SAndroid Build Coastguard Worker				)
418*333d2b36SAndroid Build Coastguard Worker			}
419*333d2b36SAndroid Build Coastguard Worker		}
420*333d2b36SAndroid Build Coastguard Worker	})
421*333d2b36SAndroid Build Coastguard Worker	// do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
422*333d2b36SAndroid Build Coastguard Worker	// may contain filegroup or genrule.
423*333d2b36SAndroid Build Coastguard Worker	srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
424*333d2b36SAndroid Build Coastguard Worker	j.implicits = append(j.implicits, srcFiles...)
425*333d2b36SAndroid Build Coastguard Worker
426*333d2b36SAndroid Build Coastguard Worker	// Module can depend on a java_aconfig_library module using the ":module_name{.tag}" syntax.
427*333d2b36SAndroid Build Coastguard Worker	// Find the corresponding aconfig_declarations module name for such case.
428*333d2b36SAndroid Build Coastguard Worker	for _, src := range j.properties.Srcs {
429*333d2b36SAndroid Build Coastguard Worker		if moduleName, tag := android.SrcIsModuleWithTag(src); moduleName != "" {
430*333d2b36SAndroid Build Coastguard Worker			otherModule := android.GetModuleProxyFromPathDep(ctx, moduleName, tag)
431*333d2b36SAndroid Build Coastguard Worker			if otherModule != nil {
432*333d2b36SAndroid Build Coastguard Worker				if dep, ok := android.OtherModuleProvider(ctx, *otherModule, android.CodegenInfoProvider); ok {
433*333d2b36SAndroid Build Coastguard Worker					deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
434*333d2b36SAndroid Build Coastguard Worker				}
435*333d2b36SAndroid Build Coastguard Worker			}
436*333d2b36SAndroid Build Coastguard Worker		}
437*333d2b36SAndroid Build Coastguard Worker	}
438*333d2b36SAndroid Build Coastguard Worker
439*333d2b36SAndroid Build Coastguard Worker	filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
440*333d2b36SAndroid Build Coastguard Worker		if filterPackages == nil {
441*333d2b36SAndroid Build Coastguard Worker			return srcs
442*333d2b36SAndroid Build Coastguard Worker		}
443*333d2b36SAndroid Build Coastguard Worker		filtered := []android.Path{}
444*333d2b36SAndroid Build Coastguard Worker		for _, src := range srcs {
445*333d2b36SAndroid Build Coastguard Worker			if src.Ext() != ".java" {
446*333d2b36SAndroid Build Coastguard Worker				// Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
447*333d2b36SAndroid Build Coastguard Worker				// but otherwise metalava emits stub sources having references to the generated AIDL classes
448*333d2b36SAndroid Build Coastguard Worker				// in filtered-out pacages (e.g. com.android.internal.*).
449*333d2b36SAndroid Build Coastguard Worker				// TODO(b/141149570) We need to fix this by introducing default private constructors or
450*333d2b36SAndroid Build Coastguard Worker				// fixing metalava to not emit constructors having references to unknown classes.
451*333d2b36SAndroid Build Coastguard Worker				filtered = append(filtered, src)
452*333d2b36SAndroid Build Coastguard Worker				continue
453*333d2b36SAndroid Build Coastguard Worker			}
454*333d2b36SAndroid Build Coastguard Worker			packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
455*333d2b36SAndroid Build Coastguard Worker			if android.HasAnyPrefix(packageName, filterPackages) {
456*333d2b36SAndroid Build Coastguard Worker				filtered = append(filtered, src)
457*333d2b36SAndroid Build Coastguard Worker			}
458*333d2b36SAndroid Build Coastguard Worker		}
459*333d2b36SAndroid Build Coastguard Worker		return filtered
460*333d2b36SAndroid Build Coastguard Worker	}
461*333d2b36SAndroid Build Coastguard Worker	srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
462*333d2b36SAndroid Build Coastguard Worker
463*333d2b36SAndroid Build Coastguard Worker	aidlFlags := j.collectAidlFlags(ctx, deps)
464*333d2b36SAndroid Build Coastguard Worker	srcFiles = j.genSources(ctx, srcFiles, aidlFlags)
465*333d2b36SAndroid Build Coastguard Worker
466*333d2b36SAndroid Build Coastguard Worker	// srcs may depend on some genrule output.
467*333d2b36SAndroid Build Coastguard Worker	j.srcJars = srcFiles.FilterByExt(".srcjar")
468*333d2b36SAndroid Build Coastguard Worker	j.srcJars = append(j.srcJars, deps.srcJars...)
469*333d2b36SAndroid Build Coastguard Worker
470*333d2b36SAndroid Build Coastguard Worker	j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
471*333d2b36SAndroid Build Coastguard Worker	j.srcFiles = append(j.srcFiles, deps.srcs...)
472*333d2b36SAndroid Build Coastguard Worker
473*333d2b36SAndroid Build Coastguard Worker	if len(j.srcFiles) > 0 {
474*333d2b36SAndroid Build Coastguard Worker		j.sourcepaths = android.PathsForModuleSrc(ctx, []string{"."})
475*333d2b36SAndroid Build Coastguard Worker	}
476*333d2b36SAndroid Build Coastguard Worker
477*333d2b36SAndroid Build Coastguard Worker	return deps
478*333d2b36SAndroid Build Coastguard Worker}
479*333d2b36SAndroid Build Coastguard Worker
480*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) expandArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
481*333d2b36SAndroid Build Coastguard Worker	var argFiles android.Paths
482*333d2b36SAndroid Build Coastguard Worker	argFilesMap := map[string]string{}
483*333d2b36SAndroid Build Coastguard Worker	argFileLabels := []string{}
484*333d2b36SAndroid Build Coastguard Worker
485*333d2b36SAndroid Build Coastguard Worker	for _, label := range j.properties.Arg_files {
486*333d2b36SAndroid Build Coastguard Worker		var paths = android.PathsForModuleSrc(ctx, []string{label})
487*333d2b36SAndroid Build Coastguard Worker		if _, exists := argFilesMap[label]; !exists {
488*333d2b36SAndroid Build Coastguard Worker			argFilesMap[label] = strings.Join(cmd.PathsForInputs(paths), " ")
489*333d2b36SAndroid Build Coastguard Worker			argFileLabels = append(argFileLabels, label)
490*333d2b36SAndroid Build Coastguard Worker			argFiles = append(argFiles, paths...)
491*333d2b36SAndroid Build Coastguard Worker		} else {
492*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
493*333d2b36SAndroid Build Coastguard Worker				label, argFilesMap[label], paths)
494*333d2b36SAndroid Build Coastguard Worker		}
495*333d2b36SAndroid Build Coastguard Worker	}
496*333d2b36SAndroid Build Coastguard Worker
497*333d2b36SAndroid Build Coastguard Worker	var argsPropertyName string
498*333d2b36SAndroid Build Coastguard Worker	flags := make([]string, 0)
499*333d2b36SAndroid Build Coastguard Worker	if j.properties.Args != nil && j.properties.Flags != nil {
500*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("args", "flags is set. Cannot set args")
501*333d2b36SAndroid Build Coastguard Worker	} else if args := proptools.String(j.properties.Args); args != "" {
502*333d2b36SAndroid Build Coastguard Worker		flags = append(flags, args)
503*333d2b36SAndroid Build Coastguard Worker		argsPropertyName = "args"
504*333d2b36SAndroid Build Coastguard Worker	} else {
505*333d2b36SAndroid Build Coastguard Worker		flags = append(flags, j.properties.Flags...)
506*333d2b36SAndroid Build Coastguard Worker		argsPropertyName = "flags"
507*333d2b36SAndroid Build Coastguard Worker	}
508*333d2b36SAndroid Build Coastguard Worker
509*333d2b36SAndroid Build Coastguard Worker	for _, flag := range flags {
510*333d2b36SAndroid Build Coastguard Worker		expanded, err := android.Expand(flag, func(name string) (string, error) {
511*333d2b36SAndroid Build Coastguard Worker			if strings.HasPrefix(name, "location ") {
512*333d2b36SAndroid Build Coastguard Worker				label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
513*333d2b36SAndroid Build Coastguard Worker				if paths, ok := argFilesMap[label]; ok {
514*333d2b36SAndroid Build Coastguard Worker					return paths, nil
515*333d2b36SAndroid Build Coastguard Worker				} else {
516*333d2b36SAndroid Build Coastguard Worker					return "", fmt.Errorf("unknown location label %q, expecting one of %q",
517*333d2b36SAndroid Build Coastguard Worker						label, strings.Join(argFileLabels, ", "))
518*333d2b36SAndroid Build Coastguard Worker				}
519*333d2b36SAndroid Build Coastguard Worker			} else if name == "genDir" {
520*333d2b36SAndroid Build Coastguard Worker				return android.PathForModuleGen(ctx).String(), nil
521*333d2b36SAndroid Build Coastguard Worker			}
522*333d2b36SAndroid Build Coastguard Worker			return "", fmt.Errorf("unknown variable '$(%s)'", name)
523*333d2b36SAndroid Build Coastguard Worker		})
524*333d2b36SAndroid Build Coastguard Worker
525*333d2b36SAndroid Build Coastguard Worker		if err != nil {
526*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf(argsPropertyName, "%s", err.Error())
527*333d2b36SAndroid Build Coastguard Worker		}
528*333d2b36SAndroid Build Coastguard Worker		cmd.Flag(expanded)
529*333d2b36SAndroid Build Coastguard Worker	}
530*333d2b36SAndroid Build Coastguard Worker
531*333d2b36SAndroid Build Coastguard Worker	cmd.Implicits(argFiles)
532*333d2b36SAndroid Build Coastguard Worker}
533*333d2b36SAndroid Build Coastguard Worker
534*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
535*333d2b36SAndroid Build Coastguard Worker	j.addDeps(ctx)
536*333d2b36SAndroid Build Coastguard Worker}
537*333d2b36SAndroid Build Coastguard Worker
538*333d2b36SAndroid Build Coastguard Workerfunc (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
539*333d2b36SAndroid Build Coastguard Worker	deps := j.collectDeps(ctx)
540*333d2b36SAndroid Build Coastguard Worker
541*333d2b36SAndroid Build Coastguard Worker	j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
542*333d2b36SAndroid Build Coastguard Worker
543*333d2b36SAndroid Build Coastguard Worker	outDir := android.PathForModuleOut(ctx, "out")
544*333d2b36SAndroid Build Coastguard Worker	srcJarDir := android.PathForModuleOut(ctx, "srcjars")
545*333d2b36SAndroid Build Coastguard Worker
546*333d2b36SAndroid Build Coastguard Worker	j.stubsSrcJar = nil
547*333d2b36SAndroid Build Coastguard Worker
548*333d2b36SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
549*333d2b36SAndroid Build Coastguard Worker
550*333d2b36SAndroid Build Coastguard Worker	rule.Command().Text("rm -rf").Text(outDir.String())
551*333d2b36SAndroid Build Coastguard Worker	rule.Command().Text("mkdir -p").Text(outDir.String())
552*333d2b36SAndroid Build Coastguard Worker
553*333d2b36SAndroid Build Coastguard Worker	srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
554*333d2b36SAndroid Build Coastguard Worker
555*333d2b36SAndroid Build Coastguard Worker	javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), android.SdkContext(j))
556*333d2b36SAndroid Build Coastguard Worker
557*333d2b36SAndroid Build Coastguard Worker	cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
558*333d2b36SAndroid Build Coastguard Worker		deps.systemModules, deps.classpath, j.sourcepaths)
559*333d2b36SAndroid Build Coastguard Worker
560*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithArg("-source ", javaVersion.String()).
561*333d2b36SAndroid Build Coastguard Worker		Flag("-J-Xmx1024m").
562*333d2b36SAndroid Build Coastguard Worker		Flag("-XDignore.symbol.file").
563*333d2b36SAndroid Build Coastguard Worker		Flag("-Xdoclint:none")
564*333d2b36SAndroid Build Coastguard Worker
565*333d2b36SAndroid Build Coastguard Worker	j.expandArgs(ctx, cmd)
566*333d2b36SAndroid Build Coastguard Worker
567*333d2b36SAndroid Build Coastguard Worker	rule.Command().
568*333d2b36SAndroid Build Coastguard Worker		BuiltTool("soong_zip").
569*333d2b36SAndroid Build Coastguard Worker		Flag("-write_if_changed").
570*333d2b36SAndroid Build Coastguard Worker		Flag("-d").
571*333d2b36SAndroid Build Coastguard Worker		FlagWithOutput("-o ", j.docZip).
572*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-C ", outDir.String()).
573*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-D ", outDir.String())
574*333d2b36SAndroid Build Coastguard Worker
575*333d2b36SAndroid Build Coastguard Worker	rule.Restat()
576*333d2b36SAndroid Build Coastguard Worker
577*333d2b36SAndroid Build Coastguard Worker	zipSyncCleanupCmd(rule, srcJarDir)
578*333d2b36SAndroid Build Coastguard Worker
579*333d2b36SAndroid Build Coastguard Worker	rule.Build("javadoc", "javadoc")
580*333d2b36SAndroid Build Coastguard Worker
581*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles(android.Paths{j.docZip}, ".docs.zip")
582*333d2b36SAndroid Build Coastguard Worker}
583*333d2b36SAndroid Build Coastguard Worker
584*333d2b36SAndroid Build Coastguard Worker// Droiddoc
585*333d2b36SAndroid Build Coastguard Workertype Droiddoc struct {
586*333d2b36SAndroid Build Coastguard Worker	Javadoc
587*333d2b36SAndroid Build Coastguard Worker
588*333d2b36SAndroid Build Coastguard Worker	properties DroiddocProperties
589*333d2b36SAndroid Build Coastguard Worker}
590*333d2b36SAndroid Build Coastguard Worker
591*333d2b36SAndroid Build Coastguard Worker// droiddoc converts .java source files to documentation using doclava or dokka.
592*333d2b36SAndroid Build Coastguard Workerfunc DroiddocFactory() android.Module {
593*333d2b36SAndroid Build Coastguard Worker	module := &Droiddoc{}
594*333d2b36SAndroid Build Coastguard Worker
595*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties,
596*333d2b36SAndroid Build Coastguard Worker		&module.Javadoc.properties)
597*333d2b36SAndroid Build Coastguard Worker
598*333d2b36SAndroid Build Coastguard Worker	InitDroiddocModule(module, android.HostAndDeviceSupported)
599*333d2b36SAndroid Build Coastguard Worker	return module
600*333d2b36SAndroid Build Coastguard Worker}
601*333d2b36SAndroid Build Coastguard Worker
602*333d2b36SAndroid Build Coastguard Worker// droiddoc_host converts .java source files to documentation using doclava or dokka.
603*333d2b36SAndroid Build Coastguard Workerfunc DroiddocHostFactory() android.Module {
604*333d2b36SAndroid Build Coastguard Worker	module := &Droiddoc{}
605*333d2b36SAndroid Build Coastguard Worker
606*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties,
607*333d2b36SAndroid Build Coastguard Worker		&module.Javadoc.properties)
608*333d2b36SAndroid Build Coastguard Worker
609*333d2b36SAndroid Build Coastguard Worker	InitDroiddocModule(module, android.HostSupported)
610*333d2b36SAndroid Build Coastguard Worker	return module
611*333d2b36SAndroid Build Coastguard Worker}
612*333d2b36SAndroid Build Coastguard Worker
613*333d2b36SAndroid Build Coastguard Workerfunc (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
614*333d2b36SAndroid Build Coastguard Worker	d.Javadoc.addDeps(ctx)
615*333d2b36SAndroid Build Coastguard Worker
616*333d2b36SAndroid Build Coastguard Worker	if String(d.properties.Custom_template) != "" {
617*333d2b36SAndroid Build Coastguard Worker		ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
618*333d2b36SAndroid Build Coastguard Worker	}
619*333d2b36SAndroid Build Coastguard Worker}
620*333d2b36SAndroid Build Coastguard Worker
621*333d2b36SAndroid Build Coastguard Workerfunc (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
622*333d2b36SAndroid Build Coastguard Worker	buildNumberFile := ctx.Config().BuildNumberFile(ctx)
623*333d2b36SAndroid Build Coastguard Worker	// Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources.  For modules with 1.9
624*333d2b36SAndroid Build Coastguard Worker	// sources, droiddoc will get sources produced by metalava which will have already stripped out the
625*333d2b36SAndroid Build Coastguard Worker	// 1.9 language features.
626*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithArg("-source ", getStubsJavaVersion().String()).
627*333d2b36SAndroid Build Coastguard Worker		Flag("-J-Xmx1600m").
628*333d2b36SAndroid Build Coastguard Worker		Flag("-J-XX:-OmitStackTraceInFastThrow").
629*333d2b36SAndroid Build Coastguard Worker		Flag("-XDignore.symbol.file").
630*333d2b36SAndroid Build Coastguard Worker		Flag("--ignore-source-errors").
631*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-doclet ", "com.google.doclava.Doclava").
632*333d2b36SAndroid Build Coastguard Worker		FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
633*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-Xmaxerrs ", "10").
634*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-Xmaxwarns ", "10").
635*333d2b36SAndroid Build Coastguard Worker		Flag("-J--add-exports=jdk.javadoc/jdk.javadoc.internal.doclets.formats.html=ALL-UNNAMED").
636*333d2b36SAndroid Build Coastguard Worker		Flag("-J--add-exports=jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED").
637*333d2b36SAndroid Build Coastguard Worker		Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED").
638*333d2b36SAndroid Build Coastguard Worker		Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED").
639*333d2b36SAndroid Build Coastguard Worker		Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED").
640*333d2b36SAndroid Build Coastguard Worker		Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED").
641*333d2b36SAndroid Build Coastguard Worker		Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED").
642*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-$(cat "+buildNumberFile.String()+")").OrderOnly(buildNumberFile).
643*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-hdf page.now ", `"$(date -d @$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
644*333d2b36SAndroid Build Coastguard Worker
645*333d2b36SAndroid Build Coastguard Worker	if String(d.properties.Custom_template) == "" {
646*333d2b36SAndroid Build Coastguard Worker		// TODO: This is almost always droiddoc-templates-sdk
647*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("custom_template", "must specify a template")
648*333d2b36SAndroid Build Coastguard Worker	}
649*333d2b36SAndroid Build Coastguard Worker
650*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
651*333d2b36SAndroid Build Coastguard Worker		if t, ok := m.(*ExportedDroiddocDir); ok {
652*333d2b36SAndroid Build Coastguard Worker			cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
653*333d2b36SAndroid Build Coastguard Worker		} else {
654*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_exported_dir", ctx.OtherModuleName(m))
655*333d2b36SAndroid Build Coastguard Worker		}
656*333d2b36SAndroid Build Coastguard Worker	})
657*333d2b36SAndroid Build Coastguard Worker
658*333d2b36SAndroid Build Coastguard Worker	if len(d.properties.Html_dirs) > 0 {
659*333d2b36SAndroid Build Coastguard Worker		htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
660*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("-htmldir ", htmlDir.String()).
661*333d2b36SAndroid Build Coastguard Worker			Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
662*333d2b36SAndroid Build Coastguard Worker	}
663*333d2b36SAndroid Build Coastguard Worker
664*333d2b36SAndroid Build Coastguard Worker	if len(d.properties.Html_dirs) > 1 {
665*333d2b36SAndroid Build Coastguard Worker		htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
666*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
667*333d2b36SAndroid Build Coastguard Worker			Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
668*333d2b36SAndroid Build Coastguard Worker	}
669*333d2b36SAndroid Build Coastguard Worker
670*333d2b36SAndroid Build Coastguard Worker	if len(d.properties.Html_dirs) > 2 {
671*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
672*333d2b36SAndroid Build Coastguard Worker	}
673*333d2b36SAndroid Build Coastguard Worker
674*333d2b36SAndroid Build Coastguard Worker	knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
675*333d2b36SAndroid Build Coastguard Worker	cmd.FlagForEachInput("-knowntags ", knownTags)
676*333d2b36SAndroid Build Coastguard Worker
677*333d2b36SAndroid Build Coastguard Worker	cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
678*333d2b36SAndroid Build Coastguard Worker
679*333d2b36SAndroid Build Coastguard Worker	if String(d.properties.Proofread_file) != "" {
680*333d2b36SAndroid Build Coastguard Worker		proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
681*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithOutput("-proofread ", proofreadFile)
682*333d2b36SAndroid Build Coastguard Worker	}
683*333d2b36SAndroid Build Coastguard Worker
684*333d2b36SAndroid Build Coastguard Worker	if String(d.properties.Todo_file) != "" {
685*333d2b36SAndroid Build Coastguard Worker		// tricky part:
686*333d2b36SAndroid Build Coastguard Worker		// we should not compute full path for todo_file through PathForModuleOut().
687*333d2b36SAndroid Build Coastguard Worker		// the non-standard doclet will get the full path relative to "-o".
688*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
689*333d2b36SAndroid Build Coastguard Worker			ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
690*333d2b36SAndroid Build Coastguard Worker	}
691*333d2b36SAndroid Build Coastguard Worker
692*333d2b36SAndroid Build Coastguard Worker	if String(d.properties.Lint_baseline) != "" {
693*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithInput("-lintbaseline ", android.PathForModuleSrc(ctx, String(d.properties.Lint_baseline)))
694*333d2b36SAndroid Build Coastguard Worker	}
695*333d2b36SAndroid Build Coastguard Worker
696*333d2b36SAndroid Build Coastguard Worker	if String(d.properties.Resourcesdir) != "" {
697*333d2b36SAndroid Build Coastguard Worker		// TODO: should we add files under resourcesDir to the implicits? It seems that
698*333d2b36SAndroid Build Coastguard Worker		// resourcesDir is one sub dir of htmlDir
699*333d2b36SAndroid Build Coastguard Worker		resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
700*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
701*333d2b36SAndroid Build Coastguard Worker	}
702*333d2b36SAndroid Build Coastguard Worker
703*333d2b36SAndroid Build Coastguard Worker	if String(d.properties.Resourcesoutdir) != "" {
704*333d2b36SAndroid Build Coastguard Worker		// TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
705*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
706*333d2b36SAndroid Build Coastguard Worker	}
707*333d2b36SAndroid Build Coastguard Worker}
708*333d2b36SAndroid Build Coastguard Worker
709*333d2b36SAndroid Build Coastguard Workerfunc (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
710*333d2b36SAndroid Build Coastguard Worker	if String(d.properties.Static_doc_index_redirect) != "" {
711*333d2b36SAndroid Build Coastguard Worker		staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
712*333d2b36SAndroid Build Coastguard Worker		rule.Command().Text("cp").
713*333d2b36SAndroid Build Coastguard Worker			Input(staticDocIndexRedirect).
714*333d2b36SAndroid Build Coastguard Worker			Output(android.PathForModuleOut(ctx, "out", "index.html"))
715*333d2b36SAndroid Build Coastguard Worker	}
716*333d2b36SAndroid Build Coastguard Worker
717*333d2b36SAndroid Build Coastguard Worker	if String(d.properties.Static_doc_properties) != "" {
718*333d2b36SAndroid Build Coastguard Worker		staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
719*333d2b36SAndroid Build Coastguard Worker		rule.Command().Text("cp").
720*333d2b36SAndroid Build Coastguard Worker			Input(staticDocProperties).
721*333d2b36SAndroid Build Coastguard Worker			Output(android.PathForModuleOut(ctx, "out", "source.properties"))
722*333d2b36SAndroid Build Coastguard Worker	}
723*333d2b36SAndroid Build Coastguard Worker}
724*333d2b36SAndroid Build Coastguard Worker
725*333d2b36SAndroid Build Coastguard Workerfunc javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
726*333d2b36SAndroid Build Coastguard Worker	outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
727*333d2b36SAndroid Build Coastguard Worker
728*333d2b36SAndroid Build Coastguard Worker	cmd := rule.Command().
729*333d2b36SAndroid Build Coastguard Worker		BuiltTool("soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
730*333d2b36SAndroid Build Coastguard Worker		Flag(config.JavacVmFlags).
731*333d2b36SAndroid Build Coastguard Worker		FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "javadoc.rsp"), srcs).
732*333d2b36SAndroid Build Coastguard Worker		FlagWithInput("@", srcJarList)
733*333d2b36SAndroid Build Coastguard Worker
734*333d2b36SAndroid Build Coastguard Worker	// TODO(ccross): Remove this if- statement once we finish migration for all Doclava
735*333d2b36SAndroid Build Coastguard Worker	// based stubs generation.
736*333d2b36SAndroid Build Coastguard Worker	// In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
737*333d2b36SAndroid Build Coastguard Worker	// dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
738*333d2b36SAndroid Build Coastguard Worker	// the correct package name base path.
739*333d2b36SAndroid Build Coastguard Worker	if len(sourcepaths) > 0 {
740*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
741*333d2b36SAndroid Build Coastguard Worker	} else {
742*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
743*333d2b36SAndroid Build Coastguard Worker	}
744*333d2b36SAndroid Build Coastguard Worker
745*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithArg("-d ", outDir.String()).
746*333d2b36SAndroid Build Coastguard Worker		Flag("-quiet")
747*333d2b36SAndroid Build Coastguard Worker
748*333d2b36SAndroid Build Coastguard Worker	return cmd
749*333d2b36SAndroid Build Coastguard Worker}
750*333d2b36SAndroid Build Coastguard Worker
751*333d2b36SAndroid Build Coastguard Workerfunc javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
752*333d2b36SAndroid Build Coastguard Worker	outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
753*333d2b36SAndroid Build Coastguard Worker	classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
754*333d2b36SAndroid Build Coastguard Worker
755*333d2b36SAndroid Build Coastguard Worker	cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
756*333d2b36SAndroid Build Coastguard Worker
757*333d2b36SAndroid Build Coastguard Worker	flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
758*333d2b36SAndroid Build Coastguard Worker	cmd.Flag(flag).Implicits(deps)
759*333d2b36SAndroid Build Coastguard Worker
760*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithArg("--patch-module ", "java.base=.")
761*333d2b36SAndroid Build Coastguard Worker
762*333d2b36SAndroid Build Coastguard Worker	if len(classpath) > 0 {
763*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
764*333d2b36SAndroid Build Coastguard Worker	}
765*333d2b36SAndroid Build Coastguard Worker
766*333d2b36SAndroid Build Coastguard Worker	return cmd
767*333d2b36SAndroid Build Coastguard Worker}
768*333d2b36SAndroid Build Coastguard Worker
769*333d2b36SAndroid Build Coastguard Workerfunc javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
770*333d2b36SAndroid Build Coastguard Worker	outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
771*333d2b36SAndroid Build Coastguard Worker	sourcepaths android.Paths) *android.RuleBuilderCommand {
772*333d2b36SAndroid Build Coastguard Worker
773*333d2b36SAndroid Build Coastguard Worker	cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
774*333d2b36SAndroid Build Coastguard Worker
775*333d2b36SAndroid Build Coastguard Worker	if len(bootclasspath) == 0 && ctx.Device() {
776*333d2b36SAndroid Build Coastguard Worker		// explicitly specify -bootclasspath "" if the bootclasspath is empty to
777*333d2b36SAndroid Build Coastguard Worker		// ensure java does not fall back to the default bootclasspath.
778*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithArg("-bootclasspath ", `""`)
779*333d2b36SAndroid Build Coastguard Worker	} else if len(bootclasspath) > 0 {
780*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
781*333d2b36SAndroid Build Coastguard Worker	}
782*333d2b36SAndroid Build Coastguard Worker
783*333d2b36SAndroid Build Coastguard Worker	if len(classpath) > 0 {
784*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
785*333d2b36SAndroid Build Coastguard Worker	}
786*333d2b36SAndroid Build Coastguard Worker
787*333d2b36SAndroid Build Coastguard Worker	return cmd
788*333d2b36SAndroid Build Coastguard Worker}
789*333d2b36SAndroid Build Coastguard Worker
790*333d2b36SAndroid Build Coastguard Workerfunc dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
791*333d2b36SAndroid Build Coastguard Worker	outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
792*333d2b36SAndroid Build Coastguard Worker
793*333d2b36SAndroid Build Coastguard Worker	// Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
794*333d2b36SAndroid Build Coastguard Worker	dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
795*333d2b36SAndroid Build Coastguard Worker
796*333d2b36SAndroid Build Coastguard Worker	return rule.Command().
797*333d2b36SAndroid Build Coastguard Worker		BuiltTool("dokka").
798*333d2b36SAndroid Build Coastguard Worker		Flag(config.JavacVmFlags).
799*333d2b36SAndroid Build Coastguard Worker		Flag("-J--add-opens=java.base/java.lang=ALL-UNNAMED").
800*333d2b36SAndroid Build Coastguard Worker		Flag(srcJarDir.String()).
801*333d2b36SAndroid Build Coastguard Worker		FlagWithInputList("-classpath ", dokkaClasspath, ":").
802*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-format ", "dac").
803*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-dacRoot ", "/reference/kotlin").
804*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-output ", outDir.String())
805*333d2b36SAndroid Build Coastguard Worker}
806*333d2b36SAndroid Build Coastguard Worker
807*333d2b36SAndroid Build Coastguard Workerfunc (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
808*333d2b36SAndroid Build Coastguard Worker	deps := d.Javadoc.collectDeps(ctx)
809*333d2b36SAndroid Build Coastguard Worker
810*333d2b36SAndroid Build Coastguard Worker	d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
811*333d2b36SAndroid Build Coastguard Worker
812*333d2b36SAndroid Build Coastguard Worker	jsilver := ctx.Config().HostJavaToolPath(ctx, "jsilver.jar")
813*333d2b36SAndroid Build Coastguard Worker	doclava := ctx.Config().HostJavaToolPath(ctx, "doclava.jar")
814*333d2b36SAndroid Build Coastguard Worker
815*333d2b36SAndroid Build Coastguard Worker	outDir := android.PathForModuleOut(ctx, "out")
816*333d2b36SAndroid Build Coastguard Worker	srcJarDir := android.PathForModuleOut(ctx, "srcjars")
817*333d2b36SAndroid Build Coastguard Worker
818*333d2b36SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
819*333d2b36SAndroid Build Coastguard Worker
820*333d2b36SAndroid Build Coastguard Worker	srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
821*333d2b36SAndroid Build Coastguard Worker
822*333d2b36SAndroid Build Coastguard Worker	var cmd *android.RuleBuilderCommand
823*333d2b36SAndroid Build Coastguard Worker	if Bool(d.properties.Dokka_enabled) {
824*333d2b36SAndroid Build Coastguard Worker		cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
825*333d2b36SAndroid Build Coastguard Worker	} else {
826*333d2b36SAndroid Build Coastguard Worker		cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
827*333d2b36SAndroid Build Coastguard Worker			deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
828*333d2b36SAndroid Build Coastguard Worker	}
829*333d2b36SAndroid Build Coastguard Worker
830*333d2b36SAndroid Build Coastguard Worker	d.expandArgs(ctx, cmd)
831*333d2b36SAndroid Build Coastguard Worker
832*333d2b36SAndroid Build Coastguard Worker	if d.properties.Compat_config != nil {
833*333d2b36SAndroid Build Coastguard Worker		compatConfig := android.PathForModuleSrc(ctx, String(d.properties.Compat_config))
834*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithInput("-compatconfig ", compatConfig)
835*333d2b36SAndroid Build Coastguard Worker	}
836*333d2b36SAndroid Build Coastguard Worker
837*333d2b36SAndroid Build Coastguard Worker	var desc string
838*333d2b36SAndroid Build Coastguard Worker	if Bool(d.properties.Dokka_enabled) {
839*333d2b36SAndroid Build Coastguard Worker		desc = "dokka"
840*333d2b36SAndroid Build Coastguard Worker	} else {
841*333d2b36SAndroid Build Coastguard Worker		d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
842*333d2b36SAndroid Build Coastguard Worker
843*333d2b36SAndroid Build Coastguard Worker		for _, o := range d.Javadoc.properties.Out {
844*333d2b36SAndroid Build Coastguard Worker			cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
845*333d2b36SAndroid Build Coastguard Worker		}
846*333d2b36SAndroid Build Coastguard Worker
847*333d2b36SAndroid Build Coastguard Worker		d.postDoclavaCmds(ctx, rule)
848*333d2b36SAndroid Build Coastguard Worker		desc = "doclava"
849*333d2b36SAndroid Build Coastguard Worker	}
850*333d2b36SAndroid Build Coastguard Worker
851*333d2b36SAndroid Build Coastguard Worker	rule.Command().
852*333d2b36SAndroid Build Coastguard Worker		BuiltTool("soong_zip").
853*333d2b36SAndroid Build Coastguard Worker		Flag("-write_if_changed").
854*333d2b36SAndroid Build Coastguard Worker		Flag("-d").
855*333d2b36SAndroid Build Coastguard Worker		FlagWithOutput("-o ", d.docZip).
856*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-C ", outDir.String()).
857*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-D ", outDir.String())
858*333d2b36SAndroid Build Coastguard Worker
859*333d2b36SAndroid Build Coastguard Worker	rule.Restat()
860*333d2b36SAndroid Build Coastguard Worker
861*333d2b36SAndroid Build Coastguard Worker	zipSyncCleanupCmd(rule, srcJarDir)
862*333d2b36SAndroid Build Coastguard Worker
863*333d2b36SAndroid Build Coastguard Worker	rule.Build("javadoc", desc)
864*333d2b36SAndroid Build Coastguard Worker
865*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles(android.Paths{d.Javadoc.docZip}, "")
866*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles(android.Paths{d.Javadoc.docZip}, ".docs.zip")
867*333d2b36SAndroid Build Coastguard Worker}
868*333d2b36SAndroid Build Coastguard Worker
869*333d2b36SAndroid Build Coastguard Worker// Exported Droiddoc Directory
870*333d2b36SAndroid Build Coastguard Workervar droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
871*333d2b36SAndroid Build Coastguard Worker
872*333d2b36SAndroid Build Coastguard Workertype ExportedDroiddocDirProperties struct {
873*333d2b36SAndroid Build Coastguard Worker	// path to the directory containing Droiddoc related files.
874*333d2b36SAndroid Build Coastguard Worker	Path *string
875*333d2b36SAndroid Build Coastguard Worker}
876*333d2b36SAndroid Build Coastguard Worker
877*333d2b36SAndroid Build Coastguard Workertype ExportedDroiddocDir struct {
878*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
879*333d2b36SAndroid Build Coastguard Worker
880*333d2b36SAndroid Build Coastguard Worker	properties ExportedDroiddocDirProperties
881*333d2b36SAndroid Build Coastguard Worker
882*333d2b36SAndroid Build Coastguard Worker	deps android.Paths
883*333d2b36SAndroid Build Coastguard Worker	dir  android.Path
884*333d2b36SAndroid Build Coastguard Worker}
885*333d2b36SAndroid Build Coastguard Worker
886*333d2b36SAndroid Build Coastguard Worker// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
887*333d2b36SAndroid Build Coastguard Workerfunc ExportedDroiddocDirFactory() android.Module {
888*333d2b36SAndroid Build Coastguard Worker	module := &ExportedDroiddocDir{}
889*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties)
890*333d2b36SAndroid Build Coastguard Worker	android.InitAndroidModule(module)
891*333d2b36SAndroid Build Coastguard Worker	return module
892*333d2b36SAndroid Build Coastguard Worker}
893*333d2b36SAndroid Build Coastguard Worker
894*333d2b36SAndroid Build Coastguard Workerfunc (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
895*333d2b36SAndroid Build Coastguard Worker
896*333d2b36SAndroid Build Coastguard Workerfunc (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
897*333d2b36SAndroid Build Coastguard Worker	path := String(d.properties.Path)
898*333d2b36SAndroid Build Coastguard Worker	d.dir = android.PathForModuleSrc(ctx, path)
899*333d2b36SAndroid Build Coastguard Worker	d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
900*333d2b36SAndroid Build Coastguard Worker}
901*333d2b36SAndroid Build Coastguard Worker
902*333d2b36SAndroid Build Coastguard Worker// Defaults
903*333d2b36SAndroid Build Coastguard Workertype DocDefaults struct {
904*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
905*333d2b36SAndroid Build Coastguard Worker	android.DefaultsModuleBase
906*333d2b36SAndroid Build Coastguard Worker}
907*333d2b36SAndroid Build Coastguard Worker
908*333d2b36SAndroid Build Coastguard Workerfunc DocDefaultsFactory() android.Module {
909*333d2b36SAndroid Build Coastguard Worker	module := &DocDefaults{}
910*333d2b36SAndroid Build Coastguard Worker
911*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(
912*333d2b36SAndroid Build Coastguard Worker		&JavadocProperties{},
913*333d2b36SAndroid Build Coastguard Worker		&DroiddocProperties{},
914*333d2b36SAndroid Build Coastguard Worker	)
915*333d2b36SAndroid Build Coastguard Worker
916*333d2b36SAndroid Build Coastguard Worker	android.InitDefaultsModule(module)
917*333d2b36SAndroid Build Coastguard Worker
918*333d2b36SAndroid Build Coastguard Worker	return module
919*333d2b36SAndroid Build Coastguard Worker}
920*333d2b36SAndroid Build Coastguard Worker
921*333d2b36SAndroid Build Coastguard Workerfunc zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
922*333d2b36SAndroid Build Coastguard Worker	srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
923*333d2b36SAndroid Build Coastguard Worker
924*333d2b36SAndroid Build Coastguard Worker	cmd := rule.Command()
925*333d2b36SAndroid Build Coastguard Worker	cmd.Text("rm -rf").Text(cmd.PathForOutput(srcJarDir))
926*333d2b36SAndroid Build Coastguard Worker	cmd = rule.Command()
927*333d2b36SAndroid Build Coastguard Worker	cmd.Text("mkdir -p").Text(cmd.PathForOutput(srcJarDir))
928*333d2b36SAndroid Build Coastguard Worker	srcJarList := srcJarDir.Join(ctx, "list")
929*333d2b36SAndroid Build Coastguard Worker
930*333d2b36SAndroid Build Coastguard Worker	rule.Temporary(srcJarList)
931*333d2b36SAndroid Build Coastguard Worker
932*333d2b36SAndroid Build Coastguard Worker	cmd = rule.Command()
933*333d2b36SAndroid Build Coastguard Worker	cmd.BuiltTool("zipsync").
934*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-d ", cmd.PathForOutput(srcJarDir)).
935*333d2b36SAndroid Build Coastguard Worker		FlagWithOutput("-l ", srcJarList).
936*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-f ", `"*.java"`).
937*333d2b36SAndroid Build Coastguard Worker		Inputs(srcJars)
938*333d2b36SAndroid Build Coastguard Worker
939*333d2b36SAndroid Build Coastguard Worker	return srcJarList
940*333d2b36SAndroid Build Coastguard Worker}
941*333d2b36SAndroid Build Coastguard Worker
942*333d2b36SAndroid Build Coastguard Workerfunc zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
943*333d2b36SAndroid Build Coastguard Worker	rule.Command().Text("rm -rf").Text(srcJarDir.String())
944*333d2b36SAndroid Build Coastguard Worker}
945