blob: 96bba4febf99d3ac13303ce35720618cf833314f [file] [log] [blame]
Adam Lesinski6f6ceb72014-11-14 14:48:12 -08001/*
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_RESOURCE_PARSER_H
18#define AAPT_RESOURCE_PARSER_H
19
20#include "ConfigDescription.h"
21#include "Logger.h"
22#include "ResourceTable.h"
23#include "ResourceValues.h"
24#include "StringPiece.h"
25#include "StringPool.h"
26#include "XmlPullParser.h"
27
28#include <istream>
29#include <memory>
30
31namespace aapt {
32
33/*
34 * Parses an XML file for resources and adds them to a ResourceTable.
35 */
36class ResourceParser {
37public:
38 /*
39 * Extracts the package, type, and name from a string of the format:
40 *
41 * [package:]type/name
42 *
43 * where the package can be empty. Validation must be performed on each
44 * individual extracted piece to verify that the pieces are valid.
45 */
46 static void extractResourceName(const StringPiece16& str, StringPiece16* outPackage,
47 StringPiece16* outType, StringPiece16* outEntry);
48
49 /*
50 * Returns true if the string was parsed as a reference (@[+][package:]type/name), with
51 * `outReference` set to the parsed reference.
52 *
53 * If '+' was present in the reference, `outCreate` is set to true.
54 * If '*' was present in the reference, `outPrivate` is set to true.
55 */
56 static bool tryParseReference(const StringPiece16& str, ResourceNameRef* outReference,
57 bool* outCreate, bool* outPrivate);
58
59 /*
60 * Returns true if the string was parsed as an attribute reference (?[package:]type/name),
61 * with `outReference` set to the parsed reference.
62 */
63 static bool tryParseAttributeReference(const StringPiece16& str,
64 ResourceNameRef* outReference);
65
66 /*
67 * Returns a Reference object if the string was parsed as a resource or attribute reference,
68 * ( @[+][package:]type/name | ?[package:]type/name )
69 * assigning defaultPackage if the package was not present in the string, and setting
70 * outCreate to true if the '+' was present in the string.
71 */
72 static std::unique_ptr<Reference> tryParseReference(const StringPiece16& str,
73 const StringPiece16& defaultPackage,
74 bool* outCreate);
75
76 /*
77 * Returns a BinaryPrimitve object representing @null or @empty if the string was parsed
78 * as one.
79 */
80 static std::unique_ptr<BinaryPrimitive> tryParseNullOrEmpty(const StringPiece16& str);
81
82 /*
83 * Returns a BinaryPrimitve object representing a color if the string was parsed
84 * as one.
85 */
86 static std::unique_ptr<BinaryPrimitive> tryParseColor(const StringPiece16& str);
87
88 /*
89 * Returns a BinaryPrimitve object representing a boolean if the string was parsed
90 * as one.
91 */
92 static std::unique_ptr<BinaryPrimitive> tryParseBool(const StringPiece16& str);
93
94 /*
95 * Returns a BinaryPrimitve object representing an integer if the string was parsed
96 * as one.
97 */
98 static std::unique_ptr<BinaryPrimitive> tryParseInt(const StringPiece16& str);
99
100 /*
101 * Returns a BinaryPrimitve object representing a floating point number
102 * (float, dimension, etc) if the string was parsed as one.
103 */
104 static std::unique_ptr<BinaryPrimitive> tryParseFloat(const StringPiece16& str);
105
106 /*
107 * Returns a BinaryPrimitve object representing an enum symbol if the string was parsed
108 * as one.
109 */
110 static std::unique_ptr<BinaryPrimitive> tryParseEnumSymbol(const Attribute& enumAttr,
111 const StringPiece16& str);
112
113 /*
114 * Returns a BinaryPrimitve object representing a flag symbol if the string was parsed
115 * as one.
116 */
117 static std::unique_ptr<BinaryPrimitive> tryParseFlagSymbol(const Attribute& enumAttr,
118 const StringPiece16& str);
119
120 /*
121 * Try to convert a string to an Item for the given attribute. The attribute will
122 * restrict what values the string can be converted to.
123 * The defaultPackage is used when the string is a reference with no defined package.
124 * The callback function onCreateReference is called when the parsed item is a
125 * reference to an ID that must be created (@+id/foo).
126 */
127 static std::unique_ptr<Item> parseItemForAttribute(
128 const StringPiece16& value, const Attribute& attr, const StringPiece16& defaultPackage,
129 std::function<void(const ResourceName&)> onCreateReference = {});
130
131 static std::unique_ptr<Item> parseItemForAttribute(
132 const StringPiece16& value, uint32_t typeMask, const StringPiece16& defaultPackage,
133 std::function<void(const ResourceName&)> onCreateReference = {});
134
135 static uint32_t androidTypeToAttributeTypeMask(uint16_t type);
136
137 ResourceParser(const std::shared_ptr<ResourceTable>& table, const Source& source,
138 const ConfigDescription& config, const std::shared_ptr<XmlPullParser>& parser);
139
140 ResourceParser(const ResourceParser&) = delete; // No copy.
141
142 bool parse();
143
144private:
145 /*
146 * Parses the XML subtree as a StyleString (flattened XML representation for strings
147 * with formatting). If successful, `outStyleString`
148 * contains the escaped and whitespace trimmed text, while `outRawString`
149 * contains the unescaped text. Returns true on success.
150 */
151 bool flattenXmlSubtree(XmlPullParser* parser, std::u16string* outRawString,\
152 StyleString* outStyleString);
153
154 /*
155 * Parses the XML subtree and converts it to an Item. The type of Item that can be
156 * parsed is denoted by the `typeMask`. If `allowRawValue` is true and the subtree
157 * can not be parsed as a regular Item, then a RawString is returned. Otherwise
158 * this returns nullptr.
159 */
160 std::unique_ptr<Item> parseXml(XmlPullParser* parser, uint32_t typeMask, bool allowRawValue);
161
162 bool parseResources(XmlPullParser* parser);
163 bool parseString(XmlPullParser* parser, const ResourceNameRef& resourceName);
164 bool parseColor(XmlPullParser* parser, const ResourceNameRef& resourceName);
165 bool parsePrimitive(XmlPullParser* parser, const ResourceNameRef& resourceName);
166 bool parsePublic(XmlPullParser* parser, const StringPiece16& name);
167 bool parseAttr(XmlPullParser* parser, const ResourceNameRef& resourceName);
168 std::unique_ptr<Attribute> parseAttrImpl(XmlPullParser* parser,
169 const ResourceNameRef& resourceName,
170 bool weak);
171 bool parseEnumOrFlagItem(XmlPullParser* parser, const StringPiece16& tag,
172 Attribute::Symbol* outSymbol);
173 bool parseStyle(XmlPullParser* parser, const ResourceNameRef& resourceName);
174 bool parseUntypedItem(XmlPullParser* parser, Style& style);
175 bool parseDeclareStyleable(XmlPullParser* parser, const ResourceNameRef& resourceName);
176 bool parseArray(XmlPullParser* parser, const ResourceNameRef& resourceName, uint32_t typeMask);
177 bool parsePlural(XmlPullParser* parser, const ResourceNameRef& resourceName);
178
179 std::shared_ptr<ResourceTable> mTable;
180 Source mSource;
181 ConfigDescription mConfig;
182 SourceLogger mLogger;
183 std::shared_ptr<XmlPullParser> mParser;
184};
185
186} // namespace aapt
187
188#endif // AAPT_RESOURCE_PARSER_H