diff --git a/android/soongconfig/modules.go b/android/soongconfig/modules.go index 212b752d6..8dd9b8949 100644 --- a/android/soongconfig/modules.go +++ b/android/soongconfig/modules.go @@ -639,9 +639,13 @@ func (s *stringVariable) initializeProperties(v reflect.Value, typ reflect.Type) // Extracts an interface from values containing the properties to apply based on config. // If config does not match a value with a non-nil property set, the default value will be returned. func (s *stringVariable) PropertiesToApply(config SoongConfig, values reflect.Value) (interface{}, error) { + configValue := config.String(s.variable) + if configValue != "" && !InList(configValue, s.values) { + return nil, fmt.Errorf("Soong config property %q must be one of %v, found %q", s.variable, s.values, configValue) + } for j, v := range s.values { f := values.Field(j) - if config.String(s.variable) == v && !f.Elem().IsNil() { + if configValue == v && !f.Elem().IsNil() { return f.Interface(), nil } } @@ -858,3 +862,13 @@ type emptyInterfaceStruct struct { } var emptyInterfaceType = reflect.TypeOf(emptyInterfaceStruct{}).Field(0).Type + +// InList checks if the string belongs to the list +func InList(s string, list []string) bool { + for _, s2 := range list { + if s2 == s { + return true + } + } + return false +} diff --git a/android/soongconfig/modules_test.go b/android/soongconfig/modules_test.go index a7800e8ef..d5d87efc0 100644 --- a/android/soongconfig/modules_test.go +++ b/android/soongconfig/modules_test.go @@ -303,6 +303,10 @@ type soongConfigVars struct { Bool_var interface{} } +type stringSoongConfigVars struct { + String_var interface{} +} + func Test_PropertiesToApply(t *testing.T) { mt, _ := newModuleType(&ModuleTypeProperties{ Module_type: "foo", @@ -365,6 +369,51 @@ func Test_PropertiesToApply(t *testing.T) { } } +func Test_PropertiesToApply_String_Error(t *testing.T) { + mt, _ := newModuleType(&ModuleTypeProperties{ + Module_type: "foo", + Config_namespace: "bar", + Variables: []string{"string_var"}, + Properties: []string{"a", "b"}, + }) + mt.Variables = append(mt.Variables, &stringVariable{ + baseVariable: baseVariable{ + variable: "string_var", + }, + values: []string{"a", "b", "c"}, + }) + stringVarPositive := &properties{ + A: proptools.StringPtr("A"), + B: true, + } + conditionsDefault := &properties{ + A: proptools.StringPtr("default"), + B: false, + } + actualProps := &struct { + Soong_config_variables stringSoongConfigVars + }{ + Soong_config_variables: stringSoongConfigVars{ + String_var: &boolVarProps{ + A: stringVarPositive.A, + B: stringVarPositive.B, + Conditions_default: conditionsDefault, + }, + }, + } + props := reflect.ValueOf(actualProps) + + _, err := PropertiesToApply(mt, props, Config(map[string]string{ + "string_var": "x", + })) + expected := `Soong config property "string_var" must be one of [a b c], found "x"` + if err == nil { + t.Fatalf("Expected an error, got nil") + } else if err.Error() != expected { + t.Fatalf("Error message was not correct, expected %q, got %q", expected, err.Error()) + } +} + func Test_Bp2BuildSoongConfigDefinitions(t *testing.T) { testCases := []struct { desc string