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