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_VALUES_H 18 #define AAPT_RESOURCE_VALUES_H 19 20 #include <array> 21 #include <limits> 22 #include <ostream> 23 #include <vector> 24 25 #include "androidfw/ResourceTypes.h" 26 #include "androidfw/StringPiece.h" 27 28 #include "Diagnostics.h" 29 #include "Resource.h" 30 #include "StringPool.h" 31 #include "ValueTransformer.h" 32 #include "io/File.h" 33 #include "text/Printer.h" 34 35 namespace aapt { 36 37 class ValueVisitor; 38 class ConstValueVisitor; 39 40 // A resource value. This is an all-encompassing representation 41 // of Item and Map and their subclasses. The way to do 42 // type specific operations is to check the Value's type() and 43 // cast it to the appropriate subclass. This isn't super clean, 44 // but it is the simplest strategy. 45 class Value { 46 public: 47 virtual ~Value() = default; 48 49 // Whether this value is weak and can be overridden without warning or error. Default is false. IsWeak()50 bool IsWeak() const { 51 return weak_; 52 } 53 SetWeak(bool val)54 void SetWeak(bool val) { 55 weak_ = val; 56 } 57 58 // Whether the value is marked as translatable. This does not persist when flattened to binary. 59 // It is only used during compilation phase. SetTranslatable(bool val)60 void SetTranslatable(bool val) { 61 translatable_ = val; 62 } 63 64 // Default true. IsTranslatable()65 bool IsTranslatable() const { 66 return translatable_; 67 } 68 69 // Returns the source where this value was defined. GetSource()70 const Source& GetSource() const { 71 return source_; 72 } 73 SetSource(const Source & source)74 void SetSource(const Source& source) { 75 source_ = source; 76 } 77 SetSource(Source && source)78 void SetSource(Source&& source) { 79 source_ = std::move(source); 80 } 81 82 // Returns the comment that was associated with this resource. GetComment()83 const std::string& GetComment() const { 84 return comment_; 85 } 86 SetComment(const android::StringPiece & str)87 void SetComment(const android::StringPiece& str) { 88 comment_ = str.to_string(); 89 } 90 SetComment(std::string && str)91 void SetComment(std::string&& str) { 92 comment_ = std::move(str); 93 } 94 95 virtual bool Equals(const Value* value) const = 0; 96 97 // Calls the appropriate overload of ValueVisitor. 98 virtual void Accept(ValueVisitor* visitor) = 0; 99 100 // Calls the appropriate overload of ConstValueVisitor. 101 virtual void Accept(ConstValueVisitor* visitor) const = 0; 102 103 // Transform this Value into another Value using the transformer. 104 std::unique_ptr<Value> Transform(ValueTransformer& transformer) const; 105 106 // Human readable printout of this value. 107 virtual void Print(std::ostream* out) const = 0; 108 109 // Human readable printout of this value that may omit some information for the sake 110 // of brevity and readability. Default implementation just calls Print(). 111 virtual void PrettyPrint(text::Printer* printer) const; 112 113 friend std::ostream& operator<<(std::ostream& out, const Value& value); 114 115 protected: 116 Source source_; 117 std::string comment_; 118 bool weak_ = false; 119 bool translatable_ = true; 120 121 private: 122 virtual Value* TransformValueImpl(ValueTransformer& transformer) const = 0; 123 }; 124 125 // Inherit from this to get visitor accepting implementations for free. 126 template <typename Derived> 127 struct BaseValue : public Value { 128 void Accept(ValueVisitor* visitor) override; 129 void Accept(ConstValueVisitor* visitor) const override; 130 }; 131 132 // A resource item with a single value. This maps to android::ResTable_entry. 133 struct Item : public Value { 134 // Fills in an android::Res_value structure with this Item's binary representation. 135 // Returns false if an error occurred. 136 virtual bool Flatten(android::Res_value* out_value) const = 0; 137 138 // Transform this Item into another Item using the transformer. 139 std::unique_ptr<Item> Transform(ValueTransformer& transformer) const; 140 141 private: 142 virtual Item* TransformItemImpl(ValueTransformer& transformer) const = 0; 143 }; 144 145 // Inherit from this to get visitor accepting implementations for free. 146 template <typename Derived> 147 struct BaseItem : public Item { 148 void Accept(ValueVisitor* visitor) override; 149 void Accept(ConstValueVisitor* visitor) const override; 150 }; 151 152 // A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE. 153 // A reference can be symbolic (with the name set to a valid resource name) or be 154 // numeric (the id is set to a valid resource ID). 155 struct Reference : public TransformableItem<Reference, BaseItem<Reference>> { 156 enum class Type : uint8_t { 157 kResource, 158 kAttribute, 159 }; 160 161 std::optional<ResourceName> name; 162 std::optional<ResourceId> id; 163 std::optional<uint32_t> type_flags; 164 Reference::Type reference_type; 165 bool private_reference = false; 166 bool is_dynamic = false; 167 bool allow_raw = false; 168 169 Reference(); 170 explicit Reference(const ResourceNameRef& n, Type type = Type::kResource); 171 explicit Reference(const ResourceId& i, Type type = Type::kResource); 172 Reference(const ResourceNameRef& n, const ResourceId& i); 173 174 bool Equals(const Value* value) const override; 175 bool Flatten(android::Res_value* out_value) const override; 176 void Print(std::ostream* out) const override; 177 void PrettyPrint(text::Printer* printer) const override; 178 179 // Prints the reference without a package name if the package name matches the one given. 180 void PrettyPrint(const android::StringPiece& package, text::Printer* printer) const; 181 }; 182 183 bool operator<(const Reference&, const Reference&); 184 bool operator==(const Reference&, const Reference&); 185 186 // An ID resource. Has no real value, just a place holder. 187 struct Id : public TransformableItem<Id, BaseItem<Id>> { IdId188 Id() { 189 weak_ = true; 190 } 191 192 bool Equals(const Value* value) const override; 193 bool Flatten(android::Res_value* out) const override; 194 void Print(std::ostream* out) const override; 195 }; 196 197 // A raw, unprocessed string. This may contain quotations, escape sequences, and whitespace. 198 // This shall *NOT* end up in the final resource table. 199 struct RawString : public TransformableItem<RawString, BaseItem<RawString>> { 200 StringPool::Ref value; 201 202 explicit RawString(const StringPool::Ref& ref); 203 204 bool Equals(const Value* value) const override; 205 bool Flatten(android::Res_value* out_value) const override; 206 void Print(std::ostream* out) const override; 207 }; 208 209 // Identifies a range of characters in a string that are untranslatable. 210 // These should not be pseudolocalized. The start and end indices are measured in bytes. 211 struct UntranslatableSection { 212 // Start offset inclusive. 213 size_t start; 214 215 // End offset exclusive. 216 size_t end; 217 }; 218 219 inline bool operator==(const UntranslatableSection& a, const UntranslatableSection& b) { 220 return a.start == b.start && a.end == b.end; 221 } 222 223 inline bool operator!=(const UntranslatableSection& a, const UntranslatableSection& b) { 224 return a.start != b.start || a.end != b.end; 225 } 226 227 struct String : public TransformableItem<String, BaseItem<String>> { 228 StringPool::Ref value; 229 230 // Sections of the string to NOT translate. Mainly used 231 // for pseudolocalization. This data is NOT persisted 232 // in any format. 233 std::vector<UntranslatableSection> untranslatable_sections; 234 235 explicit String(const StringPool::Ref& ref); 236 237 bool Equals(const Value* value) const override; 238 bool Flatten(android::Res_value* out_value) const override; 239 void Print(std::ostream* out) const override; 240 void PrettyPrint(text::Printer* printer) const override; 241 }; 242 243 struct StyledString : public TransformableItem<StyledString, BaseItem<StyledString>> { 244 StringPool::StyleRef value; 245 246 // Sections of the string to NOT translate. Mainly used 247 // for pseudolocalization. This data is NOT persisted 248 // in any format. 249 std::vector<UntranslatableSection> untranslatable_sections; 250 251 explicit StyledString(const StringPool::StyleRef& ref); 252 253 bool Equals(const Value* value) const override; 254 bool Flatten(android::Res_value* out_value) const override; 255 void Print(std::ostream* out) const override; 256 }; 257 258 struct FileReference : public TransformableItem<FileReference, BaseItem<FileReference>> { 259 StringPool::Ref path; 260 261 // A handle to the file object from which this file can be read. 262 // This field is NOT persisted in any format. It is transient. 263 io::IFile* file = nullptr; 264 265 // FileType of the file pointed to by `file`. This is used to know how to inflate the file, 266 // or if to inflate at all (just copy). 267 ResourceFile::Type type = ResourceFile::Type::kUnknown; 268 269 FileReference() = default; 270 explicit FileReference(const StringPool::Ref& path); 271 272 bool Equals(const Value* value) const override; 273 bool Flatten(android::Res_value* out_value) const override; 274 void Print(std::ostream* out) const override; 275 }; 276 277 // Represents any other android::Res_value. 278 struct BinaryPrimitive : public TransformableItem<BinaryPrimitive, BaseItem<BinaryPrimitive>> { 279 android::Res_value value; 280 281 BinaryPrimitive() = default; 282 explicit BinaryPrimitive(const android::Res_value& val); 283 BinaryPrimitive(uint8_t dataType, uint32_t data); 284 285 bool Equals(const Value* value) const override; 286 bool Flatten(android::Res_value* out_value) const override; 287 void Print(std::ostream* out) const override; 288 void PrettyPrint(text::Printer* printer) const override; 289 }; 290 291 struct Attribute : public TransformableValue<Attribute, BaseValue<Attribute>> { 292 struct Symbol { 293 Reference symbol; 294 uint32_t value; 295 uint8_t type; 296 297 friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol); 298 }; 299 300 uint32_t type_mask; 301 int32_t min_int; 302 int32_t max_int; 303 std::vector<Symbol> symbols; 304 305 explicit Attribute(uint32_t t = 0u); 306 307 bool Equals(const Value* value) const override; 308 309 // Returns true if this Attribute's format is compatible with the given Attribute. The basic 310 // rule is that TYPE_REFERENCE can be ignored for both of the Attributes, and TYPE_FLAGS and 311 // TYPE_ENUMS are never compatible. 312 bool IsCompatibleWith(const Attribute& attr) const; 313 314 std::string MaskString() const; 315 static std::string MaskString(uint32_t type_mask); 316 317 void Print(std::ostream* out) const override; 318 bool Matches(const Item& item, DiagMessage* out_msg = nullptr) const; 319 }; 320 321 struct Style : public TransformableValue<Style, BaseValue<Style>> { 322 struct Entry { 323 Reference key; 324 std::unique_ptr<Item> value; 325 326 friend std::ostream& operator<<(std::ostream& out, const Entry& entry); 327 }; 328 329 std::optional<Reference> parent; 330 331 // If set to true, the parent was auto inferred from the style's name. 332 bool parent_inferred = false; 333 334 std::vector<Entry> entries; 335 336 bool Equals(const Value* value) const override; 337 void Print(std::ostream* out) const override; 338 339 // Merges `style` into this Style. All identical attributes of `style` take precedence, including 340 // the parent, if there is one. 341 void MergeWith(Style* style, StringPool* pool); 342 }; 343 344 struct Array : public TransformableValue<Array, BaseValue<Array>> { 345 std::vector<std::unique_ptr<Item>> elements; 346 347 bool Equals(const Value* value) const override; 348 void Print(std::ostream* out) const override; 349 }; 350 351 struct Plural : public TransformableValue<Plural, BaseValue<Plural>> { 352 enum { Zero = 0, One, Two, Few, Many, Other, Count }; 353 354 std::array<std::unique_ptr<Item>, Count> values; 355 356 bool Equals(const Value* value) const override; 357 void Print(std::ostream* out) const override; 358 }; 359 360 struct Styleable : public TransformableValue<Styleable, BaseValue<Styleable>> { 361 std::vector<Reference> entries; 362 363 bool Equals(const Value* value) const override; 364 void Print(std::ostream* out) const override; 365 void MergeWith(Styleable* styleable); 366 }; 367 368 struct Macro : public TransformableValue<Macro, BaseValue<Macro>> { 369 std::string raw_value; 370 StyleString style_string; 371 std::vector<UntranslatableSection> untranslatable_sections; 372 373 struct Namespace { 374 std::string alias; 375 std::string package_name; 376 bool is_private; 377 378 bool operator==(const Namespace& right) const { 379 return alias == right.alias && package_name == right.package_name && 380 is_private == right.is_private; 381 } 382 }; 383 384 std::vector<Namespace> alias_namespaces; 385 386 bool Equals(const Value* value) const override; 387 void Print(std::ostream* out) const override; 388 }; 389 390 template <typename T> 391 typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<( 392 std::ostream& out, const std::unique_ptr<T>& value) { 393 if (value == nullptr) { 394 out << "NULL"; 395 } else { 396 value->Print(&out); 397 } 398 return out; 399 } 400 401 struct CloningValueTransformer : public ValueTransformer { 402 explicit CloningValueTransformer(StringPool* new_pool); 403 404 std::unique_ptr<Reference> TransformDerived(const Reference* value) override; 405 std::unique_ptr<Id> TransformDerived(const Id* value) override; 406 std::unique_ptr<RawString> TransformDerived(const RawString* value) override; 407 std::unique_ptr<String> TransformDerived(const String* value) override; 408 std::unique_ptr<StyledString> TransformDerived(const StyledString* value) override; 409 std::unique_ptr<FileReference> TransformDerived(const FileReference* value) override; 410 std::unique_ptr<BinaryPrimitive> TransformDerived(const BinaryPrimitive* value) override; 411 std::unique_ptr<Attribute> TransformDerived(const Attribute* value) override; 412 std::unique_ptr<Style> TransformDerived(const Style* value) override; 413 std::unique_ptr<Array> TransformDerived(const Array* value) override; 414 std::unique_ptr<Plural> TransformDerived(const Plural* value) override; 415 std::unique_ptr<Styleable> TransformDerived(const Styleable* value) override; 416 std::unique_ptr<Macro> TransformDerived(const Macro* value) override; 417 }; 418 419 } // namespace aapt 420 421 #endif // AAPT_RESOURCE_VALUES_H 422