Allow soong config value variables to set nested properties

Previously, it would error out if it saw anything that wasn't a string
or slice of strings. Now it will also recurse in sub-structs.

Fixes: 326255534
Test: go test
Change-Id: Icbca8e4a2cf54b5610599a10805550fed05eb396
diff --git a/android/soongconfig/modules.go b/android/soongconfig/modules.go
index d525bdc..c78b726 100644
--- a/android/soongconfig/modules.go
+++ b/android/soongconfig/modules.go
@@ -681,6 +681,14 @@
 	if !propStruct.IsValid() {
 		return nil, nil
 	}
+	if err := s.printfIntoPropertyRecursive(nil, propStruct, configValue); err != nil {
+		return nil, err
+	}
+
+	return values.Interface(), nil
+}
+
+func (s *valueVariable) printfIntoPropertyRecursive(fieldName []string, propStruct reflect.Value, configValue string) error {
 	for i := 0; i < propStruct.NumField(); i++ {
 		field := propStruct.Field(i)
 		kind := field.Kind()
@@ -695,23 +703,31 @@
 		case reflect.String:
 			err := printfIntoProperty(field, configValue)
 			if err != nil {
-				return nil, fmt.Errorf("soong_config_variables.%s.%s: %s", s.variable, propStruct.Type().Field(i).Name, err)
+				fieldName = append(fieldName, propStruct.Type().Field(i).Name)
+				return fmt.Errorf("soong_config_variables.%s.%s: %s", s.variable, strings.Join(fieldName, "."), err)
 			}
 		case reflect.Slice:
 			for j := 0; j < field.Len(); j++ {
 				err := printfIntoProperty(field.Index(j), configValue)
 				if err != nil {
-					return nil, fmt.Errorf("soong_config_variables.%s.%s: %s", s.variable, propStruct.Type().Field(i).Name, err)
+					fieldName = append(fieldName, propStruct.Type().Field(i).Name)
+					return fmt.Errorf("soong_config_variables.%s.%s: %s", s.variable, strings.Join(fieldName, "."), err)
 				}
 			}
 		case reflect.Bool:
 			// Nothing to do
+		case reflect.Struct:
+			fieldName = append(fieldName, propStruct.Type().Field(i).Name)
+			if err := s.printfIntoPropertyRecursive(fieldName, field, configValue); err != nil {
+				return err
+			}
+			fieldName = fieldName[:len(fieldName)-1]
 		default:
-			return nil, fmt.Errorf("soong_config_variables.%s.%s: unsupported property type %q", s.variable, propStruct.Type().Field(i).Name, kind)
+			fieldName = append(fieldName, propStruct.Type().Field(i).Name)
+			return fmt.Errorf("soong_config_variables.%s.%s: unsupported property type %q", s.variable, strings.Join(fieldName, "."), kind)
 		}
 	}
-
-	return values.Interface(), nil
+	return nil
 }
 
 func printfIntoProperty(propertyValue reflect.Value, configValue string) error {