AAPT2: Fix overlay support

Supports the <add-resource> tag and mimics old AAPT behavior of
not allowing new resources defined unless <add-resource> was used
or --auto-add-overlay was specified.

Change-Id: I9b461137357617ade37fd7045b418b8e6450b9c4
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index c2ddb5c..d4c536f 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -173,7 +173,7 @@
     ResourceName name;
     Source source;
     ResourceId id;
-    SymbolState symbolState = SymbolState::kUndefined;
+    Maybe<SymbolState> symbolState;
     std::u16string comment;
     std::unique_ptr<Value> value;
     std::list<ParsedResource> childResources;
@@ -182,9 +182,9 @@
 // Recursively adds resources to the ResourceTable.
 static bool addResourcesToTable(ResourceTable* table, const ConfigDescription& config,
                                 IDiagnostics* diag, ParsedResource* res) {
-    if (res->symbolState != SymbolState::kUndefined) {
+    if (res->symbolState) {
         Symbol symbol;
-        symbol.state = res->symbolState;
+        symbol.state = res->symbolState.value();
         symbol.source = res->source;
         symbol.comment = res->comment;
         if (!table->setSymbolState(res->name, res->id, symbol, diag)) {
@@ -325,6 +325,8 @@
             result = parseSymbol(parser, &parsedResource);
         } else if (elementName == u"public-group") {
             result = parsePublicGroup(parser, &parsedResource);
+        } else if (elementName == u"add-resource") {
+            result = parseAddResource(parser, &parsedResource);
         } else {
             // Try parsing the elementName (or type) as a resource. These shall only be
             // resources like 'layout' or 'xml' and they can only be references.
@@ -643,7 +645,7 @@
     return !error;
 }
 
-bool ResourceParser::parseSymbol(xml::XmlPullParser* parser, ParsedResource* outResource) {
+bool ResourceParser::parseSymbolImpl(xml::XmlPullParser* parser, ParsedResource* outResource) {
     const Source source = mSource.withLine(parser->getLineNumber());
 
     Maybe<StringPiece16> maybeType = xml::findNonEmptyAttribute(parser, u"type");
@@ -661,10 +663,25 @@
     }
 
     outResource->name.type = *parsedType;
-    outResource->symbolState = SymbolState::kPrivate;
     return true;
 }
 
+bool ResourceParser::parseSymbol(xml::XmlPullParser* parser, ParsedResource* outResource) {
+    if (parseSymbolImpl(parser, outResource)) {
+        outResource->symbolState = SymbolState::kPrivate;
+        return true;
+    }
+    return false;
+}
+
+bool ResourceParser::parseAddResource(xml::XmlPullParser* parser, ParsedResource* outResource) {
+    if (parseSymbolImpl(parser, outResource)) {
+        outResource->symbolState = SymbolState::kUndefined;
+        return true;
+    }
+    return false;
+}
+
 static uint32_t parseFormatType(const StringPiece16& piece) {
     if (piece == u"reference")      return android::ResTable_map::TYPE_REFERENCE;
     else if (piece == u"string")    return android::ResTable_map::TYPE_STRING;
@@ -870,7 +887,7 @@
     }
 
     return Attribute::Symbol{
-            Reference(ResourceName({}, ResourceType::kId, maybeName.value().toString())),
+            Reference(ResourceNameRef({}, ResourceType::kId, maybeName.value())),
             val.data };
 }