AAPT2: Support static lib referencing static lib

When a static library A references static library B,
and app C references both A and B, we get the following symbol merging,
symbols from library B get imported twice.

We must only check that symbol references to library B are valid
when building library A. We should only merge all the symbols
when building final app C.

Change-Id: I23cba33b0901dcbb5328d9c9dfaa6a979c073c36
diff --git a/tools/aapt2/Linker.h b/tools/aapt2/Linker.h
index 9db64ab..6f03515 100644
--- a/tools/aapt2/Linker.h
+++ b/tools/aapt2/Linker.h
@@ -50,14 +50,25 @@
  */
 class Linker : ValueVisitor {
 public:
+    struct Options {
+        /**
+         * Assign resource Ids to references when linking.
+         * When building a static library, set this to false.
+         */
+        bool linkResourceIds = true;
+    };
+
     /**
      * Create a Linker for the given resource table with the sources available in
      * IResolver. IResolver should contain the ResourceTable as a source too.
      */
-    Linker(std::shared_ptr<ResourceTable> table, std::shared_ptr<IResolver> resolver);
+    Linker(const std::shared_ptr<ResourceTable>& table,
+           const std::shared_ptr<IResolver>& resolver, const Options& options);
 
     Linker(const Linker&) = delete;
 
+    virtual ~Linker() = default;
+
     /**
      * Entry point to the linker. Assigns resource IDs, follows references,
      * and validates types. Returns true if all references to defined values
@@ -73,6 +84,12 @@
     using ResourceNameToSourceMap = std::map<ResourceName, std::vector<SourceLine>>;
     const ResourceNameToSourceMap& getUnresolvedReferences() const;
 
+protected:
+    virtual void doResolveReference(Reference& reference, const SourceLine& source);
+    virtual const Attribute* doResolveAttribute(Reference& attribute, const SourceLine& source);
+
+    std::shared_ptr<IResolver> mResolver;
+
 private:
     struct Args : public ValueVisitorArgs {
         Args(const ResourceNameRef& r, const SourceLine& s);
@@ -92,33 +109,13 @@
     void visit(Plural& plural, ValueVisitorArgs& args) override;
 
     void processAttributeValue(const ResourceNameRef& name, const SourceLine& source,
-            const Attribute& attr, std::unique_ptr<Item>& value);
+                               const Attribute& attr, std::unique_ptr<Item>& value);
 
     void addUnresolvedSymbol(const ResourceNameRef& name, const SourceLine& source);
 
-    /**
-     * Node of the resource table graph.
-     */
-    struct Node {
-        // We use ResourceNameRef and StringPiece, which are safe so long as the ResourceTable
-        // that defines the data isn't modified.
-        ResourceNameRef name;
-        StringPiece source;
-        size_t line;
-
-        // The reference object that points to name.
-        Reference* reference;
-
-        bool operator<(const Node& rhs) const;
-        bool operator==(const Node& rhs) const;
-        bool operator!=(const Node& rhs) const;
-    };
-    friend ::std::ostream& operator<<(::std::ostream&, const Node&);
-
     std::shared_ptr<ResourceTable> mTable;
-    std::shared_ptr<IResolver> mResolver;
-    std::map<ResourceNameRef, std::vector<Node>> mGraph;
     std::map<ResourceName, std::vector<SourceLine>> mUnresolvedSymbols;
+    Options mOptions;
     bool mError;
 };