175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/* 275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Copyright (C) 2015 The Android Open Source Project 375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * 475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * you may not use this file except in compliance with the License. 675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * You may obtain a copy of the License at 775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * 875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * 1075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Unless required by applicable law or agreed to in writing, software 1175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 1275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * See the License for the specific language governing permissions and 1475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * limitations under the License. 1575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 1675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 1775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#ifndef AAPT_XML_DOM_H 1875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#define AAPT_XML_DOM_H 1975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "Diagnostics.h" 211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "Resource.h" 221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "ResourceValues.h" 231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/StringPiece.h" 241ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h" 25467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski#include "xml/XmlUtil.h" 2675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 2775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <istream> 2875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <memory> 2975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <string> 3075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <vector> 3175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 3275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskinamespace aapt { 3375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskinamespace xml { 3475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct RawVisitor; 3675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 3775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 3875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Base class for all XML nodes. 3975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 4075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Node { 411ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski Node* parent = nullptr; 421ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski size_t lineNumber = 0; 431ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski size_t columnNumber = 0; 4475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::u16string comment; 4575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::vector<std::unique_ptr<Node>> children; 4675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 47467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski virtual ~Node() = default; 48467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski 4975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski void addChild(std::unique_ptr<Node> child); 501ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual void accept(RawVisitor* visitor) = 0; 5175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 5275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 5375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 5475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Base class that implements the visitor methods for a 5575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * subclass of Node. 5675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 5775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskitemplate <typename Derived> 5875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct BaseNode : public Node { 591ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual void accept(RawVisitor* visitor) override; 6075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 6175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 6275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 6375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * A Namespace XML node. Can only have one child. 6475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 6575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Namespace : public BaseNode<Namespace> { 6675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::u16string namespacePrefix; 6775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::u16string namespaceUri; 681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 6975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 701ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct AaptAttribute { 7164587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski Maybe<ResourceId> id; 721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski aapt::Attribute attribute; 7375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 7475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 7575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 7675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * An XML attribute. 7775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 7875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Attribute { 7975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::u16string namespaceUri; 8075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::u16string name; 8175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::u16string value; 821ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 831ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski Maybe<AaptAttribute> compiledAttribute; 841ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski std::unique_ptr<Item> compiledValue; 8575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 8675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 8775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 8875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * An Element XML node. 8975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 9075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Element : public BaseNode<Element> { 9175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::u16string namespaceUri; 9275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::u16string name; 9375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::vector<Attribute> attributes; 9475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 9575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski Attribute* findAttribute(const StringPiece16& ns, const StringPiece16& name); 9675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski xml::Element* findChild(const StringPiece16& ns, const StringPiece16& name); 9775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski xml::Element* findChildWithAttribute(const StringPiece16& ns, const StringPiece16& name, 981ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski const StringPiece16& attrNs, 991ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski const StringPiece16& attrName, 1001ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski const StringPiece16& attrValue); 10175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::vector<xml::Element*> getChildElements(); 10275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 10375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 10475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 10575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * A Text (CDATA) XML node. Can not have any children. 10675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 10775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Text : public BaseNode<Text> { 10875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::u16string text; 10975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 11075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 11175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 112467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski * An XML resource with a source, name, and XML tree. 113467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski */ 114467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinskistruct XmlResource { 115467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski ResourceFile file; 116467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski std::unique_ptr<xml::Node> root; 117467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski}; 118467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski 119467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski/** 12075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Inflates an XML DOM from a text stream, logging errors to the logger. 12175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Returns the root node on success, or nullptr on failure. 12275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 1231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistd::unique_ptr<XmlResource> inflate(std::istream* in, IDiagnostics* diag, const Source& source); 12475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 12575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 12675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger. 12775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Returns the root node on success, or nullptr on failure. 12875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 1291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistd::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnostics* diag, 1301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski const Source& source); 1311ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 132467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam LesinskiElement* findRootElement(XmlResource* doc); 133ca5638fd85098c3d0a699492751043545f75553aAdam LesinskiElement* findRootElement(Node* node); 134ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski 1351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/** 1361ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * A visitor interface for the different XML Node subtypes. This will not traverse into 1371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * children. Use Visitor for that. 1381ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 1391ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct RawVisitor { 1401ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual ~RawVisitor() = default; 1411ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1421ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual void visit(Namespace* node) {} 1431ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual void visit(Element* node) {} 1441ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual void visit(Text* text) {} 1451ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 1461ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1471ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/** 1481ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Visitor whose default implementation visits the children nodes of any node. 1491ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 1501ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct Visitor : public RawVisitor { 1511ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski using RawVisitor::visit; 1521ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1531ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski void visit(Namespace* node) override { 1541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski visitChildren(node); 1551ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 1561ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1571ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski void visit(Element* node) override { 1581ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski visitChildren(node); 1591ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 1601ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1611ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski void visit(Text* text) override { 1621ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski visitChildren(text); 1631ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 1641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski void visitChildren(Node* node) { 1661ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski for (auto& child : node->children) { 1671ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski child->accept(this); 1681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 1691ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 1701ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 17175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 17275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 1731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * An XML DOM visitor that will record the package name for a namespace prefix. 17475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 1751ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass PackageAwareVisitor : public Visitor, public IPackageDeclStack { 1761ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiprivate: 1771ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski struct PackageDecl { 1781ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski std::u16string prefix; 179467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski ExtractedPackage package; 1801ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski }; 1811ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1821ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski std::vector<PackageDecl> mPackageDecls; 1831ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1841ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskipublic: 1851ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski using Visitor::visit; 1861ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 187467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski void visit(Namespace* ns) override; 188467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski Maybe<ExtractedPackage> transformPackageAlias( 189467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski const StringPiece16& alias, const StringPiece16& localPackage) const override; 19075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 19175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 19275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski// Implementations 19375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 19475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskitemplate <typename Derived> 1951ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid BaseNode<Derived>::accept(RawVisitor* visitor) { 1961ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski visitor->visit(static_cast<Derived*>(this)); 19775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} 19875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 1991ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T> 2001ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct NodeCastImpl : public RawVisitor { 2011ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski using RawVisitor::visit; 2021ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 2031ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski T* value = nullptr; 2041ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 2051ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski void visit(T* v) override { 2061ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski value = v; 2071ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 2081ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 2091ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 2101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T> 2111ab598f46c3ff520a67f9d80194847741f3467abAdam LesinskiT* nodeCast(Node* node) { 2121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski NodeCastImpl<T> visitor; 2131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski node->accept(&visitor); 2141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski return visitor.value; 21575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} 21675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 21775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} // namespace xml 21875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} // namespace aapt 21975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 22075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#endif // AAPT_XML_DOM_H 221