AAPT2: Separate out the various steps

An early refactor. Some ideas became clearer as
development continued. Now the various phases are much
clearer and more easily reusable.

Also added a ton of tests!

Change-Id: Ic8f0a70c8222370352e63533b329c40457c0903e
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index a93d0ff..cb98afd 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -16,8 +16,11 @@
 
 #include "ResourceParser.h"
 #include "ResourceTable.h"
+#include "ResourceUtils.h"
 #include "ResourceValues.h"
-#include "SourceXmlPullParser.h"
+#include "XmlPullParser.h"
+
+#include "test/Context.h"
 
 #include <gtest/gtest.h>
 #include <sstream>
@@ -27,156 +30,41 @@
 
 constexpr const char* kXmlPreamble = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
 
-TEST(ResourceParserReferenceTest, ParseReferenceWithNoPackage) {
-    ResourceNameRef expected = { {}, ResourceType::kColor, u"foo" };
-    ResourceNameRef actual;
-    bool create = false;
-    bool privateRef = false;
-    EXPECT_TRUE(ResourceParser::tryParseReference(u"@color/foo", &actual, &create, &privateRef));
-    EXPECT_EQ(expected, actual);
-    EXPECT_FALSE(create);
-    EXPECT_FALSE(privateRef);
-}
-
-TEST(ResourceParserReferenceTest, ParseReferenceWithPackage) {
-    ResourceNameRef expected = { u"android", ResourceType::kColor, u"foo" };
-    ResourceNameRef actual;
-    bool create = false;
-    bool privateRef = false;
-    EXPECT_TRUE(ResourceParser::tryParseReference(u"@android:color/foo", &actual, &create,
-                                                  &privateRef));
-    EXPECT_EQ(expected, actual);
-    EXPECT_FALSE(create);
-    EXPECT_FALSE(privateRef);
-}
-
-TEST(ResourceParserReferenceTest, ParseReferenceWithSurroundingWhitespace) {
-    ResourceNameRef expected = { u"android", ResourceType::kColor, u"foo" };
-    ResourceNameRef actual;
-    bool create = false;
-    bool privateRef = false;
-    EXPECT_TRUE(ResourceParser::tryParseReference(u"\t @android:color/foo\n \n\t", &actual,
-                                                  &create, &privateRef));
-    EXPECT_EQ(expected, actual);
-    EXPECT_FALSE(create);
-    EXPECT_FALSE(privateRef);
-}
-
-TEST(ResourceParserReferenceTest, ParseAutoCreateIdReference) {
-    ResourceNameRef expected = { u"android", ResourceType::kId, u"foo" };
-    ResourceNameRef actual;
-    bool create = false;
-    bool privateRef = false;
-    EXPECT_TRUE(ResourceParser::tryParseReference(u"@+android:id/foo", &actual, &create,
-                                                  &privateRef));
-    EXPECT_EQ(expected, actual);
-    EXPECT_TRUE(create);
-    EXPECT_FALSE(privateRef);
-}
-
-TEST(ResourceParserReferenceTest, ParsePrivateReference) {
-    ResourceNameRef expected = { u"android", ResourceType::kId, u"foo" };
-    ResourceNameRef actual;
-    bool create = false;
-    bool privateRef = false;
-    EXPECT_TRUE(ResourceParser::tryParseReference(u"@*android:id/foo", &actual, &create,
-                                                  &privateRef));
-    EXPECT_EQ(expected, actual);
-    EXPECT_FALSE(create);
-    EXPECT_TRUE(privateRef);
-}
-
-TEST(ResourceParserReferenceTest, FailToParseAutoCreateNonIdReference) {
-    bool create = false;
-    bool privateRef = false;
-    ResourceNameRef actual;
-    EXPECT_FALSE(ResourceParser::tryParseReference(u"@+android:color/foo", &actual, &create,
-                                                   &privateRef));
-}
-
-TEST(ResourceParserReferenceTest, ParseStyleParentReference) {
-    Reference ref;
-    std::string errStr;
-    EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"@android:style/foo", &ref, &errStr));
-    EXPECT_EQ(ref.name, (ResourceName{ u"android", ResourceType::kStyle, u"foo" }));
-
-    EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"@style/foo", &ref, &errStr));
-    EXPECT_EQ(ref.name, (ResourceName{ {}, ResourceType::kStyle, u"foo" }));
-
-    EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"?android:style/foo", &ref, &errStr));
-    EXPECT_EQ(ref.name, (ResourceName{ u"android", ResourceType::kStyle, u"foo" }));
-
-    EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"?style/foo", &ref, &errStr));
-    EXPECT_EQ(ref.name, (ResourceName{ {}, ResourceType::kStyle, u"foo" }));
-
-    EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"android:style/foo", &ref, &errStr));
-    EXPECT_EQ(ref.name, (ResourceName{ u"android", ResourceType::kStyle, u"foo" }));
-
-    EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"android:foo", &ref, &errStr));
-    EXPECT_EQ(ref.name, (ResourceName{ u"android", ResourceType::kStyle, u"foo" }));
-
-    EXPECT_TRUE(ResourceParser::parseStyleParentReference(u"foo", &ref, &errStr));
-    EXPECT_EQ(ref.name, (ResourceName{ {}, ResourceType::kStyle, u"foo" }));
+TEST(ResourceParserSingleTest, FailToParseWithNoRootResourcesElement) {
+    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+    std::stringstream input(kXmlPreamble);
+    input << "<attr name=\"foo\"/>" << std::endl;
+    ResourceTable table;
+    ResourceParser parser(context->getDiagnostics(), &table, Source{ "test" }, {});
+    XmlPullParser xmlParser(input);
+    ASSERT_FALSE(parser.parse(&xmlParser));
 }
 
 struct ResourceParserTest : public ::testing::Test {
-    virtual void SetUp() override {
-        mTable = std::make_shared<ResourceTable>();
-        mTable->setPackage(u"android");
+    ResourceTable mTable;
+    std::unique_ptr<IAaptContext> mContext;
+
+    void SetUp() override {
+        mContext = test::ContextBuilder().build();
     }
 
     ::testing::AssertionResult testParse(const StringPiece& str) {
         std::stringstream input(kXmlPreamble);
         input << "<resources>\n" << str << "\n</resources>" << std::endl;
-        ResourceParser parser(mTable, Source{ "test" }, {},
-                              std::make_shared<SourceXmlPullParser>(input));
-        if (parser.parse()) {
+        ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{ "test" }, {});
+        XmlPullParser xmlParser(input);
+        if (parser.parse(&xmlParser)) {
             return ::testing::AssertionSuccess();
         }
         return ::testing::AssertionFailure();
     }
-
-    template <typename T>
-    const T* findResource(const ResourceNameRef& name, const ConfigDescription& config) {
-        using std::begin;
-        using std::end;
-
-        const ResourceTableType* type;
-        const ResourceEntry* entry;
-        std::tie(type, entry) = mTable->findResource(name);
-        if (!type || !entry) {
-            return nullptr;
-        }
-
-        for (const auto& configValue : entry->values) {
-            if (configValue.config == config) {
-                return dynamic_cast<const T*>(configValue.value.get());
-            }
-        }
-        return nullptr;
-    }
-
-    template <typename T>
-    const T* findResource(const ResourceNameRef& name) {
-        return findResource<T>(name, {});
-    }
-
-    std::shared_ptr<ResourceTable> mTable;
 };
 
-TEST_F(ResourceParserTest, FailToParseWithNoRootResourcesElement) {
-    std::stringstream input(kXmlPreamble);
-    input << "<attr name=\"foo\"/>" << std::endl;
-    ResourceParser parser(mTable, {}, {}, std::make_shared<SourceXmlPullParser>(input));
-    ASSERT_FALSE(parser.parse());
-}
-
 TEST_F(ResourceParserTest, ParseQuotedString) {
     std::string input = "<string name=\"foo\">   \"  hey there \" </string>";
     ASSERT_TRUE(testParse(input));
 
-    const String* str = findResource<String>(ResourceName{
-            u"android", ResourceType::kString, u"foo"});
+    String* str = test::getValue<String>(&mTable, u"@string/foo");
     ASSERT_NE(nullptr, str);
     EXPECT_EQ(std::u16string(u"  hey there "), *str->value);
 }
@@ -185,12 +73,22 @@
     std::string input = "<string name=\"foo\">\\?123</string>";
     ASSERT_TRUE(testParse(input));
 
-    const String* str = findResource<String>(ResourceName{
-            u"android", ResourceType::kString, u"foo" });
+    String* str = test::getValue<String>(&mTable, u"@string/foo");
     ASSERT_NE(nullptr, str);
     EXPECT_EQ(std::u16string(u"?123"), *str->value);
 }
 
+TEST_F(ResourceParserTest, IgnoreXliffTags) {
+    std::string input = "<string name=\"foo\" \n"
+                        "        xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n"
+                        "  There are <xliff:g id=\"count\">%1$d</xliff:g> apples</string>";
+    ASSERT_TRUE(testParse(input));
+
+    String* str = test::getValue<String>(&mTable, u"@string/foo");
+    ASSERT_NE(nullptr, str);
+    EXPECT_EQ(StringPiece16(u"There are %1$d apples"), StringPiece16(*str->value));
+}
+
 TEST_F(ResourceParserTest, ParseNull) {
     std::string input = "<integer name=\"foo\">@null</integer>";
     ASSERT_TRUE(testParse(input));
@@ -199,8 +97,7 @@
     // a non-existing value, and this causes problems in styles when trying to resolve
     // an attribute. Null values must be encoded as android::Res_value::TYPE_REFERENCE
     // with a data value of 0.
-    const BinaryPrimitive* integer = findResource<BinaryPrimitive>(ResourceName{
-            u"android", ResourceType::kInteger, u"foo" });
+    BinaryPrimitive* integer = test::getValue<BinaryPrimitive>(&mTable, u"@integer/foo");
     ASSERT_NE(nullptr, integer);
     EXPECT_EQ(uint16_t(android::Res_value::TYPE_REFERENCE), integer->value.dataType);
     EXPECT_EQ(0u, integer->value.data);
@@ -210,8 +107,7 @@
     std::string input = "<integer name=\"foo\">@empty</integer>";
     ASSERT_TRUE(testParse(input));
 
-    const BinaryPrimitive* integer = findResource<BinaryPrimitive>(ResourceName{
-            u"android", ResourceType::kInteger, u"foo" });
+    BinaryPrimitive* integer = test::getValue<BinaryPrimitive>(&mTable, u"@integer/foo");
     ASSERT_NE(nullptr, integer);
     EXPECT_EQ(uint16_t(android::Res_value::TYPE_NULL), integer->value.dataType);
     EXPECT_EQ(uint32_t(android::Res_value::DATA_NULL_EMPTY), integer->value.data);
@@ -222,14 +118,12 @@
                         "<attr name=\"bar\"/>";
     ASSERT_TRUE(testParse(input));
 
-    const Attribute* attr = findResource<Attribute>(ResourceName{
-            u"android", ResourceType::kAttr, u"foo"});
-    EXPECT_NE(nullptr, attr);
+    Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/foo");
+    ASSERT_NE(nullptr, attr);
     EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask);
 
-    attr = findResource<Attribute>(ResourceName{
-            u"android", ResourceType::kAttr, u"bar"});
-    EXPECT_NE(nullptr, attr);
+    attr = test::getValue<Attribute>(&mTable, u"@attr/bar");
+    ASSERT_NE(nullptr, attr);
     EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_ANY), attr->typeMask);
 }
 
@@ -240,8 +134,7 @@
                         "<attr name=\"foo\" format=\"string\"/>";
     ASSERT_TRUE(testParse(input));
 
-    const Attribute* attr = findResource<Attribute>(ResourceName{
-            u"android", ResourceType::kAttr, u"foo"});
+    Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/foo");
     ASSERT_NE(nullptr, attr);
     EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_STRING), attr->typeMask);
 }
@@ -255,8 +148,7 @@
                         "</declare-styleable>";
     ASSERT_TRUE(testParse(input));
 
-    const Attribute* attr = findResource<Attribute>(ResourceName{
-            u"android", ResourceType::kAttr, u"foo"});
+    Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/foo");
     ASSERT_NE(nullptr, attr);
     EXPECT_EQ(uint32_t(android::ResTable_map::TYPE_BOOLEAN), attr->typeMask);
 }
@@ -269,19 +161,21 @@
                         "</attr>";
     ASSERT_TRUE(testParse(input));
 
-    const Attribute* enumAttr = findResource<Attribute>(ResourceName{
-            u"android", ResourceType::kAttr, u"foo"});
+    Attribute* enumAttr = test::getValue<Attribute>(&mTable, u"@attr/foo");
     ASSERT_NE(enumAttr, nullptr);
     EXPECT_EQ(enumAttr->typeMask, android::ResTable_map::TYPE_ENUM);
     ASSERT_EQ(enumAttr->symbols.size(), 3u);
 
-    EXPECT_EQ(enumAttr->symbols[0].symbol.name.entry, u"bar");
+    AAPT_ASSERT_TRUE(enumAttr->symbols[0].symbol.name);
+    EXPECT_EQ(enumAttr->symbols[0].symbol.name.value().entry, u"bar");
     EXPECT_EQ(enumAttr->symbols[0].value, 0u);
 
-    EXPECT_EQ(enumAttr->symbols[1].symbol.name.entry, u"bat");
+    AAPT_ASSERT_TRUE(enumAttr->symbols[1].symbol.name);
+    EXPECT_EQ(enumAttr->symbols[1].symbol.name.value().entry, u"bat");
     EXPECT_EQ(enumAttr->symbols[1].value, 1u);
 
-    EXPECT_EQ(enumAttr->symbols[2].symbol.name.entry, u"baz");
+    AAPT_ASSERT_TRUE(enumAttr->symbols[2].symbol.name);
+    EXPECT_EQ(enumAttr->symbols[2].symbol.name.value().entry, u"baz");
     EXPECT_EQ(enumAttr->symbols[2].value, 2u);
 }
 
@@ -293,23 +187,25 @@
                         "</attr>";
     ASSERT_TRUE(testParse(input));
 
-    const Attribute* flagAttr = findResource<Attribute>(ResourceName{
-            u"android", ResourceType::kAttr, u"foo"});
+    Attribute* flagAttr = test::getValue<Attribute>(&mTable, u"@attr/foo");
     ASSERT_NE(flagAttr, nullptr);
     EXPECT_EQ(flagAttr->typeMask, android::ResTable_map::TYPE_FLAGS);
     ASSERT_EQ(flagAttr->symbols.size(), 3u);
 
-    EXPECT_EQ(flagAttr->symbols[0].symbol.name.entry, u"bar");
+    AAPT_ASSERT_TRUE(flagAttr->symbols[0].symbol.name);
+    EXPECT_EQ(flagAttr->symbols[0].symbol.name.value().entry, u"bar");
     EXPECT_EQ(flagAttr->symbols[0].value, 0u);
 
-    EXPECT_EQ(flagAttr->symbols[1].symbol.name.entry, u"bat");
+    AAPT_ASSERT_TRUE(flagAttr->symbols[1].symbol.name);
+    EXPECT_EQ(flagAttr->symbols[1].symbol.name.value().entry, u"bat");
     EXPECT_EQ(flagAttr->symbols[1].value, 1u);
 
-    EXPECT_EQ(flagAttr->symbols[2].symbol.name.entry, u"baz");
+    AAPT_ASSERT_TRUE(flagAttr->symbols[2].symbol.name);
+    EXPECT_EQ(flagAttr->symbols[2].symbol.name.value().entry, u"baz");
     EXPECT_EQ(flagAttr->symbols[2].value, 2u);
 
-    std::unique_ptr<BinaryPrimitive> flagValue =
-            ResourceParser::tryParseFlagSymbol(*flagAttr, u"baz|bat");
+    std::unique_ptr<BinaryPrimitive> flagValue = ResourceUtils::tryParseFlagSymbol(flagAttr,
+                                                                                   u"baz|bat");
     ASSERT_NE(flagValue, nullptr);
     EXPECT_EQ(flagValue->value.data, 1u | 2u);
 }
@@ -331,28 +227,32 @@
                         "</style>";
     ASSERT_TRUE(testParse(input));
 
-    const Style* style = findResource<Style>(ResourceName{
-            u"android", ResourceType::kStyle, u"foo"});
+    Style* style = test::getValue<Style>(&mTable, u"@style/foo");
     ASSERT_NE(style, nullptr);
-    EXPECT_EQ(ResourceNameRef(u"android", ResourceType::kStyle, u"fu"), style->parent.name);
-    ASSERT_EQ(style->entries.size(), 3u);
+    AAPT_ASSERT_TRUE(style->parent);
+    AAPT_ASSERT_TRUE(style->parent.value().name);
+    EXPECT_EQ(test::parseNameOrDie(u"@style/fu"), style->parent.value().name.value());
+    ASSERT_EQ(3u, style->entries.size());
 
-    EXPECT_EQ(style->entries[0].key.name,
-              (ResourceName{ u"android", ResourceType::kAttr, u"bar" }));
-    EXPECT_EQ(style->entries[1].key.name,
-              (ResourceName{ u"android", ResourceType::kAttr, u"bat" }));
-    EXPECT_EQ(style->entries[2].key.name,
-              (ResourceName{ u"android", ResourceType::kAttr, u"baz" }));
+    AAPT_ASSERT_TRUE(style->entries[0].key.name);
+    EXPECT_EQ(test::parseNameOrDie(u"@attr/bar"), style->entries[0].key.name.value());
+
+    AAPT_ASSERT_TRUE(style->entries[1].key.name);
+    EXPECT_EQ(test::parseNameOrDie(u"@attr/bat"), style->entries[1].key.name.value());
+
+    AAPT_ASSERT_TRUE(style->entries[2].key.name);
+    EXPECT_EQ(test::parseNameOrDie(u"@attr/baz"), style->entries[2].key.name.value());
 }
 
 TEST_F(ResourceParserTest, ParseStyleWithShorthandParent) {
     std::string input = "<style name=\"foo\" parent=\"com.app:Theme\"/>";
     ASSERT_TRUE(testParse(input));
 
-    const Style* style = findResource<Style>(
-            ResourceName{ u"android", ResourceType::kStyle, u"foo" });
+    Style* style = test::getValue<Style>(&mTable, u"@style/foo");
     ASSERT_NE(style, nullptr);
-    EXPECT_EQ(ResourceNameRef(u"com.app", ResourceType::kStyle, u"Theme"), style->parent.name);
+    AAPT_ASSERT_TRUE(style->parent);
+    AAPT_ASSERT_TRUE(style->parent.value().name);
+    EXPECT_EQ(test::parseNameOrDie(u"@com.app:style/Theme"), style->parent.value().name.value());
 }
 
 TEST_F(ResourceParserTest, ParseStyleWithPackageAliasedParent) {
@@ -360,10 +260,11 @@
                         "       name=\"foo\" parent=\"app:Theme\"/>";
     ASSERT_TRUE(testParse(input));
 
-    const Style* style = findResource<Style>(ResourceName{
-            u"android", ResourceType::kStyle, u"foo" });
+    Style* style = test::getValue<Style>(&mTable, u"@style/foo");
     ASSERT_NE(style, nullptr);
-    EXPECT_EQ(ResourceNameRef(u"android", ResourceType::kStyle, u"Theme"), style->parent.name);
+    AAPT_ASSERT_TRUE(style->parent);
+    AAPT_ASSERT_TRUE(style->parent.value().name);
+    EXPECT_EQ(test::parseNameOrDie(u"@android:style/Theme"), style->parent.value().name.value());
 }
 
 TEST_F(ResourceParserTest, ParseStyleWithPackageAliasedItems) {
@@ -373,22 +274,21 @@
             "</style>";
     ASSERT_TRUE(testParse(input));
 
-    const Style* style = findResource<Style>(ResourceName{
-            u"android", ResourceType::kStyle, u"foo" });
+    Style* style = test::getValue<Style>(&mTable, u"@style/foo");
     ASSERT_NE(style, nullptr);
     ASSERT_EQ(1u, style->entries.size());
-    EXPECT_EQ(ResourceNameRef(u"android", ResourceType::kAttr, u"bar"),
-              style->entries[0].key.name);
+    EXPECT_EQ(test::parseNameOrDie(u"@android:attr/bar"), style->entries[0].key.name.value());
 }
 
 TEST_F(ResourceParserTest, ParseStyleWithInferredParent) {
     std::string input = "<style name=\"foo.bar\"/>";
     ASSERT_TRUE(testParse(input));
 
-    const Style* style = findResource<Style>(ResourceName{
-            u"android", ResourceType::kStyle, u"foo.bar" });
+    Style* style = test::getValue<Style>(&mTable, u"@style/foo.bar");
     ASSERT_NE(style, nullptr);
-    EXPECT_EQ(style->parent.name, (ResourceName{ u"android", ResourceType::kStyle, u"foo" }));
+    AAPT_ASSERT_TRUE(style->parent);
+    AAPT_ASSERT_TRUE(style->parent.value().name);
+    EXPECT_EQ(style->parent.value().name.value(), test::parseNameOrDie(u"@style/foo"));
     EXPECT_TRUE(style->parentInferred);
 }
 
@@ -396,10 +296,9 @@
     std::string input = "<style name=\"foo.bar\" parent=\"\"/>";
     ASSERT_TRUE(testParse(input));
 
-    const Style* style = findResource<Style>(ResourceName{
-            u"android", ResourceType::kStyle, u"foo.bar" });
+    Style* style = test::getValue<Style>(&mTable, u"@style/foo.bar");
     ASSERT_NE(style, nullptr);
-    EXPECT_FALSE(style->parent.name.isValid());
+    AAPT_EXPECT_FALSE(style->parent);
     EXPECT_FALSE(style->parentInferred);
 }
 
@@ -407,7 +306,7 @@
     std::string input = "<string name=\"foo\">@+id/bar</string>";
     ASSERT_TRUE(testParse(input));
 
-    const Id* id = findResource<Id>(ResourceName{ u"android", ResourceType::kId, u"bar"});
+    Id* id = test::getValue<Id>(&mTable, u"@id/bar");
     ASSERT_NE(id, nullptr);
 }
 
@@ -418,22 +317,20 @@
                         "</declare-styleable>";
     ASSERT_TRUE(testParse(input));
 
-    const Attribute* attr = findResource<Attribute>(ResourceName{
-            u"android", ResourceType::kAttr, u"bar"});
+    Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/bar");
     ASSERT_NE(attr, nullptr);
     EXPECT_TRUE(attr->isWeak());
 
-    attr = findResource<Attribute>(ResourceName{ u"android", ResourceType::kAttr, u"bat"});
+    attr = test::getValue<Attribute>(&mTable, u"@attr/bat");
     ASSERT_NE(attr, nullptr);
     EXPECT_TRUE(attr->isWeak());
 
-    const Styleable* styleable = findResource<Styleable>(ResourceName{
-            u"android", ResourceType::kStyleable, u"foo" });
+    Styleable* styleable = test::getValue<Styleable>(&mTable, u"@styleable/foo");
     ASSERT_NE(styleable, nullptr);
     ASSERT_EQ(2u, styleable->entries.size());
 
-    EXPECT_EQ((ResourceName{u"android", ResourceType::kAttr, u"bar"}), styleable->entries[0].name);
-    EXPECT_EQ((ResourceName{u"android", ResourceType::kAttr, u"bat"}), styleable->entries[1].name);
+    EXPECT_EQ(test::parseNameOrDie(u"@attr/bar"), styleable->entries[0].name.value());
+    EXPECT_EQ(test::parseNameOrDie(u"@attr/bat"), styleable->entries[1].name.value());
 }
 
 TEST_F(ResourceParserTest, ParseArray) {
@@ -444,14 +341,13 @@
                         "</array>";
     ASSERT_TRUE(testParse(input));
 
-    const Array* array = findResource<Array>(ResourceName{
-            u"android", ResourceType::kArray, u"foo" });
+    Array* array = test::getValue<Array>(&mTable, u"@array/foo");
     ASSERT_NE(array, nullptr);
     ASSERT_EQ(3u, array->items.size());
 
-    EXPECT_NE(nullptr, dynamic_cast<const Reference*>(array->items[0].get()));
-    EXPECT_NE(nullptr, dynamic_cast<const String*>(array->items[1].get()));
-    EXPECT_NE(nullptr, dynamic_cast<const BinaryPrimitive*>(array->items[2].get()));
+    EXPECT_NE(nullptr, valueCast<Reference>(array->items[0].get()));
+    EXPECT_NE(nullptr, valueCast<String>(array->items[1].get()));
+    EXPECT_NE(nullptr, valueCast<BinaryPrimitive>(array->items[2].get()));
 }
 
 TEST_F(ResourceParserTest, ParsePlural) {
@@ -467,11 +363,11 @@
                         "<string name=\"foo\">Hi</string>";
     ASSERT_TRUE(testParse(input));
 
-    const ResourceTableType* type;
-    const ResourceEntry* entry;
-    std::tie(type, entry) = mTable->findResource(ResourceName{
-            u"android", ResourceType::kString, u"foo"});
-    ASSERT_NE(type, nullptr);
+    Maybe<ResourceTable::SearchResult> result = mTable.findResource(
+            test::parseNameOrDie(u"@string/foo"));
+    AAPT_ASSERT_TRUE(result);
+
+    ResourceEntry* entry = result.value().entry;
     ASSERT_NE(entry, nullptr);
     ASSERT_FALSE(entry->values.empty());
     EXPECT_EQ(entry->values.front().comment, u"This is a comment");
@@ -485,7 +381,7 @@
     std::string input = "<public type=\"id\" name=\"foo\"/>";
     ASSERT_TRUE(testParse(input));
 
-    const Id* id = findResource<Id>(ResourceName{ u"android", ResourceType::kId, u"foo" });
+    Id* id = test::getValue<Id>(&mTable, u"@id/foo");
     ASSERT_NE(nullptr, id);
 }