AAPT2: Process <java-symbols> and private symbol package

Need to introduce the idea of multiple levels of visibility to support <java-symbol>.

Public, Private, Undefined.

Public means it is accessible from outside and requires an ID assigned.
Private means that we explicitly want this to be a symbol (show up in R.java), but not visible
to other packages. No ID required.

Undefined is any normal resource. When --private-symbols is specified in the link phase,
these resources will not show up in R.java.

Change-Id: Icba89221e08e685dee7683786aa7112baf28c856
diff --git a/tools/aapt2/JavaClassGenerator.cpp b/tools/aapt2/JavaClassGenerator.cpp
index 84a4125..cdf1b6a 100644
--- a/tools/aapt2/JavaClassGenerator.cpp
+++ b/tools/aapt2/JavaClassGenerator.cpp
@@ -77,6 +77,18 @@
     return output;
 }
 
+bool JavaClassGenerator::skipSymbol(SymbolState state) {
+    switch (mOptions.types) {
+    case JavaClassGeneratorOptions::SymbolTypes::kAll:
+        return false;
+    case JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate:
+        return state == SymbolState::kUndefined;
+    case JavaClassGeneratorOptions::SymbolTypes::kPublic:
+        return state != SymbolState::kPublic;
+    }
+    return true;
+}
+
 void JavaClassGenerator::generateStyleable(const StringPiece16& packageNameToGenerate,
                                            const std::u16string& entryName,
                                            const Styleable* styleable,
@@ -121,7 +133,7 @@
         // We may reference IDs from other packages, so prefix the entry name with
         // the package.
         const ResourceNameRef& itemName = sortedAttributes[i].second;
-        if (packageNameToGenerate != itemName.package) {
+        if (!itemName.package.empty() && packageNameToGenerate != itemName.package) {
             *out << "_" << transform(itemName.package);
         }
         *out << "_" << transform(itemName.entry) << " = " << i << ";\n";
@@ -137,7 +149,11 @@
     std::u16string unmangledPackage;
     std::u16string unmangledName;
     for (const auto& entry : type->entries) {
-        ResourceId id = { package->id.value(), type->id.value(), entry->id.value() };
+        if (skipSymbol(entry->symbolStatus.state)) {
+            continue;
+        }
+
+        ResourceId id(package->id.value(), type->id.value(), entry->id.value());
         assert(id.isValid());
 
         unmangledName = entry->name;
@@ -157,7 +173,7 @@
         }
 
         if (!isValidSymbol(unmangledName)) {
-            ResourceNameRef resourceName = { packageNameToGenerate, type->type, unmangledName };
+            ResourceNameRef resourceName(packageNameToGenerate, type->type, unmangledName);
             std::stringstream err;
             err << "invalid symbol name '" << resourceName << "'";
             mError = err.str();
@@ -177,13 +193,24 @@
 }
 
 bool JavaClassGenerator::generate(const StringPiece16& packageNameToGenerate, std::ostream* out) {
-    generateHeader(packageNameToGenerate, out);
+    return generate(packageNameToGenerate, packageNameToGenerate, out);
+}
+
+bool JavaClassGenerator::generate(const StringPiece16& packageNameToGenerate,
+                                  const StringPiece16& outPackageName, std::ostream* out) {
+    generateHeader(outPackageName, out);
 
     *out << "public final class R {\n";
 
     for (const auto& package : mTable->packages) {
         for (const auto& type : package->types) {
-            *out << "    public static final class " << type->type << " {\n";
+            StringPiece16 typeStr;
+            if (type->type == ResourceType::kAttrPrivate) {
+                typeStr = toString(ResourceType::kAttr);
+            } else {
+                typeStr = toString(type->type);
+            }
+            *out << "    public static final class " << typeStr << " {\n";
             if (!generateType(packageNameToGenerate, package.get(), type.get(), out)) {
                 return false;
             }
@@ -196,4 +223,6 @@
     return true;
 }
 
+
+
 } // namespace aapt