summaryrefslogtreecommitdiffstats
path: root/tools/aapt2/ResourceParser.h
blob: 7618999f002386c8970b069049142a02347d4adc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef AAPT_RESOURCE_PARSER_H
#define AAPT_RESOURCE_PARSER_H

#include "ConfigDescription.h"
#include "Logger.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "StringPiece.h"
#include "StringPool.h"
#include "XmlPullParser.h"

#include <istream>
#include <memory>

namespace aapt {

/*
 * Parses an XML file for resources and adds them to a ResourceTable.
 */
class ResourceParser {
public:
    /*
     * Extracts the package, type, and name from a string of the format:
     *
     *      [package:]type/name
     *
     * where the package can be empty. Validation must be performed on each
     * individual extracted piece to verify that the pieces are valid.
     */
    static void extractResourceName(const StringPiece16& str, StringPiece16* outPackage,
                                    StringPiece16* outType, StringPiece16* outEntry);

    /*
     * Returns true if the string was parsed as a reference (@[+][package:]type/name), with
     * `outReference` set to the parsed reference.
     *
     * If '+' was present in the reference, `outCreate` is set to true.
     * If '*' was present in the reference, `outPrivate` is set to true.
     */
    static bool tryParseReference(const StringPiece16& str, ResourceNameRef* outReference,
                                  bool* outCreate, bool* outPrivate);

    /*
     * Returns true if the string was parsed as an attribute reference (?[package:]type/name),
     * with `outReference` set to the parsed reference.
     */
    static bool tryParseAttributeReference(const StringPiece16& str,
                                           ResourceNameRef* outReference);

    /*
     * Returns true if the string `str` was parsed as a valid reference to a style.
     * The format for a style parent is slightly more flexible than a normal reference:
     *
     * @[package:]style/<entry> or
     * ?[package:]style/<entry> or
     * <package>:[style/]<entry>
     */
    static bool parseStyleParentReference(const StringPiece16& str, Reference* outReference,
                                          std::string* outError);

    /*
     * Returns a Reference object if the string was parsed as a resource or attribute reference,
     * ( @[+][package:]type/name | ?[package:]type/name ) setting outCreate to true if
     * the '+' was present in the string.
     */
    static std::unique_ptr<Reference> tryParseReference(const StringPiece16& str,
                                                        bool* outCreate);

    /*
     * Returns a BinaryPrimitve object representing @null or @empty if the string was parsed
     * as one.
     */
    static std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece16& str);

    /*
     * Returns a BinaryPrimitve object representing a color if the string was parsed
     * as one.
     */
    static std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece16& str);

    /*
     * Returns a BinaryPrimitve object representing a boolean if the string was parsed
     * as one.
     */
    static std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece16& str);

    /*
     * Returns a BinaryPrimitve object representing an integer if the string was parsed
     * as one.
     */
    static std::unique_ptr<BinaryPrimitive> tryParseInt(const StringPiece16& str);

    /*
     * Returns a BinaryPrimitve object representing a floating point number
     * (float, dimension, etc) if the string was parsed as one.
     */
    static std::unique_ptr<BinaryPrimitive> tryParseFloat(const StringPiece16& str);

    /*
     * Returns a BinaryPrimitve object representing an enum symbol if the string was parsed
     * as one.
     */
    static std::unique_ptr<BinaryPrimitive> tryParseEnumSymbol(const Attribute& enumAttr,
                                                               const StringPiece16& str);

    /*
     * Returns a BinaryPrimitve object representing a flag symbol if the string was parsed
     * as one.
     */
    static std::unique_ptr<BinaryPrimitive> tryParseFlagSymbol(const Attribute& enumAttr,
                                                               const StringPiece16& str);
    /*
     * Try to convert a string to an Item for the given attribute. The attribute will
     * restrict what values the string can be converted to.
     * The callback function onCreateReference is called when the parsed item is a
     * reference to an ID that must be created (@+id/foo).
     */
    static std::unique_ptr<Item> parseItemForAttribute(
            const StringPiece16& value, const Attribute& attr,
            std::function<void(const ResourceName&)> onCreateReference = {});

    static std::unique_ptr<Item> parseItemForAttribute(
            const StringPiece16& value, uint32_t typeMask,
            std::function<void(const ResourceName&)> onCreateReference = {});

    static uint32_t androidTypeToAttributeTypeMask(uint16_t type);

    ResourceParser(const std::shared_ptr<ResourceTable>& table, const Source& source,
                   const ConfigDescription& config, const std::shared_ptr<XmlPullParser>& parser);

    ResourceParser(const ResourceParser&) = delete; // No copy.

    bool parse();

private:
    /*
     * Parses the XML subtree as a StyleString (flattened XML representation for strings
     * with formatting). If successful, `outStyleString`
     * contains the escaped and whitespace trimmed text, while `outRawString`
     * contains the unescaped text. Returns true on success.
     */
    bool flattenXmlSubtree(XmlPullParser* parser, std::u16string* outRawString,\
                           StyleString* outStyleString);

    /*
     * Parses the XML subtree and converts it to an Item. The type of Item that can be
     * parsed is denoted by the `typeMask`. If `allowRawValue` is true and the subtree
     * can not be parsed as a regular Item, then a RawString is returned. Otherwise
     * this returns nullptr.
     */
    std::unique_ptr<Item> parseXml(XmlPullParser* parser, uint32_t typeMask, bool allowRawValue);

    bool parseResources(XmlPullParser* parser);
    bool parseString(XmlPullParser* parser, const ResourceNameRef& resourceName);
    bool parseColor(XmlPullParser* parser, const ResourceNameRef& resourceName);
    bool parsePrimitive(XmlPullParser* parser, const ResourceNameRef& resourceName);
    bool parsePublic(XmlPullParser* parser, const StringPiece16& name);
    bool parseAttr(XmlPullParser* parser, const ResourceNameRef& resourceName);
    std::unique_ptr<Attribute> parseAttrImpl(XmlPullParser* parser,
                                             ResourceName* resourceName,
                                             bool weak);
    bool parseEnumOrFlagItem(XmlPullParser* parser, const StringPiece16& tag,
                             Attribute::Symbol* outSymbol);
    bool parseStyle(XmlPullParser* parser, const ResourceNameRef& resourceName);
    bool parseUntypedItem(XmlPullParser* parser, Style& style);
    bool parseDeclareStyleable(XmlPullParser* parser, const ResourceNameRef& resourceName);
    bool parseArray(XmlPullParser* parser, const ResourceNameRef& resourceName, uint32_t typeMask);
    bool parsePlural(XmlPullParser* parser, const ResourceNameRef& resourceName);

    std::shared_ptr<ResourceTable> mTable;
    Source mSource;
    ConfigDescription mConfig;
    SourceLogger mLogger;
    std::shared_ptr<XmlPullParser> mParser;
};

} // namespace aapt

#endif // AAPT_RESOURCE_PARSER_H