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/link/XmlReferenceLinker.cpp b/tools/aapt2/link/XmlReferenceLinker.cpp
index bcecd20..6ebb80f 100644
--- a/tools/aapt2/link/XmlReferenceLinker.cpp
+++ b/tools/aapt2/link/XmlReferenceLinker.cpp
@@ -31,13 +31,9 @@
 
 namespace {
 
-/**
- * Visits all references (including parents of styles, references in styles,
- * arrays, etc) and
- * links their symbolic name to their Resource ID, performing mangling and
- * package aliasing
- * as needed.
- */
+// Visits all references (including parents of styles, references in styles, arrays, etc) and
+// links their symbolic name to their Resource ID, performing mangling and package aliasing
+// as needed.
 class ReferenceVisitor : public ValueVisitor {
  public:
   using ValueVisitor::Visit;
@@ -52,7 +48,9 @@
     }
   }
 
-  bool HasError() const { return error_; }
+  bool HasError() const {
+    return error_;
+  }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ReferenceVisitor);
@@ -64,9 +62,7 @@
   bool error_;
 };
 
-/**
- * Visits each xml Element and compiles the attributes within.
- */
+// Visits each xml Element and compiles the attributes within.
 class XmlVisitor : public xml::PackageAwareVisitor {
  public:
   using xml::PackageAwareVisitor::Visit;
@@ -92,18 +88,12 @@
       // they were assigned to the default Attribute.
 
       const Attribute* attribute = &kDefaultAttribute;
-      std::string attribute_package;
 
       if (Maybe<xml::ExtractedPackage> maybe_package =
               xml::ExtractPackageFromNamespace(attr.namespace_uri)) {
         // There is a valid package name for this attribute. We will look this up.
-        attribute_package = maybe_package.value().package;
-        if (attribute_package.empty()) {
-          // Empty package means the 'current' or 'local' package.
-          attribute_package = context_->GetCompilationPackage();
-        }
-
-        Reference attr_ref(ResourceNameRef(attribute_package, ResourceType::kAttr, attr.name));
+        Reference attr_ref(
+            ResourceNameRef(maybe_package.value().package, ResourceType::kAttr, attr.name));
         attr_ref.private_reference = maybe_package.value().private_namespace;
 
         std::string err_str;
@@ -111,9 +101,11 @@
             ReferenceLinker::CompileXmlAttribute(attr_ref, callsite_, symbols_, &err_str);
 
         if (!attr.compiled_attribute) {
-          context_->GetDiagnostics()->Error(DiagMessage(source) << "attribute '"
-                                                                << attribute_package << ":"
-                                                                << attr.name << "' " << err_str);
+          DiagMessage error_msg(source);
+          error_msg << "attribute ";
+          ReferenceLinker::WriteAttributeName(attr_ref, callsite_, this, &error_msg);
+          error_msg << " " << err_str;
+          context_->GetDiagnostics()->Error(error_msg);
           error_ = true;
           continue;
         }
@@ -129,12 +121,8 @@
       } else if ((attribute->type_mask & android::ResTable_map::TYPE_STRING) == 0) {
         // We won't be able to encode this as a string.
         DiagMessage msg(source);
-        msg << "'" << attr.value << "' "
-            << "is incompatible with attribute ";
-        if (!attribute_package.empty()) {
-          msg << attribute_package << ":";
-        }
-        msg << attr.name << " " << *attribute;
+        msg << "'" << attr.value << "' is incompatible with attribute " << attr.name << " "
+            << *attribute;
         context_->GetDiagnostics()->Error(msg);
         error_ = true;
       }
@@ -163,7 +151,17 @@
 }  // namespace
 
 bool XmlReferenceLinker::Consume(IAaptContext* context, xml::XmlResource* resource) {
-  const CallSite callsite = {resource->file.name};
+  CallSite callsite{resource->file.name.package};
+
+  std::string out_name = resource->file.name.entry;
+  NameMangler::Unmangle(&out_name, &callsite.package);
+
+  if (callsite.package.empty()) {
+    // Assume an empty package means that the XML file is local. This is true of AndroidManifest.xml
+    // for example.
+    callsite.package = context->GetCompilationPackage();
+  }
+
   XmlVisitor visitor(resource->file.source, callsite, context, context->GetExternalSymbols());
   if (resource->root) {
     resource->root->Accept(&visitor);