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_RESOURCE_PARSER_H 18 #define AAPT_RESOURCE_PARSER_H 19 20 #include <memory> 21 #include <optional> 22 23 #include "ResourceTable.h" 24 #include "ResourceValues.h" 25 #include "android-base/macros.h" 26 #include "androidfw/ConfigDescription.h" 27 #include "androidfw/IDiagnostics.h" 28 #include "androidfw/StringPiece.h" 29 #include "androidfw/StringPool.h" 30 #include "cmd/Util.h" 31 #include "xml/XmlPullParser.h" 32 33 namespace aapt { 34 35 struct ParsedResource; 36 37 struct ResourceParserOptions { 38 /** 39 * Whether the default setting for this parser is to allow translation. 40 */ 41 bool translatable = true; 42 43 /** 44 * Whether positional arguments in formatted strings are treated as errors or 45 * warnings. 46 */ 47 bool error_on_positional_arguments = true; 48 49 /** 50 * If true, apply the same visibility rules for styleables as are used for 51 * all other resources. Otherwise, all styleables will be made public. 52 */ 53 bool preserve_visibility_of_styleables = false; 54 55 // If visibility was forced, we need to use it when creating a new resource and also error if we 56 // try to parse the <public>, <public-group>, <java-symbol> or <symbol> tags. 57 std::optional<Visibility::Level> visibility; 58 59 FeatureFlagValues feature_flag_values; 60 61 // The flag that should be applied to all resources parsed 62 std::optional<FeatureFlagAttribute> flag; 63 64 FlagStatus flag_status = FlagStatus::NoFlag; 65 }; 66 67 struct FlattenedXmlSubTree { 68 std::string raw_value; 69 android::StyleString style_string; 70 std::vector<UntranslatableSection> untranslatable_sections; 71 xml::IPackageDeclStack* namespace_resolver; 72 android::Source source; 73 }; 74 75 /* 76 * Parses an XML file for resources and adds them to a ResourceTable. 77 */ 78 class ResourceParser { 79 public: 80 ResourceParser(android::IDiagnostics* diag, ResourceTable* table, const android::Source& source, 81 const android::ConfigDescription& config, 82 const ResourceParserOptions& options = {}); 83 bool Parse(xml::XmlPullParser* parser); 84 85 static std::unique_ptr<Item> ParseXml(const FlattenedXmlSubTree& xmlsub_tree, uint32_t type_mask, 86 bool allow_raw_value, ResourceTable& table, 87 const android::ConfigDescription& config, 88 android::IDiagnostics& diag); 89 90 private: 91 DISALLOW_COPY_AND_ASSIGN(ResourceParser); 92 93 std::optional<FlattenedXmlSubTree> CreateFlattenSubTree(xml::XmlPullParser* parser); 94 95 // Parses the XML subtree as a StyleString (flattened XML representation for strings with 96 // formatting). If parsing fails, false is returned and the out parameters are left in an 97 // unspecified state. Otherwise, 98 // `out_style_string` contains the escaped and whitespace trimmed text. 99 // `out_raw_string` contains the un-escaped text. 100 // `out_untranslatable_sections` contains the sections of the string that should not be 101 // translated. 102 bool FlattenXmlSubtree(xml::XmlPullParser* parser, std::string* out_raw_string, 103 android::StyleString* out_style_string, 104 std::vector<UntranslatableSection>* out_untranslatable_sections); 105 106 /* 107 * Parses the XML subtree and returns an Item. 108 * The type of Item that can be parsed is denoted by the `type_mask`. 109 * If `allow_raw_value` is true and the subtree can not be parsed as a regular 110 * Item, then a 111 * RawString is returned. Otherwise this returns false; 112 */ 113 std::unique_ptr<Item> ParseXml(xml::XmlPullParser* parser, const uint32_t type_mask, 114 const bool allow_raw_value); 115 116 bool ParseResources(xml::XmlPullParser* parser); 117 bool ParseResource(xml::XmlPullParser* parser, ParsedResource* out_resource); 118 119 bool ParseItem(xml::XmlPullParser* parser, ParsedResource* out_resource, uint32_t format); 120 bool ParseString(xml::XmlPullParser* parser, ParsedResource* out_resource); 121 bool ParseMacro(xml::XmlPullParser* parser, ParsedResource* out_resource); 122 bool ParsePublic(xml::XmlPullParser* parser, ParsedResource* out_resource); 123 bool ParsePublicGroup(xml::XmlPullParser* parser, ParsedResource* out_resource); 124 bool ParseStagingPublicGroup(xml::XmlPullParser* parser, ParsedResource* out_resource); 125 bool ParseStagingPublicGroupFinal(xml::XmlPullParser* parser, ParsedResource* out_resource); 126 bool ParseSymbolImpl(xml::XmlPullParser* parser, ParsedResource* out_resource); 127 bool ParseSymbol(xml::XmlPullParser* parser, ParsedResource* out_resource); 128 bool ParseOverlayable(xml::XmlPullParser* parser, ParsedResource* out_resource); 129 bool ParseAddResource(xml::XmlPullParser* parser, ParsedResource* out_resource); 130 bool ParseAttr(xml::XmlPullParser* parser, ParsedResource* out_resource); 131 bool ParseAttrImpl(xml::XmlPullParser* parser, ParsedResource* out_resource, bool weak); 132 std::optional<Attribute::Symbol> ParseEnumOrFlagItem(xml::XmlPullParser* parser, 133 android::StringPiece tag); 134 bool ParseStyle(ResourceType type, xml::XmlPullParser* parser, ParsedResource* out_resource); 135 bool ParseStyleItem(xml::XmlPullParser* parser, Style* style); 136 bool ParseDeclareStyleable(xml::XmlPullParser* parser, ParsedResource* out_resource); 137 bool ParseArray(xml::XmlPullParser* parser, ParsedResource* out_resource); 138 bool ParseIntegerArray(xml::XmlPullParser* parser, ParsedResource* out_resource); 139 bool ParseStringArray(xml::XmlPullParser* parser, ParsedResource* out_resource); 140 bool ParseArrayImpl(xml::XmlPullParser* parser, ParsedResource* out_resource, uint32_t typeMask); 141 bool ParsePlural(xml::XmlPullParser* parser, ParsedResource* out_resource); 142 143 android::IDiagnostics* diag_; 144 ResourceTable* table_; 145 android::Source source_; 146 android::ConfigDescription config_; 147 ResourceParserOptions options_; 148 }; 149 150 } // namespace aapt 151 152 #endif // AAPT_RESOURCE_PARSER_H 153