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 "android-base/macros.h"
21
22#include "Resource.h"
23#include "ResourceValues.h"
24#include "ValueVisitor.h"
25#include "link/Linkers.h"
26#include "process/IResourceTableConsumer.h"
27#include "process/SymbolTable.h"
28#include "xml/XmlDom.h"
29
30namespace aapt {
31
32/**
33 * Resolves all references to resources in the ResourceTable and assigns them
34 * IDs.
35 * The ResourceTable must already have IDs assigned to each resource.
36 * Once the ResourceTable is processed by this linker, it is ready to be
37 * flattened.
38 */
39class ReferenceLinker : public IResourceTableConsumer {
40 public:
41  ReferenceLinker() = default;
42
43  /**
44   * Returns true if the symbol is visible by the reference and from the
45   * callsite.
46   */
47  static bool IsSymbolVisible(const SymbolTable::Symbol& symbol,
48                              const Reference& ref, const CallSite& callsite);
49
50  /**
51   * Performs name mangling and looks up the resource in the symbol table.
52   * Returns nullptr if the symbol was not found.
53   */
54  static const SymbolTable::Symbol* ResolveSymbol(const Reference& reference, SymbolTable* symbols);
55
56  /**
57   * Performs name mangling and looks up the resource in the symbol table. If
58   * the symbol is not visible by the reference at the callsite, nullptr is
59   * returned. out_error holds the error message.
60   */
61  static const SymbolTable::Symbol* ResolveSymbolCheckVisibility(const Reference& reference,
62                                                                 const CallSite& callsite,
63                                                                 SymbolTable* symbols,
64                                                                 std::string* out_error);
65
66  /**
67   * Same as resolveSymbolCheckVisibility(), but also makes sure the symbol is
68   * an attribute.
69   * That is, the return value will have a non-null value for
70   * ISymbolTable::Symbol::attribute.
71   */
72  static const SymbolTable::Symbol* ResolveAttributeCheckVisibility(const Reference& reference,
73                                                                    const CallSite& callsite,
74                                                                    SymbolTable* symbols,
75                                                                    std::string* out_error);
76
77  /**
78   * Resolves the attribute reference and returns an xml::AaptAttribute if
79   * successful.
80   * If resolution fails, outError holds the error message.
81   */
82  static Maybe<xml::AaptAttribute> CompileXmlAttribute(const Reference& reference,
83                                                       const CallSite& callsite,
84                                                       SymbolTable* symbols,
85                                                       std::string* out_error);
86
87  /**
88   * Writes the resource name to the DiagMessage, using the
89   * "orig_name (aka <transformed_name>)" syntax.
90   */
91  static void WriteResourceName(DiagMessage* out_msg, const Reference& orig,
92                                const Reference& transformed);
93
94  /**
95   * Transforms the package name of the reference to the fully qualified package
96   * name using
97   * the xml::IPackageDeclStack, then mangles and looks up the symbol. If the
98   * symbol is visible
99   * to the reference at the callsite, the reference is updated with an ID.
100   * Returns false on failure, and an error message is logged to the
101   * IDiagnostics in the context.
102   */
103  static bool LinkReference(const CallSite& callsite, Reference* reference, IAaptContext* context,
104                            SymbolTable* symbols, xml::IPackageDeclStack* decls);
105
106  /**
107   * Links all references in the ResourceTable.
108   */
109  bool Consume(IAaptContext* context, ResourceTable* table) override;
110
111 private:
112  DISALLOW_COPY_AND_ASSIGN(ReferenceLinker);
113};
114
115}  // namespace aapt
116
117#endif /* AAPT_LINKER_REFERENCELINKER_H */
118