AAPT2: Fixup namespace implementation

A few pieces were missing in the namespace mangling implementation.
Namespace aware libraries now work, along with R class generation.

Bug: 64706588
Test: make AaptTestNamespace_App
Change-Id: I12f78d6aa909e782c0faf7ceaa36058f2e6c864a
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index cbb652e..19de3af 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -274,6 +274,8 @@
     switch (code) {
       case ResXMLParser::START_NAMESPACE: {
         NamespaceDecl decl;
+        decl.line_number = tree.getLineNumber();
+
         size_t len;
         const char16_t* str16 = tree.getNamespacePrefix(&len);
         if (str16) {
@@ -288,6 +290,7 @@
         if (pending_element == nullptr) {
           pending_element = util::make_unique<Element>();
         }
+        pending_element->namespace_decls.push_back(std::move(decl));
         break;
       }
 
@@ -297,8 +300,8 @@
           el = std::move(pending_element);
         } else {
           el = util::make_unique<Element>();
-          ;
         }
+        el->line_number = tree.getLineNumber();
 
         size_t len;
         const char16_t* str16 = tree.getElementNamespace(&len);
@@ -479,10 +482,9 @@
   package_decls_.pop_back();
 }
 
-Maybe<ExtractedPackage> PackageAwareVisitor::TransformPackageAlias(
-    const StringPiece& alias, const StringPiece& local_package) const {
+Maybe<ExtractedPackage> PackageAwareVisitor::TransformPackageAlias(const StringPiece& alias) const {
   if (alias.empty()) {
-    return ExtractedPackage{local_package.to_string(), false /* private */};
+    return ExtractedPackage{{}, false /*private*/};
   }
 
   const auto rend = package_decls_.rend();
@@ -493,7 +495,7 @@
       const PackageDecl& decl = *iter2;
       if (alias == decl.prefix) {
         if (decl.package.package.empty()) {
-          return ExtractedPackage{local_package.to_string(), decl.package.private_namespace};
+          return ExtractedPackage{{}, decl.package.private_namespace};
         }
         return decl.package;
       }
diff --git a/tools/aapt2/xml/XmlDom.h b/tools/aapt2/xml/XmlDom.h
index 1542243..9a9151d 100644
--- a/tools/aapt2/xml/XmlDom.h
+++ b/tools/aapt2/xml/XmlDom.h
@@ -185,8 +185,7 @@
  public:
   using Visitor::Visit;
 
-  Maybe<ExtractedPackage> TransformPackageAlias(
-      const android::StringPiece& alias, const android::StringPiece& local_package) const override;
+  Maybe<ExtractedPackage> TransformPackageAlias(const android::StringPiece& alias) const override;
 
  protected:
   PackageAwareVisitor() = default;
diff --git a/tools/aapt2/xml/XmlDom_test.cpp b/tools/aapt2/xml/XmlDom_test.cpp
index 6ed2d61..10a4587 100644
--- a/tools/aapt2/xml/XmlDom_test.cpp
+++ b/tools/aapt2/xml/XmlDom_test.cpp
@@ -86,19 +86,14 @@
 
   void Visit(Element* el) override {
     if (el->name == "View1") {
-      EXPECT_THAT(TransformPackageAlias("one", "local"),
-                  Eq(make_value(ExtractedPackage{"com.one", false})));
+      EXPECT_THAT(TransformPackageAlias("one"), Eq(make_value(ExtractedPackage{"com.one", false})));
     } else if (el->name == "View2") {
-      EXPECT_THAT(TransformPackageAlias("one", "local"),
-                  Eq(make_value(ExtractedPackage{"com.one", false})));
-      EXPECT_THAT(TransformPackageAlias("two", "local"),
-                  Eq(make_value(ExtractedPackage{"com.two", false})));
+      EXPECT_THAT(TransformPackageAlias("one"), Eq(make_value(ExtractedPackage{"com.one", false})));
+      EXPECT_THAT(TransformPackageAlias("two"), Eq(make_value(ExtractedPackage{"com.two", false})));
     } else if (el->name == "View3") {
-      EXPECT_THAT(TransformPackageAlias("one", "local"),
-                  Eq(make_value(ExtractedPackage{"com.one", false})));
-      EXPECT_THAT(TransformPackageAlias("two", "local"),
-                  Eq(make_value(ExtractedPackage{"com.two", false})));
-      EXPECT_THAT(TransformPackageAlias("three", "local"),
+      EXPECT_THAT(TransformPackageAlias("one"), Eq(make_value(ExtractedPackage{"com.one", false})));
+      EXPECT_THAT(TransformPackageAlias("two"), Eq(make_value(ExtractedPackage{"com.two", false})));
+      EXPECT_THAT(TransformPackageAlias("three"),
                   Eq(make_value(ExtractedPackage{"com.three", false})));
     }
   }
@@ -112,7 +107,6 @@
         </View2>
       </View1>)");
 
-  Debug::DumpXml(doc.get());
   TestVisitor visitor;
   doc->root->Accept(&visitor);
 }
diff --git a/tools/aapt2/xml/XmlPullParser.cpp b/tools/aapt2/xml/XmlPullParser.cpp
index 30bdc50..402e5a4 100644
--- a/tools/aapt2/xml/XmlPullParser.cpp
+++ b/tools/aapt2/xml/XmlPullParser.cpp
@@ -141,17 +141,16 @@
   return event_queue_.front().data2;
 }
 
-Maybe<ExtractedPackage> XmlPullParser::TransformPackageAlias(
-    const StringPiece& alias, const StringPiece& local_package) const {
+Maybe<ExtractedPackage> XmlPullParser::TransformPackageAlias(const StringPiece& alias) const {
   if (alias.empty()) {
-    return ExtractedPackage{local_package.to_string(), false /* private */};
+    return ExtractedPackage{{}, false /*private*/};
   }
 
   const auto end_iter = package_aliases_.rend();
   for (auto iter = package_aliases_.rbegin(); iter != end_iter; ++iter) {
     if (alias == iter->prefix) {
       if (iter->package.package.empty()) {
-        return ExtractedPackage{local_package.to_string(), iter->package.private_namespace};
+        return ExtractedPackage{{}, iter->package.private_namespace};
       }
       return iter->package;
     }
diff --git a/tools/aapt2/xml/XmlPullParser.h b/tools/aapt2/xml/XmlPullParser.h
index a00caa1..63db66f 100644
--- a/tools/aapt2/xml/XmlPullParser.h
+++ b/tools/aapt2/xml/XmlPullParser.h
@@ -119,8 +119,7 @@
    * If xmlns:app="http://schemas.android.com/apk/res-auto", then
    * 'package' will be set to 'defaultPackage'.
    */
-  Maybe<ExtractedPackage> TransformPackageAlias(
-      const android::StringPiece& alias, const android::StringPiece& local_package) const override;
+  Maybe<ExtractedPackage> TransformPackageAlias(const android::StringPiece& alias) const override;
 
   //
   // Remaining methods are for retrieving information about attributes
diff --git a/tools/aapt2/xml/XmlUtil.cpp b/tools/aapt2/xml/XmlUtil.cpp
index fb8cee8..c1186e8 100644
--- a/tools/aapt2/xml/XmlUtil.cpp
+++ b/tools/aapt2/xml/XmlUtil.cpp
@@ -62,19 +62,15 @@
   return {};
 }
 
-void TransformReferenceFromNamespace(IPackageDeclStack* decl_stack,
-                                     const StringPiece& local_package,
-                                     Reference* in_ref) {
+void ResolvePackage(const IPackageDeclStack* decl_stack, Reference* in_ref) {
   if (in_ref->name) {
     if (Maybe<ExtractedPackage> transformed_package =
-            decl_stack->TransformPackageAlias(in_ref->name.value().package,
-                                              local_package)) {
+            decl_stack->TransformPackageAlias(in_ref->name.value().package)) {
       ExtractedPackage& extracted_package = transformed_package.value();
       in_ref->name.value().package = std::move(extracted_package.package);
 
       // If the reference was already private (with a * prefix) and the
-      // namespace is public,
-      // we keep the reference private.
+      // namespace is public, we keep the reference private.
       in_ref->private_reference |= extracted_package.private_namespace;
     }
   }
diff --git a/tools/aapt2/xml/XmlUtil.h b/tools/aapt2/xml/XmlUtil.h
index 866b6dc..4eb359a 100644
--- a/tools/aapt2/xml/XmlUtil.h
+++ b/tools/aapt2/xml/XmlUtil.h
@@ -35,7 +35,7 @@
 // Result of extracting a package name from a namespace URI declaration.
 struct ExtractedPackage {
   // The name of the package. This can be the empty string, which means that the package
-  // should be assumed to be the package being compiled.
+  // should be assumed to be the same as the CallSite it was defined in.
   std::string package;
 
   // True if the package's private namespace was declared. This means that private resources
@@ -51,8 +51,8 @@
 //   http://schemas.android.com/apk/res/<package> or
 //   http://schemas.android.com/apk/prv/res/<package>
 //
-// Special case: if namespaceUri is http://schemas.android.com/apk/res-auto,
-// returns an empty package name.
+// Special case: if namespaceUri is http://schemas.android.com/apk/res-auto, returns an empty
+// package name.
 Maybe<ExtractedPackage> ExtractPackageFromNamespace(const std::string& namespace_uri);
 
 // Returns an XML Android namespace for the given package of the form:
@@ -63,21 +63,20 @@
 std::string BuildPackageNamespace(const android::StringPiece& package,
                                   bool private_reference = false);
 
-// Interface representing a stack of XML namespace declarations. When looking up the package
-// for a namespace prefix, the stack is checked from top to bottom.
+// Interface representing a stack of XML namespace declarations. When looking up the package for a
+// namespace prefix, the stack is checked from top to bottom.
 struct IPackageDeclStack {
   virtual ~IPackageDeclStack() = default;
 
   // Returns an ExtractedPackage struct if the alias given corresponds with a package declaration.
   virtual Maybe<ExtractedPackage> TransformPackageAlias(
-      const android::StringPiece& alias, const android::StringPiece& local_package) const = 0;
+      const android::StringPiece& alias) const = 0;
 };
 
 // Helper function for transforming the original Reference inRef to a fully qualified reference
 // via the IPackageDeclStack. This will also mark the Reference as private if the namespace of the
 // package declaration was private.
-void TransformReferenceFromNamespace(IPackageDeclStack* decl_stack,
-                                     const android::StringPiece& local_package, Reference* in_ref);
+void ResolvePackage(const IPackageDeclStack* decl_stack, Reference* in_ref);
 
 }  // namespace xml
 }  // namespace aapt