Add abstraction for tracking compile multilib usages

Ensures consistent tracking of multilib usages.

Bug: 142935992
Test: m nothing
Change-Id: I82ba4a53a21a0823503cb98f7edfde449b48b440
diff --git a/sdk/update.go b/sdk/update.go
index ce25fc4..c706d1c 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -144,8 +144,7 @@
 	byType := make(map[android.SdkMemberType][]*sdkMember)
 	byName := make(map[string]*sdkMember)
 
-	lib32 := false // True if any of the members have 32 bit version.
-	lib64 := false // True if any of the members have 64 bit version.
+	multilib := multilibNone
 
 	for _, memberRef := range memberRefs {
 		memberType := memberRef.memberType
@@ -159,12 +158,7 @@
 			byType[memberType] = append(byType[memberType], member)
 		}
 
-		multilib := variant.Target().Arch.ArchType.Multilib
-		if multilib == "lib32" {
-			lib32 = true
-		} else if multilib == "lib64" {
-			lib64 = true
-		}
+		multilib = multilib.addArchType(variant.Target().Arch.ArchType)
 
 		// Only append new variants to the list. This is needed because a member can be both
 		// exported by the sdk and also be a transitive sdk member.
@@ -177,17 +171,7 @@
 		members = append(members, membersOfType...)
 	}
 
-	// Compute the setting of multilib.
-	var multilib string
-	if lib32 && lib64 {
-		multilib = "both"
-	} else if lib32 {
-		multilib = "32"
-	} else if lib64 {
-		multilib = "64"
-	}
-
-	return members, multilib
+	return members, multilib.String()
 }
 
 func appendUniqueVariants(variants []android.SdkAware, newVariant android.SdkAware) []android.SdkAware {
@@ -787,6 +771,47 @@
 	return m.variants
 }
 
+// Track usages of multilib variants.
+type multilibUsage int
+
+const (
+	multilibNone multilibUsage = 0
+	multilib32   multilibUsage = 1
+	multilib64   multilibUsage = 2
+	multilibBoth               = multilib32 | multilib64
+)
+
+// Add the multilib that is used in the arch type.
+func (m multilibUsage) addArchType(archType android.ArchType) multilibUsage {
+	multilib := archType.Multilib
+	switch multilib {
+	case "":
+		return m
+	case "lib32":
+		return m | multilib32
+	case "lib64":
+		return m | multilib64
+	default:
+		panic(fmt.Errorf("Unknown Multilib field in ArchType, expected 'lib32' or 'lib64', found %q", multilib))
+	}
+}
+
+func (m multilibUsage) String() string {
+	switch m {
+	case multilibNone:
+		return ""
+	case multilib32:
+		return "32"
+	case multilib64:
+		return "64"
+	case multilibBoth:
+		return "both"
+	default:
+		panic(fmt.Errorf("Unknown multilib value, found %b, expected one of %b, %b, %b or %b",
+			m, multilibNone, multilib32, multilib64, multilibBoth))
+	}
+}
+
 type baseInfo struct {
 	Properties android.SdkMemberProperties
 }
@@ -865,8 +890,11 @@
 		return
 	}
 
+	multilib := multilibNone
 	var archPropertiesList []android.SdkMemberProperties
 	for _, archInfo := range osInfo.archInfos {
+		multilib = multilib.addArchType(archInfo.archType)
+
 		// Optimize the arch properties first.
 		archInfo.optimizeProperties(commonValueExtractor)
 
@@ -876,19 +904,7 @@
 	commonValueExtractor.extractCommonProperties(osInfo.Properties, archPropertiesList)
 
 	// Choose setting for compile_multilib that is appropriate for the arch variants supplied.
-	var multilib string
-	archVariantCount := len(osInfo.archInfos)
-	if archVariantCount == 2 {
-		multilib = "both"
-	} else if archVariantCount == 1 {
-		if strings.HasSuffix(osInfo.archInfos[0].archType.Name, "64") {
-			multilib = "64"
-		} else {
-			multilib = "32"
-		}
-	}
-
-	osInfo.Properties.Base().Compile_multilib = multilib
+	osInfo.Properties.Base().Compile_multilib = multilib.String()
 }
 
 // Add the properties for an os to a property set.