AAPT2: Introduce notion of 'product' to ResourceTable

This allows us to preserve the various product definitions during the compile
phase, and allows us to select the product in the link phase.

This allows compiled files to remain product-independent, so that they do not need
to be recompiled when switching targets.

Bug:25958912
Change-Id: Iaa7eed25c834b67a39cdc9be43613e8b5ab6cdd7
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 51e2dd4..348c32a 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -52,6 +52,11 @@
     void note(const DiagMessage& message) override {}
 };
 
+inline IDiagnostics* getDiagnostics() {
+    static DummyDiagnosticsImpl diag;
+    return &diag;
+}
+
 inline ResourceName parseNameOrDie(const StringPiece16& str) {
     ResourceNameRef ref;
     bool result = ResourceUtils::tryParseReference(str, &ref);
@@ -66,23 +71,25 @@
     return config;
 }
 
-template <typename T> T* getValueForConfig(ResourceTable* table, const StringPiece16& resName,
-                                           const ConfigDescription& config) {
+template <typename T> T* getValueForConfigAndProduct(ResourceTable* table,
+                                                     const StringPiece16& resName,
+                                                     const ConfigDescription& config,
+                                                     const StringPiece& product) {
     Maybe<ResourceTable::SearchResult> result = table->findResource(parseNameOrDie(resName));
     if (result) {
-        ResourceEntry* entry = result.value().entry;
-        auto iter = std::lower_bound(entry->values.begin(), entry->values.end(), config,
-                                     [](const ResourceConfigValue& a, const ConfigDescription& b)
-                                             -> bool {
-                                         return a.config < b;
-                                     });
-        if (iter != entry->values.end() && iter->config == config) {
-            return valueCast<T>(iter->value.get());
+        ResourceConfigValue* configValue = result.value().entry->findValue(config, product);
+        if (configValue) {
+            return valueCast<T>(configValue->value.get());
         }
     }
     return nullptr;
 }
 
+template <typename T> T* getValueForConfig(ResourceTable* table, const StringPiece16& resName,
+                                           const ConfigDescription& config) {
+    return getValueForConfigAndProduct<T>(table, resName, config, {});
+}
+
 template <typename T> T* getValue(ResourceTable* table, const StringPiece16& resName) {
     return getValueForConfig<T>(table, resName, {});
 }