Revert^2 "Add ability to declare licenses in soong."

df98d3e4a546a3a3e5e6aba5ca6151d00547ef20

Change-Id: Ie7e1695ecb8cd943124426a0cad2c0d1db2b46ed
diff --git a/android/licenses.go b/android/licenses.go
new file mode 100644
index 0000000..1000429
--- /dev/null
+++ b/android/licenses.go
@@ -0,0 +1,295 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+	"reflect"
+	"sync"
+
+	"github.com/google/blueprint"
+)
+
+// Adds cross-cutting licenses dependency to propagate license metadata through the build system.
+//
+// Stage 1 - bottom-up records package-level default_applicable_licenses property mapped by package name.
+// Stage 2 - bottom-up converts licenses property or package default_applicable_licenses to dependencies.
+// Stage 3 - bottom-up type-checks every added applicable license dependency and license_kind dependency.
+// Stage 4 - GenerateBuildActions calculates properties for the union of license kinds, conditions and texts.
+
+type licensesDependencyTag struct {
+	blueprint.BaseDependencyTag
+}
+
+var (
+	licensesTag = licensesDependencyTag{}
+)
+
+// Describes the property provided by a module to reference applicable licenses.
+type applicableLicensesProperty interface {
+	// The name of the property. e.g. default_applicable_licenses or licenses
+	getName() string
+	// The values assigned to the property. (Must reference license modules.)
+	getStrings() []string
+}
+
+type applicableLicensesPropertyImpl struct {
+	name             string
+	licensesProperty *[]string
+}
+
+func newApplicableLicensesProperty(name string, licensesProperty *[]string) applicableLicensesProperty {
+	return applicableLicensesPropertyImpl{
+		name: name,
+		licensesProperty: licensesProperty,
+	}
+}
+
+func (p applicableLicensesPropertyImpl) getName() string {
+	return p.name
+}
+
+func (p applicableLicensesPropertyImpl) getStrings() []string {
+	return *p.licensesProperty
+}
+
+// Set the primary applicable licenses property for a module.
+func setPrimaryLicensesProperty(module Module, name string, licensesProperty *[]string) {
+	module.base().primaryLicensesProperty = newApplicableLicensesProperty(name, licensesProperty)
+}
+
+// Storage blob for a package's default_applicable_licenses mapped by package directory.
+type licensesContainer struct {
+	licenses []string
+}
+
+func (r licensesContainer) getLicenses() []string {
+	return r.licenses
+}
+
+var packageDefaultLicensesMap = NewOnceKey("packageDefaultLicensesMap")
+
+// The map from package dir name to default applicable licenses as a licensesContainer.
+func moduleToPackageDefaultLicensesMap(config Config) *sync.Map {
+	return config.Once(packageDefaultLicensesMap, func() interface{} {
+		return &sync.Map{}
+	}).(*sync.Map)
+}
+
+// Registers the function that maps each package to its default_applicable_licenses.
+//
+// This goes before defaults expansion so the defaults can pick up the package default.
+func RegisterLicensesPackageMapper(ctx RegisterMutatorsContext) {
+	ctx.BottomUp("licensesPackageMapper", licensesPackageMapper).Parallel()
+}
+
+// Registers the function that gathers the license dependencies for each module.
+//
+// This goes after defaults expansion so that it can pick up default licenses and before visibility enforcement.
+func RegisterLicensesPropertyGatherer(ctx RegisterMutatorsContext) {
+	ctx.BottomUp("licensesPropertyGatherer", licensesPropertyGatherer).Parallel()
+}
+
+// Registers the function that verifies the licenses and license_kinds dependency types for each module.
+func RegisterLicensesDependencyChecker(ctx RegisterMutatorsContext) {
+	ctx.BottomUp("licensesPropertyChecker", licensesDependencyChecker).Parallel()
+}
+
+// Maps each package to its default applicable licenses.
+func licensesPackageMapper(ctx BottomUpMutatorContext) {
+	p, ok := ctx.Module().(*packageModule)
+	if !ok {
+		return
+	}
+
+	licenses := getLicenses(ctx, p)
+
+	dir := ctx.ModuleDir()
+	c := makeLicensesContainer(licenses)
+	moduleToPackageDefaultLicensesMap(ctx.Config()).Store(dir, c)
+}
+
+// Copies the default_applicable_licenses property values for mapping by package directory.
+func makeLicensesContainer(propVals []string) licensesContainer {
+	licenses := make([]string, 0, len(propVals))
+	licenses = append(licenses, propVals...)
+
+	return licensesContainer{licenses}
+}
+
+// Gathers the applicable licenses into dependency references after defaults expansion.
+func licensesPropertyGatherer(ctx BottomUpMutatorContext) {
+	m, ok := ctx.Module().(Module)
+	if !ok {
+		return
+	}
+
+	if exemptFromRequiredApplicableLicensesProperty(m) {
+		return
+	}
+
+	licenses := getLicenses(ctx, m)
+
+	ctx.AddVariationDependencies(nil, licensesTag, licenses...)
+}
+
+// Verifies the license and license_kind dependencies are each the correct kind of module.
+func licensesDependencyChecker(ctx BottomUpMutatorContext) {
+	m, ok := ctx.Module().(Module)
+	if !ok {
+		return
+	}
+
+	// license modules have no licenses, but license_kinds must refer to license_kind modules
+	if _, ok := m.(*licenseModule); ok {
+		for _, module := range ctx.GetDirectDepsWithTag(licenseKindTag) {
+			if _, ok := module.(*licenseKindModule); !ok {
+				ctx.ModuleErrorf("license_kinds property %q is not a license_kind module", ctx.OtherModuleName(module))
+			}
+		}
+		return
+	}
+
+	if exemptFromRequiredApplicableLicensesProperty(m) {
+		return
+	}
+
+	for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
+		if _, ok := module.(*licenseModule); !ok {
+			propertyName := "licenses"
+			primaryProperty := m.base().primaryLicensesProperty
+			if primaryProperty != nil {
+				propertyName = primaryProperty.getName()
+			}
+			ctx.ModuleErrorf("%s property %q is not a license module", propertyName, ctx.OtherModuleName(module))
+		}
+	}
+}
+
+// Flattens license and license_kind dependencies into calculated properties.
+//
+// Re-validates applicable licenses properties refer only to license modules and license_kinds properties refer
+// only to license_kind modules.
+func licensesPropertyFlattener(ctx ModuleContext) {
+	m, ok := ctx.Module().(Module)
+	if !ok {
+		return
+	}
+
+	// license modules have no licenses, but license_kinds must refer to license_kind modules
+	if l, ok := m.(*licenseModule); ok {
+		mergeProps(&m.base().commonProperties.Effective_licenses, ctx.ModuleName())
+		mergeProps(&m.base().commonProperties.Effective_license_text, PathsForModuleSrc(ctx, l.properties.License_text).Strings()...)
+		for _, module := range ctx.GetDirectDepsWithTag(licenseKindTag) {
+			if lk, ok := module.(*licenseKindModule); ok {
+				mergeProps(&m.base().commonProperties.Effective_license_conditions, lk.properties.Conditions...)
+				mergeProps(&m.base().commonProperties.Effective_license_kinds, ctx.OtherModuleName(module))
+			} else {
+				ctx.ModuleErrorf("license_kinds property %q is not a license_kind module", ctx.OtherModuleName(module))
+			}
+		}
+		return
+	}
+
+	if exemptFromRequiredApplicableLicensesProperty(m) {
+		return
+	}
+
+	for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
+		if l, ok := module.(*licenseModule); ok {
+			if m.base().commonProperties.Effective_package_name == nil && l.properties.Package_name != nil {
+				m.base().commonProperties.Effective_package_name = l.properties.Package_name
+			}
+			mergeProps(&m.base().commonProperties.Effective_licenses, module.base().commonProperties.Effective_licenses...)
+			mergeProps(&m.base().commonProperties.Effective_license_text, module.base().commonProperties.Effective_license_text...)
+			mergeProps(&m.base().commonProperties.Effective_license_kinds, module.base().commonProperties.Effective_license_kinds...)
+			mergeProps(&m.base().commonProperties.Effective_license_conditions, module.base().commonProperties.Effective_license_conditions...)
+		} else {
+			propertyName := "licenses"
+			primaryProperty := m.base().primaryLicensesProperty
+			if primaryProperty != nil {
+				propertyName = primaryProperty.getName()
+			}
+			ctx.ModuleErrorf("%s property %q is not a license module", propertyName, ctx.OtherModuleName(module))
+		}
+	}
+}
+
+// Update a property string array with a distinct union of its values and a list of new values.
+func mergeProps(prop *[]string, values ...string) {
+	s := make(map[string]bool)
+	for _, v := range *prop {
+		s[v] = true
+	}
+	for _, v := range values {
+		s[v] = true
+	}
+	*prop = []string{}
+	*prop = append(*prop, SortedStringKeys(s)...)
+}
+
+// Get the licenses property falling back to the package default.
+func getLicenses(ctx BaseModuleContext, module Module) []string {
+	if exemptFromRequiredApplicableLicensesProperty(module) {
+		return nil
+	}
+
+	primaryProperty := module.base().primaryLicensesProperty
+	if primaryProperty == nil {
+		if ctx.Config().IsEnvTrue("ANDROID_REQUIRE_LICENSES") {
+			ctx.ModuleErrorf("module type %q must have an applicable licenses property", ctx.OtherModuleType(module))
+		}
+		return nil
+	}
+
+	licenses := primaryProperty.getStrings()
+	if len(licenses) > 0 {
+		s := make(map[string]bool)
+		for _, l := range licenses {
+			if _, ok := s[l]; ok {
+				ctx.ModuleErrorf("duplicate %q %s", l, primaryProperty.getName())
+			}
+			s[l] = true
+		}
+		return licenses
+	}
+
+	dir := ctx.OtherModuleDir(module)
+
+	moduleToApplicableLicenses := moduleToPackageDefaultLicensesMap(ctx.Config())
+	value, ok := moduleToApplicableLicenses.Load(dir)
+	var c licensesContainer
+	if ok {
+		c = value.(licensesContainer)
+	} else {
+		c = licensesContainer{}
+	}
+	return c.getLicenses()
+}
+
+// Returns whether a module is an allowed list of modules that do not have or need applicable licenses.
+func exemptFromRequiredApplicableLicensesProperty(module Module) bool {
+	switch reflect.TypeOf(module).String() {
+	case "*android.licenseModule": // is a license, doesn't need one
+	case "*android.licenseKindModule": // is a license, doesn't need one
+	case "*android.NamespaceModule": // just partitions things, doesn't add anything
+	case "*android.soongConfigModuleTypeModule": // creates aliases for modules with licenses
+	case "*android.soongConfigModuleTypeImport": // creates aliases for modules with licenses
+	case "*android.soongConfigStringVariableDummyModule": // used for creating aliases
+	case "*android.SoongConfigBoolVariableDummyModule": // used for creating aliases
+	default:
+		return false
+	}
+	return true
+}