• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 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 xsdc
16
17import (
18	"android/soong/android"
19	"android/soong/java"
20	"path/filepath"
21	"strings"
22
23	"github.com/google/blueprint"
24	"github.com/google/blueprint/proptools"
25)
26
27func init() {
28	pctx.Import("android/soong/java/config")
29	android.RegisterModuleType("xsd_config", xsdConfigFactory)
30
31	android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
32		ctx.TopDown("xsd_config", xsdConfigMutator).Parallel()
33	})
34}
35
36var (
37	pctx = android.NewPackageContext("android/xsdc")
38
39	xsdc         = pctx.HostBinToolVariable("xsdcCmd", "xsdc")
40	xsdcJavaRule = pctx.StaticRule("xsdcJavaRule", blueprint.RuleParams{
41		Command: `rm -rf "${out}.temp" && mkdir -p "${out}.temp" && ` +
42			`${xsdcCmd} $in -p $pkgName -o ${out}.temp -j && ` +
43			`${config.SoongZipCmd} -jar -o ${out} -C ${out}.temp -D ${out}.temp && ` +
44			`rm -rf ${out}.temp`,
45		CommandDeps: []string{"${xsdcCmd}", "${config.SoongZipCmd}"},
46		Description: "xsdc Java ${in} => ${out}",
47	}, "pkgName")
48
49	xsdcCppRule = pctx.StaticRule("xsdcCppRule", blueprint.RuleParams{
50		Command: `rm -rf "${outDir}" && ` +
51			`${xsdcCmd} $in -p $pkgName -o ${outDir} -c`,
52		CommandDeps: []string{"${xsdcCmd}", "${config.SoongZipCmd}"},
53		Description: "xsdc C++ ${in} => ${out}",
54	}, "pkgName", "outDir")
55
56	xsdConfigRule = pctx.StaticRule("xsdConfigRule", blueprint.RuleParams{
57		Command:     "cp -f ${in} ${output}",
58		Description: "copy the xsd file: ${in} => ${output}",
59	}, "output")
60)
61
62type xsdConfigProperties struct {
63	Srcs         []string
64	Package_name *string
65	Api_dir      *string
66}
67
68type xsdConfig struct {
69	android.ModuleBase
70
71	properties xsdConfigProperties
72
73	genOutputDir android.Path
74	genOutputs_j android.WritablePath
75	genOutputs_c android.WritablePath
76	genOutputs_h android.WritablePath
77
78	docsPath android.Path
79
80	xsdConfigPath android.OptionalPath
81	genOutputs  android.Paths
82}
83
84var _ android.SourceFileProducer = (*xsdConfig)(nil)
85
86type ApiToCheck struct {
87	Api_file         *string
88	Removed_api_file *string
89	Args             *string
90}
91
92type CheckApi struct {
93	Last_released ApiToCheck
94	Current       ApiToCheck
95}
96type DroidstubsProperties struct {
97	Name                 *string
98	Installable          *bool
99	Srcs                 []string
100	Sdk_version          *string
101	Args                 *string
102	Api_filename         *string
103	Removed_api_filename *string
104	Check_api            CheckApi
105}
106
107func (module *xsdConfig) GeneratedSourceFiles() android.Paths {
108	return android.Paths{module.genOutputs_c}
109}
110
111func (module *xsdConfig) Srcs() android.Paths {
112	return append(module.genOutputs, module.genOutputs_j)
113}
114
115func (module *xsdConfig) GeneratedDeps() android.Paths {
116	return android.Paths{module.genOutputs_h}
117}
118
119func (module *xsdConfig) GeneratedHeaderDirs() android.Paths {
120	return android.Paths{module.genOutputDir}
121}
122
123func (module *xsdConfig) DepsMutator(ctx android.BottomUpMutatorContext) {
124	android.ExtractSourcesDeps(ctx, module.properties.Srcs)
125}
126
127func (module *xsdConfig) generateXsdConfig(ctx android.ModuleContext) {
128	if !module.xsdConfigPath.Valid() {
129		return
130	}
131
132	output := android.PathForModuleGen(ctx, module.Name()+".xsd")
133	module.genOutputs = append(module.genOutputs, output)
134
135	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
136		Rule:   xsdConfigRule,
137		Input:  module.xsdConfigPath.Path(),
138		Output: output,
139		Args: map[string]string{
140			"output": output.String(),
141		},
142	})
143}
144
145func (module *xsdConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
146	if len(module.properties.Srcs) != 1 {
147		ctx.PropertyErrorf("srcs", "xsd_config must be one src")
148	}
149
150	ctx.VisitDirectDeps(func(to android.Module) {
151		if doc, ok := to.(java.ApiFilePath); ok {
152			module.docsPath = doc.ApiFilePath()
153		}
154	})
155
156	srcFiles := ctx.ExpandSources(module.properties.Srcs, nil)
157	xsdFile := srcFiles[0]
158
159	pkgName := *module.properties.Package_name
160	filenameStem := strings.Replace(pkgName, ".", "_", -1)
161
162	module.genOutputs_j = android.PathForModuleGen(ctx, "java", filenameStem+"_xsdcgen.srcjar")
163
164	ctx.Build(pctx, android.BuildParams{
165		Rule:        xsdcJavaRule,
166		Description: "xsdc " + xsdFile.String(),
167		Input:       xsdFile,
168		Implicit:    module.docsPath,
169		Output:      module.genOutputs_j,
170		Args: map[string]string{
171			"pkgName": pkgName,
172		},
173	})
174
175	module.genOutputs_c = android.PathForModuleGen(ctx, "cpp", filenameStem+".cpp")
176	module.genOutputs_h = android.PathForModuleGen(ctx, "cpp", "include/"+filenameStem+".h")
177	module.genOutputDir = android.PathForModuleGen(ctx, "cpp", "include")
178
179	ctx.Build(pctx, android.BuildParams{
180		Rule:           xsdcCppRule,
181		Description:    "xsdc " + xsdFile.String(),
182		Input:          xsdFile,
183		Implicit:       module.docsPath,
184		Output:         module.genOutputs_c,
185		ImplicitOutput: module.genOutputs_h,
186		Args: map[string]string{
187			"pkgName": pkgName,
188			"outDir":  android.PathForModuleGen(ctx, "cpp").String(),
189		},
190	})
191	module.xsdConfigPath = android.ExistentPathForSource(ctx, xsdFile.String())
192	module.generateXsdConfig(ctx)
193}
194
195func xsdConfigMutator(mctx android.TopDownMutatorContext) {
196	if module, ok := mctx.Module().(*xsdConfig); ok {
197		name := module.BaseModuleName()
198
199		args := " --stub-packages " + *module.properties.Package_name +
200			" --hide MissingPermission --hide BroadcastBehavior" +
201			" --hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol" +
202			" --hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
203
204		api_dir := proptools.StringDefault(module.properties.Api_dir, "api")
205
206		currentApiFileName := filepath.Join(api_dir, "current.txt")
207		removedApiFileName := filepath.Join(api_dir, "removed.txt")
208
209		check_api := CheckApi{}
210
211		check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
212		check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
213
214		check_api.Last_released.Api_file = proptools.StringPtr(
215			filepath.Join(api_dir, "last_current.txt"))
216		check_api.Last_released.Removed_api_file = proptools.StringPtr(
217			filepath.Join(api_dir, "last_removed.txt"))
218
219		mctx.CreateModule(java.DroidstubsFactory, &DroidstubsProperties{
220			Name:                 proptools.StringPtr(name + ".docs"),
221			Srcs:                 []string{":" + name},
222			Args:                 proptools.StringPtr(args),
223			Api_filename:         proptools.StringPtr(currentApiFileName),
224			Removed_api_filename: proptools.StringPtr(removedApiFileName),
225			Check_api:            check_api,
226			Installable:          proptools.BoolPtr(false),
227			Sdk_version:          proptools.StringPtr("core_platform"),
228		})
229	}
230}
231
232func xsdConfigFactory() android.Module {
233	module := &xsdConfig{}
234	module.AddProperties(&module.properties)
235	android.InitAndroidModule(module)
236
237	return module
238}
239