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 
68   // Returns the source where this value was defined.
GetSource()69   const android::Source& GetSource() const {
70     return source_;
71   }
72 
SetSource(const android::Source & source)73   void SetSource(const android::Source& source) {
74     source_ = source;
75   }
76 
SetSource(android::Source && source)77   void SetSource(android::Source&& source) {
78     source_ = std::move(source);
79   }
80 
81   // Returns the comment that was associated with this resource.
GetComment()82   const std::string& GetComment() const {
83     return comment_;
84   }
85 
SetComment(android::StringPiece str)86   void SetComment(android::StringPiece str) {
87     comment_.assign(str);
88   }
89 
SetComment(std::string && str)90   void SetComment(std::string&& str) {
91     comment_ = std::move(str);
92   }
93 
94   virtual bool Equals(const Value* value) const = 0;
95 
96   // Calls the appropriate overload of ValueVisitor.
97   virtual void Accept(ValueVisitor* visitor) = 0;
98 
99   // Calls the appropriate overload of ConstValueVisitor.
100   virtual void Accept(ConstValueVisitor* visitor) const = 0;
101 
102   // Transform this Value into another Value using the transformer.
103   std::unique_ptr<Value> Transform(ValueTransformer& transformer) const;
104 
105   // Human readable printout of this value.
106   virtual void Print(std::ostream* out) const = 0;
107 
108   // Human readable printout of this value that may omit some information for the sake
109   // of brevity and readability. Default implementation just calls Print().
110   virtual void PrettyPrint(text::Printer* printer) const;
111 
112   friend std::ostream& operator<<(std::ostream& out, const Value& value);
113 
114  protected:
115   android::Source source_;
116   std::string comment_;
117   bool weak_ = false;
118   bool translatable_ = true;
119 
120  private:
121   virtual Value* TransformValueImpl(ValueTransformer& transformer) const = 0;
122 };
123 
124 // Inherit from this to get visitor accepting implementations for free.
125 template <typename Derived>
126 struct BaseValue : public Value {
127   void Accept(ValueVisitor* visitor) override;
128   void Accept(ConstValueVisitor* visitor) const override;
129 };
130 
131 // A resource item with a single value. This maps to android::ResTable_entry.
132 struct Item : public Value {
133   // Fills in an android::Res_value structure with this Item's binary representation.
134   // Returns false if an error occurred.
135   virtual bool Flatten(android::Res_value* out_value) const = 0;
136 
137   // Transform this Item into another Item using the transformer.
138   std::unique_ptr<Item> Transform(ValueTransformer& transformer) const;
139 
140  private:
141   virtual Item* TransformItemImpl(ValueTransformer& transformer) const = 0;
142 };
143 
144 // Inherit from this to get visitor accepting implementations for free.
145 template <typename Derived>
146 struct BaseItem : public Item {
147   void Accept(ValueVisitor* visitor) override;
148   void Accept(ConstValueVisitor* visitor) const override;
149 };
150 
151 // A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
152 // A reference can be symbolic (with the name set to a valid resource name) or be
153 // numeric (the id is set to a valid resource ID).
154 struct Reference : public TransformableItem<Reference, BaseItem<Reference>> {
155   enum class Type : uint8_t {
156     kResource,
157     kAttribute,
158   };
159 
160   std::optional<ResourceName> name;
161   std::optional<ResourceId> id;
162   std::optional<uint32_t> type_flags;
163   Reference::Type reference_type;
164   bool private_reference = false;
165   bool is_dynamic = false;
166   bool allow_raw = false;
167 
168   Reference();
169   explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
170   explicit Reference(const ResourceId& i, Type type = Type::kResource);
171   Reference(const ResourceNameRef& n, const ResourceId& i);
172 
173   bool Equals(const Value* value) const override;
174   bool Flatten(android::Res_value* out_value) const override;
175   void Print(std::ostream* out) const override;
176   void PrettyPrint(text::Printer* printer) const override;
177 
178   // Prints the reference without a package name if the package name matches the one given.
179   void PrettyPrint(android::StringPiece package, text::Printer* printer) const;
180 };
181 
182 bool operator<(const Reference&, const Reference&);
183 bool operator==(const Reference&, const Reference&);
184 
185 // An ID resource. Has no real value, just a place holder.
186 struct Id : public TransformableItem<Id, BaseItem<Id>> {
IdId187   Id() {
188     weak_ = true;
189   }
190 
191   bool Equals(const Value* value) const override;
192   bool Flatten(android::Res_value* out) const override;
193   void Print(std::ostream* out) const override;
194 };
195 
196 // A raw, unprocessed string. This may contain quotations, escape sequences, and whitespace.
197 // This shall *NOT* end up in the final resource table.
198 struct RawString : public TransformableItem<RawString, BaseItem<RawString>> {
199   android::StringPool::Ref value;
200 
201   explicit RawString(const android::StringPool::Ref& ref);
202 
203   bool Equals(const Value* value) const override;
204   bool Flatten(android::Res_value* out_value) const override;
205   void Print(std::ostream* out) const override;
206 };
207 
208 // Identifies a range of characters in a string that are untranslatable.
209 // These should not be pseudolocalized. The start and end indices are measured in bytes.
210 struct UntranslatableSection {
211   // Start offset inclusive.
212   size_t start;
213 
214   // End offset exclusive.
215   size_t end;
216 };
217 
218 inline bool operator==(const UntranslatableSection& a, const UntranslatableSection& b) {
219   return a.start == b.start && a.end == b.end;
220 }
221 
222 inline bool operator!=(const UntranslatableSection& a, const UntranslatableSection& b) {
223   return a.start != b.start || a.end != b.end;
224 }
225 
226 struct String : public TransformableItem<String, BaseItem<String>> {
227   android::StringPool::Ref value;
228 
229   // Sections of the string to NOT translate. Mainly used
230   // for pseudolocalization. This data is NOT persisted
231   // in any format.
232   std::vector<UntranslatableSection> untranslatable_sections;
233 
234   explicit String(const android::StringPool::Ref& ref);
235 
236   bool Equals(const Value* value) const override;
237   bool Flatten(android::Res_value* out_value) const override;
238   void Print(std::ostream* out) const override;
239   void PrettyPrint(text::Printer* printer) const override;
240 };
241 
242 struct StyledString : public TransformableItem<StyledString, BaseItem<StyledString>> {
243   android::StringPool::StyleRef value;
244 
245   // Sections of the string to NOT translate. Mainly used
246   // for pseudolocalization. This data is NOT persisted
247   // in any format.
248   std::vector<UntranslatableSection> untranslatable_sections;
249 
250   explicit StyledString(const android::StringPool::StyleRef& ref);
251 
252   bool Equals(const Value* value) const override;
253   bool Flatten(android::Res_value* out_value) const override;
254   void Print(std::ostream* out) const override;
255 };
256 
257 struct FileReference : public TransformableItem<FileReference, BaseItem<FileReference>> {
258   android::StringPool::Ref path;
259 
260   // A handle to the file object from which this file can be read.
261   // This field is NOT persisted in any format. It is transient.
262   io::IFile* file = nullptr;
263 
264   // FileType of the file pointed to by `file`. This is used to know how to inflate the file,
265   // or if to inflate at all (just copy).
266   ResourceFile::Type type = ResourceFile::Type::kUnknown;
267 
268   FileReference() = default;
269   explicit FileReference(const android::StringPool::Ref& path);
270 
271   bool Equals(const Value* value) const override;
272   bool Flatten(android::Res_value* out_value) const override;
273   void Print(std::ostream* out) const override;
274 };
275 
276 // Represents any other android::Res_value.
277 struct BinaryPrimitive : public TransformableItem<BinaryPrimitive, BaseItem<BinaryPrimitive>> {
278   android::Res_value value;
279 
280   BinaryPrimitive() = default;
281   explicit BinaryPrimitive(const android::Res_value& val);
282   BinaryPrimitive(uint8_t dataType, uint32_t data);
283 
284   bool Equals(const Value* value) const override;
285   bool Flatten(android::Res_value* out_value) const override;
286   void Print(std::ostream* out) const override;
287   static const char* DecideFormat(float f);
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, android::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, android::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   android::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(android::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