Introduce ResourceNamedType that represents pair of name + ResourceType.
This type will be used as part of ResourceName to support types with
custom names inside aapt2.
DD: go/custom-resource-types-in-aapt2
Bug: b/215108200
Test: Resource_test.cpp
Change-Id: Ib09776e6b2f69fefb9724136a345dc25bea42573
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
index 307c21d..d394b24 100644
--- a/tools/aapt2/Resource.h
+++ b/tools/aapt2/Resource.h
@@ -19,22 +19,21 @@
#include <iomanip>
#include <limits>
+#include <optional>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>
+#include "Source.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/StringPiece.h"
#include "utils/JenkinsHash.h"
-#include "Source.h"
-
namespace aapt {
/**
- * The various types of resource types available. Corresponds
- * to the 'type' in package:type/entry.
+ * The various types of resource types available.
*/
enum class ResourceType {
kAnim,
@@ -78,6 +77,52 @@
const ResourceType* ParseResourceType(const android::StringPiece& str);
/**
+ * Pair of type name as in ResourceTable and actual resource type.
+ * Corresponds to the 'type' in package:type/entry.
+ *
+ * This is to support resource types with custom names inside resource tables.
+ */
+struct ResourceNamedType {
+ std::string name;
+ ResourceType type = ResourceType::kRaw;
+
+ ResourceNamedType() = default;
+ ResourceNamedType(const android::StringPiece& n, ResourceType t);
+
+ int compare(const ResourceNamedType& other) const;
+
+ const std::string& to_string() const;
+};
+
+/**
+ * Same as ResourceNamedType, but uses StringPieces instead.
+ * Use this if you need to avoid copying and know that
+ * the lifetime of this object is shorter than that
+ * of the original string.
+ */
+struct ResourceNamedTypeRef {
+ android::StringPiece name;
+ ResourceType type = ResourceType::kRaw;
+
+ ResourceNamedTypeRef() = default;
+ ResourceNamedTypeRef(const ResourceNamedTypeRef&) = default;
+ ResourceNamedTypeRef(ResourceNamedTypeRef&&) = default;
+ ResourceNamedTypeRef(const ResourceNamedType& rhs); // NOLINT(google-explicit-constructor)
+ ResourceNamedTypeRef(const android::StringPiece& n, ResourceType t);
+ ResourceNamedTypeRef& operator=(const ResourceNamedTypeRef& rhs) = default;
+ ResourceNamedTypeRef& operator=(ResourceNamedTypeRef&& rhs) = default;
+ ResourceNamedTypeRef& operator=(const ResourceNamedType& rhs);
+
+ ResourceNamedType ToResourceNamedType() const;
+
+ std::string to_string() const;
+};
+
+ResourceNamedTypeRef ResourceNamedTypeWithDefaultName(ResourceType t);
+
+std::optional<ResourceNamedTypeRef> ParseResourceNamedType(const android::StringPiece& s);
+
+/**
* A resource's name. This can uniquely identify
* a resource in the ResourceTable.
*/
@@ -295,6 +340,81 @@
}
//
+// ResourceNamedType implementation.
+//
+inline ResourceNamedType::ResourceNamedType(const android::StringPiece& n, ResourceType t)
+ : name(n.to_string()), type(t) {
+}
+
+inline int ResourceNamedType::compare(const ResourceNamedType& other) const {
+ int cmp = static_cast<int>(type) - static_cast<int>(other.type);
+ if (cmp != 0) return cmp;
+ cmp = name.compare(other.name);
+ return cmp;
+}
+
+inline const std::string& ResourceNamedType::to_string() const {
+ return name;
+}
+
+inline bool operator<(const ResourceNamedType& lhs, const ResourceNamedType& rhs) {
+ return lhs.compare(rhs) < 0;
+}
+
+inline bool operator==(const ResourceNamedType& lhs, const ResourceNamedType& rhs) {
+ return lhs.compare(rhs) == 0;
+}
+
+inline bool operator!=(const ResourceNamedType& lhs, const ResourceNamedType& rhs) {
+ return lhs.compare(rhs) != 0;
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNamedType& val) {
+ return out << val.to_string();
+}
+
+//
+// ResourceNamedTypeRef implementation.
+//
+inline ResourceNamedTypeRef::ResourceNamedTypeRef(const android::StringPiece& n, ResourceType t)
+ : name(n), type(t) {
+}
+
+inline ResourceNamedTypeRef::ResourceNamedTypeRef(const ResourceNamedType& rhs)
+ : name(rhs.name), type(rhs.type) {
+}
+
+inline ResourceNamedTypeRef& ResourceNamedTypeRef::operator=(const ResourceNamedType& rhs) {
+ name = rhs.name;
+ type = rhs.type;
+ return *this;
+}
+
+inline ResourceNamedType ResourceNamedTypeRef::ToResourceNamedType() const {
+ return ResourceNamedType(name, type);
+}
+
+inline std::string ResourceNamedTypeRef::to_string() const {
+ return name.to_string();
+}
+
+inline bool operator<(const ResourceNamedTypeRef& lhs, const ResourceNamedTypeRef& rhs) {
+ return std::tie(lhs.type, lhs.name) < std::tie(rhs.type, rhs.name);
+}
+
+inline bool operator==(const ResourceNamedTypeRef& lhs, const ResourceNamedTypeRef& rhs) {
+ return std::tie(lhs.type, lhs.name) == std::tie(rhs.type, rhs.name);
+}
+
+inline bool operator!=(const ResourceNamedTypeRef& lhs, const ResourceNamedTypeRef& rhs) {
+ return std::tie(lhs.type, lhs.name) != std::tie(rhs.type, rhs.name);
+}
+
+inline ::std::ostream& operator<<(::std::ostream& out, const ResourceNamedTypeRef& val) {
+ return out << val.name;
+}
+
+//
// ResourceName implementation.
//