1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef AAPT_LINKER_REFERENCELINKER_H
18 #define AAPT_LINKER_REFERENCELINKER_H
19 
20 #include "Resource.h"
21 #include "ResourceValues.h"
22 #include "ValueVisitor.h"
23 #include "link/Linkers.h"
24 #include "process/IResourceTableConsumer.h"
25 #include "process/SymbolTable.h"
26 #include "xml/XmlDom.h"
27 
28 #include <cassert>
29 
30 namespace aapt {
31 
32 /**
33  * Resolves all references to resources in the ResourceTable and assigns them IDs.
34  * The ResourceTable must already have IDs assigned to each resource.
35  * Once the ResourceTable is processed by this linker, it is ready to be flattened.
36  */
37 struct ReferenceLinker : public IResourceTableConsumer {
38     /**
39      * Returns true if the symbol is visible by the reference and from the callsite.
40      */
41     static bool isSymbolVisible(const SymbolTable::Symbol& symbol, const Reference& ref,
42                                 const CallSite& callSite);
43 
44     /**
45      * Performs name mangling and looks up the resource in the symbol table. Returns nullptr
46      * if the symbol was not found.
47      */
48     static const SymbolTable::Symbol* resolveSymbol(const Reference& reference,
49                                                     NameMangler* mangler, SymbolTable* symbols);
50 
51     /**
52      * Performs name mangling and looks up the resource in the symbol table. If the symbol is
53      * not visible by the reference at the callsite, nullptr is returned. outError holds
54      * the error message.
55      */
56     static const SymbolTable::Symbol* resolveSymbolCheckVisibility(const Reference& reference,
57                                                                    NameMangler* nameMangler,
58                                                                    SymbolTable* symbols,
59                                                                    CallSite* callSite,
60                                                                    std::string* outError);
61 
62     /**
63      * Same as resolveSymbolCheckVisibility(), but also makes sure the symbol is an attribute.
64      * That is, the return value will have a non-null value for ISymbolTable::Symbol::attribute.
65      */
66     static const SymbolTable::Symbol* resolveAttributeCheckVisibility(const Reference& reference,
67                                                                       NameMangler* nameMangler,
68                                                                       SymbolTable* symbols,
69                                                                       CallSite* callSite,
70                                                                       std::string* outError);
71 
72     /**
73      * Resolves the attribute reference and returns an xml::AaptAttribute if successful.
74      * If resolution fails, outError holds the error message.
75      */
76     static Maybe<xml::AaptAttribute> compileXmlAttribute(const Reference& reference,
77                                                          NameMangler* nameMangler,
78                                                          SymbolTable* symbols,
79                                                          CallSite* callSite,
80                                                          std::string* outError);
81 
82     /**
83      * Writes the resource name to the DiagMessage, using the "orig_name (aka <transformed_name>)"
84      * syntax.
85      */
86     static void writeResourceName(DiagMessage* outMsg, const Reference& orig,
87                                   const Reference& transformed);
88 
89     /**
90      * Transforms the package name of the reference to the fully qualified package name using
91      * the xml::IPackageDeclStack, then mangles and looks up the symbol. If the symbol is visible
92      * to the reference at the callsite, the reference is updated with an ID.
93      * Returns false on failure, and an error message is logged to the IDiagnostics in the context.
94      */
95     static bool linkReference(Reference* reference, IAaptContext* context, SymbolTable* symbols,
96                               xml::IPackageDeclStack* decls, CallSite* callSite);
97 
98     /**
99      * Links all references in the ResourceTable.
100      */
101     bool consume(IAaptContext* context, ResourceTable* table) override;
102 };
103 
104 } // namespace aapt
105 
106 #endif /* AAPT_LINKER_REFERENCELINKER_H */
107