Add support for merging defaults soong_config_module_types into bp2build
select statements.

This supports defaults from the same or different namespaces, and
transitively defaults as well.

Test: soong unit tests
Test: CI
Change-Id: I99435bacfcfbfe20ad753b8021a1779531d7595a
diff --git a/android/variable.go b/android/variable.go
index 89cd59e..20b268e 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -640,13 +640,15 @@
 	}
 
 	if m, ok := module.(Bazelable); ok && m.namespacedVariableProps() != nil {
-		for namespace, namespacedVariableProp := range m.namespacedVariableProps() {
-			productVariableValues(
-				soongconfig.SoongConfigProperty,
-				namespacedVariableProp,
-				namespace,
-				"",
-				&productConfigProperties)
+		for namespace, namespacedVariableProps := range m.namespacedVariableProps() {
+			for _, namespacedVariableProp := range namespacedVariableProps {
+				productVariableValues(
+					soongconfig.SoongConfigProperty,
+					namespacedVariableProp,
+					namespace,
+					"",
+					&productConfigProperties)
+			}
 		}
 	}
 
@@ -665,7 +667,19 @@
 		FullConfig: config,              // e.g. size, feature1-x86, size__conditions_default
 	}
 
-	(*p)[propertyName][productConfigProp] = property
+	if existing, ok := (*p)[propertyName][productConfigProp]; ok && namespace != "" {
+		switch dst := existing.(type) {
+		case []string:
+			if src, ok := property.([]string); ok {
+				dst = append(dst, src...)
+				(*p)[propertyName][productConfigProp] = dst
+			}
+		default:
+			// TODO(jingwen): Add support for more types.
+		}
+	} else {
+		(*p)[propertyName][productConfigProp] = property
+	}
 }
 
 var (
@@ -701,19 +715,10 @@
 	return v, true
 }
 
-// productVariableValues uses reflection to convert a property struct for
-// product_variables and soong_config_variables to structs that can be generated
-// as select statements.
-func productVariableValues(
-	fieldName string, variableProps interface{}, namespace, suffix string, productConfigProperties *ProductConfigProperties) {
-	if suffix != "" {
-		suffix = "-" + suffix
-	}
-
-	// variableValues represent the product_variables or soong_config_variables
-	// struct.
-	variableValues := reflect.ValueOf(variableProps).Elem().FieldByName(fieldName)
-
+func (productConfigProperties *ProductConfigProperties) AddProductConfigProperties(namespace, suffix string, variableValues reflect.Value) {
+	// variableValues can either be a product_variables or
+	// soong_config_variables struct.
+	//
 	// Example of product_variables:
 	//
 	// product_variables: {
@@ -834,6 +839,20 @@
 	}
 }
 
+// productVariableValues uses reflection to convert a property struct for
+// product_variables and soong_config_variables to structs that can be generated
+// as select statements.
+func productVariableValues(
+	fieldName string, variableProps interface{}, namespace, suffix string, productConfigProperties *ProductConfigProperties) {
+	if suffix != "" {
+		suffix = "-" + suffix
+	}
+
+	// variableValues represent the product_variables or soong_config_variables struct.
+	variableValues := reflect.ValueOf(variableProps).Elem().FieldByName(fieldName)
+	productConfigProperties.AddProductConfigProperties(namespace, suffix, variableValues)
+}
+
 func VariableMutator(mctx BottomUpMutatorContext) {
 	var module Module
 	var ok bool