// Copyright 2016 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/fxfa/parser/cxfa_simple_parser.h"

#include <utility>

#include "core/fxcrt/cfx_checksumcontext.h"
#include "core/fxcrt/fx_ext.h"
#include "third_party/base/ptr_util.h"
#include "xfa/fde/xml/cfde_xmlchardata.h"
#include "xfa/fde/xml/cfde_xmldoc.h"
#include "xfa/fde/xml/cfde_xmlelement.h"
#include "xfa/fde/xml/cfde_xmlinstruction.h"
#include "xfa/fde/xml/cfde_xmlnode.h"
#include "xfa/fde/xml/cfde_xmlparser.h"
#include "xfa/fde/xml/cfde_xmltext.h"
#include "xfa/fgas/crt/fgas_codepage.h"
#include "xfa/fxfa/fxfa.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_widetextread.h"
#include "xfa/fxfa/parser/xfa_basic_data.h"
#include "xfa/fxfa/parser/xfa_utils.h"

namespace {

CFDE_XMLNode* GetDocumentNode(CFDE_XMLDoc* pXMLDoc,
                              bool bVerifyWellFormness = false) {
  if (!pXMLDoc)
    return nullptr;

  for (CFDE_XMLNode* pXMLNode =
           pXMLDoc->GetRoot()->GetNodeItem(CFDE_XMLNode::FirstChild);
       pXMLNode; pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling)) {
    if (pXMLNode->GetType() != FDE_XMLNODE_Element)
      continue;

    if (!bVerifyWellFormness)
      return pXMLNode;

    for (CFDE_XMLNode* pNextNode =
             pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling);
         pNextNode;
         pNextNode = pNextNode->GetNodeItem(CFDE_XMLNode::NextSibling)) {
      if (pNextNode->GetType() == FDE_XMLNODE_Element)
        return nullptr;
    }
    return pXMLNode;
  }
  return nullptr;
}

void GetElementTagNamespaceURI(CFDE_XMLElement* pElement,
                               CFX_WideString& wsNamespaceURI) {
  CFX_WideString wsNodeStr;
  pElement->GetNamespacePrefix(wsNodeStr);
  if (!XFA_FDEExtension_ResolveNamespaceQualifier(
          pElement, wsNodeStr.AsStringC(), wsNamespaceURI)) {
    wsNamespaceURI.clear();
  }
}

bool MatchNodeName(CFDE_XMLNode* pNode,
                   const CFX_WideStringC& wsLocalTagName,
                   const CFX_WideStringC& wsNamespaceURIPrefix,
                   uint32_t eMatchFlags = XFA_XDPPACKET_FLAGS_NOMATCH) {
  if (!pNode || pNode->GetType() != FDE_XMLNODE_Element)
    return false;

  CFDE_XMLElement* pElement = reinterpret_cast<CFDE_XMLElement*>(pNode);
  CFX_WideString wsNodeStr;
  pElement->GetLocalTagName(wsNodeStr);
  if (wsNodeStr != wsLocalTagName)
    return false;

  GetElementTagNamespaceURI(pElement, wsNodeStr);
  if (eMatchFlags & XFA_XDPPACKET_FLAGS_NOMATCH)
    return true;
  if (eMatchFlags & XFA_XDPPACKET_FLAGS_PREFIXMATCH) {
    return wsNodeStr.Left(wsNamespaceURIPrefix.GetLength()) ==
           wsNamespaceURIPrefix;
  }
  return wsNodeStr == wsNamespaceURIPrefix;
}

bool GetAttributeLocalName(const CFX_WideStringC& wsAttributeName,
                           CFX_WideString& wsLocalAttrName) {
  CFX_WideString wsAttrName(wsAttributeName);
  FX_STRSIZE iFind = wsAttrName.Find(L':', 0);
  if (iFind < 0) {
    wsLocalAttrName = wsAttrName;
    return false;
  }
  wsLocalAttrName = wsAttrName.Right(wsAttrName.GetLength() - iFind - 1);
  return true;
}

bool ResolveAttribute(CFDE_XMLElement* pElement,
                      const CFX_WideStringC& wsAttributeName,
                      CFX_WideString& wsLocalAttrName,
                      CFX_WideString& wsNamespaceURI) {
  CFX_WideString wsAttrName(wsAttributeName);
  CFX_WideString wsNSPrefix;
  if (GetAttributeLocalName(wsAttributeName, wsLocalAttrName)) {
    wsNSPrefix = wsAttrName.Left(wsAttributeName.GetLength() -
                                 wsLocalAttrName.GetLength() - 1);
  }
  if (wsLocalAttrName == L"xmlns" || wsNSPrefix == L"xmlns" ||
      wsNSPrefix == L"xml") {
    return false;
  }
  if (!XFA_FDEExtension_ResolveNamespaceQualifier(
          pElement, wsNSPrefix.AsStringC(), wsNamespaceURI)) {
    wsNamespaceURI.clear();
    return false;
  }
  return true;
}

bool FindAttributeWithNS(CFDE_XMLElement* pElement,
                         const CFX_WideStringC& wsLocalAttributeName,
                         const CFX_WideStringC& wsNamespaceURIPrefix,
                         CFX_WideString& wsValue,
                         bool bMatchNSAsPrefix = false) {
  if (!pElement)
    return false;

  CFX_WideString wsAttrName;
  CFX_WideString wsAttrValue;
  CFX_WideString wsAttrNS;
  for (int32_t iAttrCount = pElement->CountAttributes(), i = 0; i < iAttrCount;
       i++) {
    pElement->GetAttribute(i, wsAttrName, wsAttrValue);
    FX_STRSIZE iFind = wsAttrName.Find(L':', 0);
    CFX_WideString wsNSPrefix;
    if (iFind < 0) {
      if (wsLocalAttributeName != wsAttrName)
        continue;
    } else {
      if (wsLocalAttributeName !=
          wsAttrName.Right(wsAttrName.GetLength() - iFind - 1)) {
        continue;
      }
      wsNSPrefix = wsAttrName.Left(iFind);
    }
    if (!XFA_FDEExtension_ResolveNamespaceQualifier(
            pElement, wsNSPrefix.AsStringC(), wsAttrNS)) {
      continue;
    }
    if (bMatchNSAsPrefix) {
      if (wsAttrNS.Left(wsNamespaceURIPrefix.GetLength()) !=
          wsNamespaceURIPrefix) {
        continue;
      }
    } else {
      if (wsAttrNS != wsNamespaceURIPrefix)
        continue;
    }
    wsValue = wsAttrValue;
    return true;
  }
  return false;
}

CFDE_XMLNode* GetDataSetsFromXDP(CFDE_XMLNode* pXMLDocumentNode) {
  if (MatchNodeName(pXMLDocumentNode,
                    XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pName,
                    XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pURI,
                    XFA_GetPacketByIndex(XFA_PACKET_Datasets)->eFlags)) {
    return pXMLDocumentNode;
  }
  if (!MatchNodeName(pXMLDocumentNode,
                     XFA_GetPacketByIndex(XFA_PACKET_XDP)->pName,
                     XFA_GetPacketByIndex(XFA_PACKET_XDP)->pURI,
                     XFA_GetPacketByIndex(XFA_PACKET_XDP)->eFlags)) {
    return nullptr;
  }
  for (CFDE_XMLNode* pDatasetsNode =
           pXMLDocumentNode->GetNodeItem(CFDE_XMLNode::FirstChild);
       pDatasetsNode;
       pDatasetsNode = pDatasetsNode->GetNodeItem(CFDE_XMLNode::NextSibling)) {
    if (!MatchNodeName(pDatasetsNode,
                       XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pName,
                       XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pURI,
                       XFA_GetPacketByIndex(XFA_PACKET_Datasets)->eFlags)) {
      continue;
    }
    return pDatasetsNode;
  }
  return nullptr;
}

bool IsStringAllWhitespace(CFX_WideString wsText) {
  wsText.TrimRight(L"\x20\x9\xD\xA");
  return wsText.IsEmpty();
}

void ConvertXMLToPlainText(CFDE_XMLElement* pRootXMLNode,
                           CFX_WideString& wsOutput) {
  for (CFDE_XMLNode* pXMLChild =
           pRootXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
       pXMLChild;
       pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
    switch (pXMLChild->GetType()) {
      case FDE_XMLNODE_Element: {
        CFX_WideString wsTextData;
        static_cast<CFDE_XMLElement*>(pXMLChild)->GetTextData(wsTextData);
        wsTextData += L"\n";
        wsOutput += wsTextData;
        break;
      }
      case FDE_XMLNODE_Text: {
        CFX_WideString wsText;
        static_cast<CFDE_XMLText*>(pXMLChild)->GetText(wsText);
        if (IsStringAllWhitespace(wsText))
          continue;

        wsOutput = wsText;
        break;
      }
      case FDE_XMLNODE_CharData: {
        CFX_WideString wsCharData;
        static_cast<CFDE_XMLCharData*>(pXMLChild)->GetCharData(wsCharData);
        if (IsStringAllWhitespace(wsCharData))
          continue;

        wsOutput = wsCharData;
        break;
      }
      default:
        ASSERT(false);
        break;
    }
  }
}

const XFA_PACKETINFO* GetPacketByName(const CFX_WideStringC& wsName) {
  if (wsName.IsEmpty())
    return nullptr;

  uint32_t uHash = FX_HashCode_GetW(wsName, false);
  int32_t iStart = 0;
  int32_t iEnd = g_iXFAPacketCount - 1;
  do {
    int32_t iMid = (iStart + iEnd) / 2;
    const XFA_PACKETINFO* pInfo = g_XFAPacketData + iMid;
    if (uHash == pInfo->uHash)
      return pInfo;
    if (uHash < pInfo->uHash)
      iEnd = iMid - 1;
    else
      iStart = iMid + 1;
  } while (iStart <= iEnd);
  return nullptr;
}

}  // namespace

bool XFA_RecognizeRichText(CFDE_XMLElement* pRichTextXMLNode) {
  if (pRichTextXMLNode) {
    CFX_WideString wsNamespaceURI;
    GetElementTagNamespaceURI(pRichTextXMLNode, wsNamespaceURI);
    if (wsNamespaceURI == L"http://www.w3.org/1999/xhtml")
      return true;
  }
  return false;
}

CXFA_SimpleParser::CXFA_SimpleParser(CXFA_Document* pFactory,
                                     bool bDocumentParser)
    : m_pXMLParser(nullptr),
      m_pXMLDoc(nullptr),
      m_pStream(nullptr),
      m_pFileRead(nullptr),
      m_pFactory(pFactory),
      m_pRootNode(nullptr),
      m_ePacketID(XFA_XDPPACKET_UNKNOWN),
      m_bDocumentParser(bDocumentParser) {}

CXFA_SimpleParser::~CXFA_SimpleParser() {}

void CXFA_SimpleParser::SetFactory(CXFA_Document* pFactory) {
  m_pFactory = pFactory;
}

int32_t CXFA_SimpleParser::StartParse(
    const CFX_RetainPtr<IFX_SeekableReadStream>& pStream,
    XFA_XDPPACKET ePacketID) {
  CloseParser();
  m_pFileRead = pStream;
  m_pStream = IFGAS_Stream::CreateStream(
      pStream, FX_STREAMACCESS_Read | FX_STREAMACCESS_Text);
  if (!m_pStream)
    return XFA_PARSESTATUS_StreamErr;

  uint16_t wCodePage = m_pStream->GetCodePage();
  if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE &&
      wCodePage != FX_CODEPAGE_UTF8) {
    m_pStream->SetCodePage(FX_CODEPAGE_UTF8);
  }
  m_pXMLDoc = pdfium::MakeUnique<CFDE_XMLDoc>();
  auto pNewParser =
      pdfium::MakeUnique<CFDE_XMLParser>(m_pXMLDoc->GetRoot(), m_pStream);
  m_pXMLParser = pNewParser.get();
  if (!m_pXMLDoc->LoadXML(std::move(pNewParser)))
    return XFA_PARSESTATUS_StatusErr;

  m_ePacketID = ePacketID;
  return XFA_PARSESTATUS_Ready;
}

int32_t CXFA_SimpleParser::DoParse(IFX_Pause* pPause) {
  if (!m_pXMLDoc || m_ePacketID == XFA_XDPPACKET_UNKNOWN)
    return XFA_PARSESTATUS_StatusErr;

  int32_t iRet = m_pXMLDoc->DoLoad(pPause);
  if (iRet < 0)
    return XFA_PARSESTATUS_SyntaxErr;
  if (iRet < 100)
    return iRet / 2;

  m_pRootNode = ParseAsXDPPacket(GetDocumentNode(m_pXMLDoc.get()), m_ePacketID);
  m_pXMLDoc->CloseXML();
  m_pStream.Reset();
  if (!m_pRootNode)
    return XFA_PARSESTATUS_StatusErr;

  return XFA_PARSESTATUS_Done;
}

int32_t CXFA_SimpleParser::ParseXMLData(const CFX_WideString& wsXML,
                                        CFDE_XMLNode*& pXMLNode,
                                        IFX_Pause* pPause) {
  CloseParser();
  pXMLNode = nullptr;
  m_pXMLDoc = pdfium::MakeUnique<CFDE_XMLDoc>();
  auto pStream = pdfium::MakeRetain<CXFA_WideTextRead>(wsXML);
  auto pParser =
      pdfium::MakeUnique<CFDE_XMLParser>(m_pXMLDoc->GetRoot(), pStream);
  pParser->m_dwCheckStatus = 0x03;
  if (!m_pXMLDoc->LoadXML(std::move(pParser)))
    return XFA_PARSESTATUS_StatusErr;

  int32_t iRet = m_pXMLDoc->DoLoad(pPause);
  if (iRet < 0 || iRet >= 100)
    m_pXMLDoc->CloseXML();
  if (iRet < 0)
    return XFA_PARSESTATUS_SyntaxErr;
  if (iRet < 100)
    return iRet / 2;

  pXMLNode = GetDocumentNode(m_pXMLDoc.get());
  return XFA_PARSESTATUS_Done;
}

void CXFA_SimpleParser::ConstructXFANode(CXFA_Node* pXFANode,
                                         CFDE_XMLNode* pXMLNode) {
  XFA_XDPPACKET ePacketID = (XFA_XDPPACKET)pXFANode->GetPacketID();
  if (ePacketID == XFA_XDPPACKET_Datasets) {
    if (pXFANode->GetElementType() == XFA_Element::DataValue) {
      for (CFDE_XMLNode* pXMLChild =
               pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
           pXMLChild;
           pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
        FDE_XMLNODETYPE eNodeType = pXMLChild->GetType();
        if (eNodeType == FDE_XMLNODE_Instruction)
          continue;

        if (eNodeType == FDE_XMLNODE_Element) {
          CXFA_Node* pXFAChild = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets,
                                                        XFA_Element::DataValue);
          if (!pXFAChild)
            return;

          CFX_WideString wsNodeStr;
          CFDE_XMLElement* child = static_cast<CFDE_XMLElement*>(pXMLChild);
          child->GetLocalTagName(wsNodeStr);
          pXFAChild->SetCData(XFA_ATTRIBUTE_Name, wsNodeStr);
          CFX_WideString wsChildValue;
          XFA_GetPlainTextFromRichText(child, wsChildValue);
          if (!wsChildValue.IsEmpty())
            pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsChildValue);

          pXFANode->InsertChild(pXFAChild);
          pXFAChild->SetXMLMappingNode(pXMLChild);
          pXFAChild->SetFlag(XFA_NodeFlag_Initialized, false);
          break;
        }
      }
      m_pRootNode = pXFANode;
    } else {
      m_pRootNode = DataLoader(pXFANode, pXMLNode, true);
    }
  } else if (pXFANode->IsContentNode()) {
    ParseContentNode(pXFANode, pXMLNode, ePacketID);
    m_pRootNode = pXFANode;
  } else {
    m_pRootNode = NormalLoader(pXFANode, pXMLNode, ePacketID, true);
  }
}

CXFA_Node* CXFA_SimpleParser::GetRootNode() const {
  return m_pRootNode;
}

CFDE_XMLDoc* CXFA_SimpleParser::GetXMLDoc() const {
  return m_pXMLDoc.get();
}

bool XFA_FDEExtension_ResolveNamespaceQualifier(
    CFDE_XMLElement* pNode,
    const CFX_WideStringC& wsQualifier,
    CFX_WideString& wsNamespaceURI) {
  if (!pNode)
    return false;

  CFDE_XMLNode* pFakeRoot = pNode->GetNodeItem(CFDE_XMLNode::Root);
  CFX_WideString wsNSAttribute;
  bool bRet = false;
  if (wsQualifier.IsEmpty()) {
    wsNSAttribute = L"xmlns";
    bRet = true;
  } else {
    wsNSAttribute = L"xmlns:" + wsQualifier;
  }
  for (; pNode != pFakeRoot; pNode = static_cast<CFDE_XMLElement*>(
                                 pNode->GetNodeItem(CFDE_XMLNode::Parent))) {
    if (pNode->GetType() != FDE_XMLNODE_Element)
      continue;

    if (pNode->HasAttribute(wsNSAttribute.c_str())) {
      pNode->GetString(wsNSAttribute.c_str(), wsNamespaceURI);
      return true;
    }
  }
  wsNamespaceURI.clear();
  return bRet;
}

CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket(CFDE_XMLNode* pXMLDocumentNode,
                                               XFA_XDPPACKET ePacketID) {
  switch (ePacketID) {
    case XFA_XDPPACKET_UNKNOWN:
      return nullptr;
    case XFA_XDPPACKET_XDP:
      return ParseAsXDPPacket_XDP(pXMLDocumentNode, ePacketID);
    case XFA_XDPPACKET_Config:
      return ParseAsXDPPacket_Config(pXMLDocumentNode, ePacketID);
    case XFA_XDPPACKET_Template:
    case XFA_XDPPACKET_Form:
      return ParseAsXDPPacket_TemplateForm(pXMLDocumentNode, ePacketID);
    case XFA_XDPPACKET_Datasets:
      return ParseAsXDPPacket_Data(pXMLDocumentNode, ePacketID);
    case XFA_XDPPACKET_Xdc:
      return ParseAsXDPPacket_Xdc(pXMLDocumentNode, ePacketID);
    case XFA_XDPPACKET_LocaleSet:
    case XFA_XDPPACKET_ConnectionSet:
    case XFA_XDPPACKET_SourceSet:
      return ParseAsXDPPacket_LocaleConnectionSourceSet(pXMLDocumentNode,
                                                        ePacketID);
    default:
      return ParseAsXDPPacket_User(pXMLDocumentNode, ePacketID);
  }
}

CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_XDP(
    CFDE_XMLNode* pXMLDocumentNode,
    XFA_XDPPACKET ePacketID) {
  if (!MatchNodeName(pXMLDocumentNode,
                     XFA_GetPacketByIndex(XFA_PACKET_XDP)->pName,
                     XFA_GetPacketByIndex(XFA_PACKET_XDP)->pURI,
                     XFA_GetPacketByIndex(XFA_PACKET_XDP)->eFlags)) {
    return nullptr;
  }
  CXFA_Node* pXFARootNode =
      m_pFactory->CreateNode(XFA_XDPPACKET_XDP, XFA_Element::Xfa);
  if (!pXFARootNode)
    return nullptr;

  m_pRootNode = pXFARootNode;
  pXFARootNode->SetCData(XFA_ATTRIBUTE_Name, L"xfa");
  {
    CFDE_XMLElement* pElement = static_cast<CFDE_XMLElement*>(pXMLDocumentNode);
    int32_t iAttributeCount = pElement->CountAttributes();
    for (int32_t i = 0; i < iAttributeCount; i++) {
      CFX_WideString wsAttriName, wsAttriValue;
      pElement->GetAttribute(i, wsAttriName, wsAttriValue);
      if (wsAttriName == L"uuid")
        pXFARootNode->SetCData(XFA_ATTRIBUTE_Uuid, wsAttriValue);
      else if (wsAttriName == L"timeStamp")
        pXFARootNode->SetCData(XFA_ATTRIBUTE_TimeStamp, wsAttriValue);
    }
  }

  CFDE_XMLNode* pXMLConfigDOMRoot = nullptr;
  CXFA_Node* pXFAConfigDOMRoot = nullptr;
  {
    for (CFDE_XMLNode* pChildItem =
             pXMLDocumentNode->GetNodeItem(CFDE_XMLNode::FirstChild);
         pChildItem;
         pChildItem = pChildItem->GetNodeItem(CFDE_XMLNode::NextSibling)) {
      const XFA_PACKETINFO* pPacketInfo =
          XFA_GetPacketByIndex(XFA_PACKET_Config);
      if (!MatchNodeName(pChildItem, pPacketInfo->pName, pPacketInfo->pURI,
                         pPacketInfo->eFlags)) {
        continue;
      }
      if (pXFARootNode->GetFirstChildByName(pPacketInfo->uHash)) {
        return nullptr;
      }
      pXMLConfigDOMRoot = pChildItem;
      pXFAConfigDOMRoot =
          ParseAsXDPPacket_Config(pXMLConfigDOMRoot, XFA_XDPPACKET_Config);
      pXFARootNode->InsertChild(pXFAConfigDOMRoot, nullptr);
    }
  }

  CFDE_XMLNode* pXMLDatasetsDOMRoot = nullptr;
  CFDE_XMLNode* pXMLFormDOMRoot = nullptr;
  CFDE_XMLNode* pXMLTemplateDOMRoot = nullptr;
  {
    for (CFDE_XMLNode* pChildItem =
             pXMLDocumentNode->GetNodeItem(CFDE_XMLNode::FirstChild);
         pChildItem;
         pChildItem = pChildItem->GetNodeItem(CFDE_XMLNode::NextSibling)) {
      if (!pChildItem || pChildItem->GetType() != FDE_XMLNODE_Element)
        continue;
      if (pChildItem == pXMLConfigDOMRoot)
        continue;

      CFDE_XMLElement* pElement =
          reinterpret_cast<CFDE_XMLElement*>(pChildItem);
      CFX_WideString wsPacketName;
      pElement->GetLocalTagName(wsPacketName);
      const XFA_PACKETINFO* pPacketInfo =
          GetPacketByName(wsPacketName.AsStringC());
      if (pPacketInfo && pPacketInfo->pURI) {
        if (!MatchNodeName(pElement, pPacketInfo->pName, pPacketInfo->pURI,
                           pPacketInfo->eFlags)) {
          pPacketInfo = nullptr;
        }
      }
      XFA_XDPPACKET ePacket =
          pPacketInfo ? pPacketInfo->eName : XFA_XDPPACKET_USER;
      if (ePacket == XFA_XDPPACKET_XDP)
        continue;
      if (ePacket == XFA_XDPPACKET_Datasets) {
        if (pXMLDatasetsDOMRoot)
          return nullptr;

        pXMLDatasetsDOMRoot = pElement;
      } else if (ePacket == XFA_XDPPACKET_Form) {
        if (pXMLFormDOMRoot)
          return nullptr;

        pXMLFormDOMRoot = pElement;
      } else if (ePacket == XFA_XDPPACKET_Template) {
        if (pXMLTemplateDOMRoot) {
          // Found a duplicate template packet.
          return nullptr;
        }
        CXFA_Node* pPacketNode = ParseAsXDPPacket(pElement, ePacket);
        if (pPacketNode) {
          pXMLTemplateDOMRoot = pElement;
          pXFARootNode->InsertChild(pPacketNode);
        }
      } else {
        CXFA_Node* pPacketNode = ParseAsXDPPacket(pElement, ePacket);
        if (pPacketNode) {
          if (pPacketInfo &&
              (pPacketInfo->eFlags & XFA_XDPPACKET_FLAGS_SUPPORTONE) &&
              pXFARootNode->GetFirstChildByName(pPacketInfo->uHash)) {
            return nullptr;
          }
          pXFARootNode->InsertChild(pPacketNode);
        }
      }
    }
  }

  if (!pXMLTemplateDOMRoot) {
    // No template is found.
    return nullptr;
  }
  if (pXMLDatasetsDOMRoot) {
    CXFA_Node* pPacketNode =
        ParseAsXDPPacket(pXMLDatasetsDOMRoot, XFA_XDPPACKET_Datasets);
    if (pPacketNode)
      pXFARootNode->InsertChild(pPacketNode);
  }
  if (pXMLFormDOMRoot) {
    CXFA_Node* pPacketNode =
        ParseAsXDPPacket(pXMLFormDOMRoot, XFA_XDPPACKET_Form);
    if (pPacketNode)
      pXFARootNode->InsertChild(pPacketNode);
  }
  pXFARootNode->SetXMLMappingNode(pXMLDocumentNode);
  return pXFARootNode;
}

CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_Config(
    CFDE_XMLNode* pXMLDocumentNode,
    XFA_XDPPACKET ePacketID) {
  if (!MatchNodeName(pXMLDocumentNode,
                     XFA_GetPacketByIndex(XFA_PACKET_Config)->pName,
                     XFA_GetPacketByIndex(XFA_PACKET_Config)->pURI,
                     XFA_GetPacketByIndex(XFA_PACKET_Config)->eFlags)) {
    return nullptr;
  }
  CXFA_Node* pNode =
      m_pFactory->CreateNode(XFA_XDPPACKET_Config, XFA_Element::Config);
  if (!pNode)
    return nullptr;

  pNode->SetCData(XFA_ATTRIBUTE_Name,
                  XFA_GetPacketByIndex(XFA_PACKET_Config)->pName);
  if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID, true))
    return nullptr;

  pNode->SetXMLMappingNode(pXMLDocumentNode);
  return pNode;
}

CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_TemplateForm(
    CFDE_XMLNode* pXMLDocumentNode,
    XFA_XDPPACKET ePacketID) {
  CXFA_Node* pNode = nullptr;
  if (ePacketID == XFA_XDPPACKET_Template) {
    if (MatchNodeName(pXMLDocumentNode,
                      XFA_GetPacketByIndex(XFA_PACKET_Template)->pName,
                      XFA_GetPacketByIndex(XFA_PACKET_Template)->pURI,
                      XFA_GetPacketByIndex(XFA_PACKET_Template)->eFlags)) {
      pNode =
          m_pFactory->CreateNode(XFA_XDPPACKET_Template, XFA_Element::Template);
      if (!pNode)
        return nullptr;

      pNode->SetCData(XFA_ATTRIBUTE_Name,
                      XFA_GetPacketByIndex(XFA_PACKET_Template)->pName);
      if (m_bDocumentParser) {
        CFX_WideString wsNamespaceURI;
        CFDE_XMLElement* pXMLDocumentElement =
            static_cast<CFDE_XMLElement*>(pXMLDocumentNode);
        pXMLDocumentElement->GetNamespaceURI(wsNamespaceURI);
        if (wsNamespaceURI.IsEmpty())
          pXMLDocumentElement->GetString(L"xmlns:xfa", wsNamespaceURI);

        pNode->GetDocument()->RecognizeXFAVersionNumber(wsNamespaceURI);
      }
      if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID, true))
        return nullptr;
    }
  } else if (ePacketID == XFA_XDPPACKET_Form) {
    if (MatchNodeName(pXMLDocumentNode,
                      XFA_GetPacketByIndex(XFA_PACKET_Form)->pName,
                      XFA_GetPacketByIndex(XFA_PACKET_Form)->pURI,
                      XFA_GetPacketByIndex(XFA_PACKET_Form)->eFlags)) {
      CFDE_XMLElement* pXMLDocumentElement =
          static_cast<CFDE_XMLElement*>(pXMLDocumentNode);
      CFX_WideString wsChecksum;
      pXMLDocumentElement->GetString(L"checksum", wsChecksum);
      if (wsChecksum.GetLength() != 28 ||
          m_pXMLParser->m_dwCheckStatus != 0x03) {
        return nullptr;
      }

      auto pChecksum = pdfium::MakeUnique<CFX_ChecksumContext>();
      pChecksum->StartChecksum();
      pChecksum->UpdateChecksum(m_pFileRead, m_pXMLParser->m_nStart[0],
                                m_pXMLParser->m_nSize[0]);
      pChecksum->UpdateChecksum(m_pFileRead, m_pXMLParser->m_nStart[1],
                                m_pXMLParser->m_nSize[1]);
      pChecksum->FinishChecksum();
      CFX_ByteString bsCheck = pChecksum->GetChecksum();
      if (bsCheck != wsChecksum.UTF8Encode())
        return nullptr;

      pNode = m_pFactory->CreateNode(XFA_XDPPACKET_Form, XFA_Element::Form);
      if (!pNode)
        return nullptr;

      pNode->SetCData(XFA_ATTRIBUTE_Name,
                      XFA_GetPacketByIndex(XFA_PACKET_Form)->pName);
      pNode->SetAttribute(XFA_ATTRIBUTE_Checksum, wsChecksum.AsStringC());
      CXFA_Node* pTemplateRoot =
          m_pRootNode->GetFirstChildByClass(XFA_Element::Template);
      CXFA_Node* pTemplateChosen =
          pTemplateRoot
              ? pTemplateRoot->GetFirstChildByClass(XFA_Element::Subform)
              : nullptr;
      bool bUseAttribute = true;
      if (pTemplateChosen &&
          pTemplateChosen->GetEnum(XFA_ATTRIBUTE_RestoreState) !=
              XFA_ATTRIBUTEENUM_Auto) {
        bUseAttribute = false;
      }
      if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID, bUseAttribute))
        return nullptr;
    }
  }
  if (pNode)
    pNode->SetXMLMappingNode(pXMLDocumentNode);

  return pNode;
}

CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_Data(
    CFDE_XMLNode* pXMLDocumentNode,
    XFA_XDPPACKET ePacketID) {
  CFDE_XMLNode* pDatasetsXMLNode = GetDataSetsFromXDP(pXMLDocumentNode);
  if (pDatasetsXMLNode) {
    CXFA_Node* pNode =
        m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataModel);
    if (!pNode)
      return nullptr;

    pNode->SetCData(XFA_ATTRIBUTE_Name,
                    XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pName);
    if (!DataLoader(pNode, pDatasetsXMLNode, false))
      return nullptr;

    pNode->SetXMLMappingNode(pDatasetsXMLNode);
    return pNode;
  }

  CFDE_XMLNode* pDataXMLNode = nullptr;
  if (MatchNodeName(pXMLDocumentNode, L"data",
                    XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pURI,
                    XFA_GetPacketByIndex(XFA_PACKET_Datasets)->eFlags)) {
    static_cast<CFDE_XMLElement*>(pXMLDocumentNode)
        ->RemoveAttribute(L"xmlns:xfa");
    pDataXMLNode = pXMLDocumentNode;
  } else {
    CFDE_XMLElement* pDataElement = new CFDE_XMLElement(L"xfa:data");
    CFDE_XMLNode* pParentXMLNode =
        pXMLDocumentNode->GetNodeItem(CFDE_XMLNode::Parent);
    if (pParentXMLNode)
      pParentXMLNode->RemoveChildNode(pXMLDocumentNode);

    ASSERT(pXMLDocumentNode->GetType() == FDE_XMLNODE_Element);
    if (pXMLDocumentNode->GetType() == FDE_XMLNODE_Element) {
      static_cast<CFDE_XMLElement*>(pXMLDocumentNode)
          ->RemoveAttribute(L"xmlns:xfa");
    }
    pDataElement->InsertChildNode(pXMLDocumentNode);
    pDataXMLNode = pDataElement;
  }

  if (pDataXMLNode) {
    CXFA_Node* pNode =
        m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataGroup);
    if (!pNode) {
      if (pDataXMLNode != pXMLDocumentNode)
        delete pDataXMLNode;
      return nullptr;
    }
    CFX_WideString wsLocalName;
    static_cast<CFDE_XMLElement*>(pDataXMLNode)->GetLocalTagName(wsLocalName);
    pNode->SetCData(XFA_ATTRIBUTE_Name, wsLocalName);
    if (!DataLoader(pNode, pDataXMLNode, true))
      return nullptr;

    pNode->SetXMLMappingNode(pDataXMLNode);
    if (pDataXMLNode != pXMLDocumentNode)
      pNode->SetFlag(XFA_NodeFlag_OwnXMLNode, false);
    return pNode;
  }
  return nullptr;
}

CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_LocaleConnectionSourceSet(
    CFDE_XMLNode* pXMLDocumentNode,
    XFA_XDPPACKET ePacketID) {
  CXFA_Node* pNode = nullptr;
  if (ePacketID == XFA_XDPPACKET_LocaleSet) {
    if (MatchNodeName(pXMLDocumentNode,
                      XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->pName,
                      XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->pURI,
                      XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->eFlags)) {
      pNode = m_pFactory->CreateNode(XFA_XDPPACKET_LocaleSet,
                                     XFA_Element::LocaleSet);
      if (!pNode)
        return nullptr;

      pNode->SetCData(XFA_ATTRIBUTE_Name,
                      XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->pName);
      if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID, true))
        return nullptr;
    }
  } else if (ePacketID == XFA_XDPPACKET_ConnectionSet) {
    if (MatchNodeName(pXMLDocumentNode,
                      XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->pName,
                      XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->pURI,
                      XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->eFlags)) {
      pNode = m_pFactory->CreateNode(XFA_XDPPACKET_ConnectionSet,
                                     XFA_Element::ConnectionSet);
      if (!pNode)
        return nullptr;

      pNode->SetCData(XFA_ATTRIBUTE_Name,
                      XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->pName);
      if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID, true))
        return nullptr;
    }
  } else if (ePacketID == XFA_XDPPACKET_SourceSet) {
    if (MatchNodeName(pXMLDocumentNode,
                      XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->pName,
                      XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->pURI,
                      XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->eFlags)) {
      pNode = m_pFactory->CreateNode(XFA_XDPPACKET_SourceSet,
                                     XFA_Element::SourceSet);
      if (!pNode)
        return nullptr;

      pNode->SetCData(XFA_ATTRIBUTE_Name,
                      XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->pName);
      if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID, true))
        return nullptr;
    }
  }
  if (pNode)
    pNode->SetXMLMappingNode(pXMLDocumentNode);
  return pNode;
}

CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_Xdc(
    CFDE_XMLNode* pXMLDocumentNode,
    XFA_XDPPACKET ePacketID) {
  if (!MatchNodeName(pXMLDocumentNode,
                     XFA_GetPacketByIndex(XFA_PACKET_Xdc)->pName,
                     XFA_GetPacketByIndex(XFA_PACKET_Xdc)->pURI,
                     XFA_GetPacketByIndex(XFA_PACKET_Xdc)->eFlags))
    return nullptr;

  CXFA_Node* pNode =
      m_pFactory->CreateNode(XFA_XDPPACKET_Xdc, XFA_Element::Xdc);
  if (!pNode)
    return nullptr;

  pNode->SetCData(XFA_ATTRIBUTE_Name,
                  XFA_GetPacketByIndex(XFA_PACKET_Xdc)->pName);
  pNode->SetXMLMappingNode(pXMLDocumentNode);
  return pNode;
}

CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_User(
    CFDE_XMLNode* pXMLDocumentNode,
    XFA_XDPPACKET ePacketID) {
  CXFA_Node* pNode =
      m_pFactory->CreateNode(XFA_XDPPACKET_XDP, XFA_Element::Packet);
  if (!pNode)
    return nullptr;

  CFX_WideString wsName;
  static_cast<CFDE_XMLElement*>(pXMLDocumentNode)->GetLocalTagName(wsName);
  pNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
  if (!UserPacketLoader(pNode, pXMLDocumentNode))
    return nullptr;

  pNode->SetXMLMappingNode(pXMLDocumentNode);
  return pNode;
}

CXFA_Node* CXFA_SimpleParser::UserPacketLoader(CXFA_Node* pXFANode,
                                               CFDE_XMLNode* pXMLDoc) {
  return pXFANode;
}

CXFA_Node* CXFA_SimpleParser::DataLoader(CXFA_Node* pXFANode,
                                         CFDE_XMLNode* pXMLDoc,
                                         bool bDoTransform) {
  ParseDataGroup(pXFANode, pXMLDoc, XFA_XDPPACKET_Datasets);
  return pXFANode;
}

CXFA_Node* CXFA_SimpleParser::NormalLoader(CXFA_Node* pXFANode,
                                           CFDE_XMLNode* pXMLDoc,
                                           XFA_XDPPACKET ePacketID,
                                           bool bUseAttribute) {
  bool bOneOfPropertyFound = false;
  for (CFDE_XMLNode* pXMLChild = pXMLDoc->GetNodeItem(CFDE_XMLNode::FirstChild);
       pXMLChild;
       pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
    switch (pXMLChild->GetType()) {
      case FDE_XMLNODE_Element: {
        CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLChild);
        CFX_WideString wsTagName;
        pXMLElement->GetLocalTagName(wsTagName);
        XFA_Element eType = XFA_GetElementTypeForName(wsTagName.AsStringC());
        if (eType == XFA_Element::Unknown)
          continue;

        const XFA_PROPERTY* pPropertyInfo = XFA_GetPropertyOfElement(
            pXFANode->GetElementType(), eType, ePacketID);
        if (pPropertyInfo &&
            ((pPropertyInfo->uFlags &
              (XFA_PROPERTYFLAG_OneOf | XFA_PROPERTYFLAG_DefaultOneOf)) != 0)) {
          if (bOneOfPropertyFound)
            break;

          bOneOfPropertyFound = true;
        }
        CXFA_Node* pXFAChild = m_pFactory->CreateNode(ePacketID, eType);
        if (!pXFAChild)
          return nullptr;
        if (ePacketID == XFA_XDPPACKET_Config)
          pXFAChild->SetAttribute(XFA_ATTRIBUTE_Name, wsTagName.AsStringC());

        bool IsNeedValue = true;
        for (int32_t i = 0, count = pXMLElement->CountAttributes(); i < count;
             i++) {
          CFX_WideString wsAttrQualifiedName;
          CFX_WideString wsAttrName;
          CFX_WideString wsAttrValue;
          pXMLElement->GetAttribute(i, wsAttrQualifiedName, wsAttrValue);
          GetAttributeLocalName(wsAttrQualifiedName.AsStringC(), wsAttrName);
          if (wsAttrName == L"nil" && wsAttrValue == L"true") {
            IsNeedValue = false;
          }
          const XFA_ATTRIBUTEINFO* lpAttrInfo =
              XFA_GetAttributeByName(wsAttrName.AsStringC());
          if (!lpAttrInfo)
            continue;

          if (!bUseAttribute && lpAttrInfo->eName != XFA_ATTRIBUTE_Name &&
              lpAttrInfo->eName != XFA_ATTRIBUTE_Save) {
            continue;
          }
          pXFAChild->SetAttribute(lpAttrInfo->eName, wsAttrValue.AsStringC());
        }
        pXFANode->InsertChild(pXFAChild);
        if (eType == XFA_Element::Validate || eType == XFA_Element::Locale) {
          if (ePacketID == XFA_XDPPACKET_Config)
            ParseContentNode(pXFAChild, pXMLElement, ePacketID);
          else
            NormalLoader(pXFAChild, pXMLElement, ePacketID, bUseAttribute);

          break;
        }
        switch (pXFAChild->GetObjectType()) {
          case XFA_ObjectType::ContentNode:
          case XFA_ObjectType::TextNode:
          case XFA_ObjectType::NodeC:
          case XFA_ObjectType::NodeV:
            if (IsNeedValue)
              ParseContentNode(pXFAChild, pXMLElement, ePacketID);
            break;
          default:
            NormalLoader(pXFAChild, pXMLElement, ePacketID, bUseAttribute);
            break;
        }
      } break;
      case FDE_XMLNODE_Instruction:
        ParseInstruction(pXFANode, static_cast<CFDE_XMLInstruction*>(pXMLChild),
                         ePacketID);
        break;
      default:
        break;
    }
  }
  return pXFANode;
}

void CXFA_SimpleParser::ParseContentNode(CXFA_Node* pXFANode,
                                         CFDE_XMLNode* pXMLNode,
                                         XFA_XDPPACKET ePacketID) {
  XFA_Element element = XFA_Element::Sharptext;
  if (pXFANode->GetElementType() == XFA_Element::ExData) {
    CFX_WideStringC wsContentType =
        pXFANode->GetCData(XFA_ATTRIBUTE_ContentType);
    if (wsContentType == L"text/html")
      element = XFA_Element::SharpxHTML;
    else if (wsContentType == L"text/xml")
      element = XFA_Element::Sharpxml;
  }
  if (element == XFA_Element::SharpxHTML)
    pXFANode->SetXMLMappingNode(pXMLNode);

  CFX_WideString wsValue;
  for (CFDE_XMLNode* pXMLChild =
           pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
       pXMLChild;
       pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
    FDE_XMLNODETYPE eNodeType = pXMLChild->GetType();
    if (eNodeType == FDE_XMLNODE_Instruction)
      continue;

    if (element == XFA_Element::SharpxHTML) {
      if (eNodeType != FDE_XMLNODE_Element)
        break;

      if (XFA_RecognizeRichText(static_cast<CFDE_XMLElement*>(pXMLChild)))
        XFA_GetPlainTextFromRichText(static_cast<CFDE_XMLElement*>(pXMLChild),
                                     wsValue);
    } else if (element == XFA_Element::Sharpxml) {
      if (eNodeType != FDE_XMLNODE_Element)
        break;

      ConvertXMLToPlainText(static_cast<CFDE_XMLElement*>(pXMLChild), wsValue);
    } else {
      if (eNodeType == FDE_XMLNODE_Element)
        break;
      if (eNodeType == FDE_XMLNODE_Text)
        static_cast<CFDE_XMLText*>(pXMLChild)->GetText(wsValue);
      else if (eNodeType == FDE_XMLNODE_CharData)
        static_cast<CFDE_XMLCharData*>(pXMLChild)->GetCharData(wsValue);
    }
    break;
  }
  if (!wsValue.IsEmpty()) {
    if (pXFANode->IsContentNode()) {
      CXFA_Node* pContentRawDataNode =
          m_pFactory->CreateNode(ePacketID, element);
      ASSERT(pContentRawDataNode);
      pContentRawDataNode->SetCData(XFA_ATTRIBUTE_Value, wsValue);
      pXFANode->InsertChild(pContentRawDataNode);
    } else {
      pXFANode->SetCData(XFA_ATTRIBUTE_Value, wsValue);
    }
  }
}

void CXFA_SimpleParser::ParseDataGroup(CXFA_Node* pXFANode,
                                       CFDE_XMLNode* pXMLNode,
                                       XFA_XDPPACKET ePacketID) {
  for (CFDE_XMLNode* pXMLChild =
           pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
       pXMLChild;
       pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
    switch (pXMLChild->GetType()) {
      case FDE_XMLNODE_Element: {
        CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLChild);
        {
          CFX_WideString wsNamespaceURI;
          GetElementTagNamespaceURI(pXMLElement, wsNamespaceURI);
          if (wsNamespaceURI == L"http://www.xfa.com/schema/xfa-package/" ||
              wsNamespaceURI == L"http://www.xfa.org/schema/xfa-package/" ||
              wsNamespaceURI == L"http://www.w3.org/2001/XMLSchema-instance") {
            continue;
          }
        }

        XFA_Element eNodeType = XFA_Element::DataModel;
        if (eNodeType == XFA_Element::DataModel) {
          CFX_WideString wsDataNodeAttr;
          if (FindAttributeWithNS(pXMLElement, L"dataNode",
                                  L"http://www.xfa.org/schema/xfa-data/1.0/",
                                  wsDataNodeAttr)) {
            if (wsDataNodeAttr == L"dataGroup")
              eNodeType = XFA_Element::DataGroup;
            else if (wsDataNodeAttr == L"dataValue")
              eNodeType = XFA_Element::DataValue;
          }
        }
        CFX_WideString wsContentType;
        if (eNodeType == XFA_Element::DataModel) {
          if (FindAttributeWithNS(pXMLElement, L"contentType",
                                  L"http://www.xfa.org/schema/xfa-data/1.0/",
                                  wsContentType)) {
            if (!wsContentType.IsEmpty())
              eNodeType = XFA_Element::DataValue;
          }
        }
        if (eNodeType == XFA_Element::DataModel) {
          for (CFDE_XMLNode* pXMLDataChild =
                   pXMLElement->GetNodeItem(CFDE_XMLNode::FirstChild);
               pXMLDataChild; pXMLDataChild = pXMLDataChild->GetNodeItem(
                                  CFDE_XMLNode::NextSibling)) {
            if (pXMLDataChild->GetType() == FDE_XMLNODE_Element) {
              if (!XFA_RecognizeRichText(
                      static_cast<CFDE_XMLElement*>(pXMLDataChild))) {
                eNodeType = XFA_Element::DataGroup;
                break;
              }
            }
          }
        }
        if (eNodeType == XFA_Element::DataModel)
          eNodeType = XFA_Element::DataValue;

        CXFA_Node* pXFAChild =
            m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
        if (!pXFAChild)
          return;

        CFX_WideString wsNodeName;
        pXMLElement->GetLocalTagName(wsNodeName);
        pXFAChild->SetCData(XFA_ATTRIBUTE_Name, wsNodeName);
        bool bNeedValue = true;
        for (int32_t i = 0; i < pXMLElement->CountAttributes(); ++i) {
          CFX_WideString wsQualifiedName;
          CFX_WideString wsValue;
          CFX_WideString wsName;
          CFX_WideString wsNS;
          pXMLElement->GetAttribute(i, wsQualifiedName, wsValue);
          if (!ResolveAttribute(pXMLElement, wsQualifiedName.AsStringC(),
                                wsName, wsNS)) {
            continue;
          }
          if (wsName == L"nil" && wsValue == L"true") {
            bNeedValue = false;
            continue;
          }
          if (wsNS == L"http://www.xfa.com/schema/xfa-package/" ||
              wsNS == L"http://www.xfa.org/schema/xfa-package/" ||
              wsNS == L"http://www.w3.org/2001/XMLSchema-instance" ||
              wsNS == L"http://www.xfa.org/schema/xfa-data/1.0/") {
            continue;
          }
          CXFA_Node* pXFAMetaData = m_pFactory->CreateNode(
              XFA_XDPPACKET_Datasets, XFA_Element::DataValue);
          if (!pXFAMetaData)
            return;

          pXFAMetaData->SetCData(XFA_ATTRIBUTE_Name, wsName);
          pXFAMetaData->SetCData(XFA_ATTRIBUTE_QualifiedName, wsQualifiedName);
          pXFAMetaData->SetCData(XFA_ATTRIBUTE_Value, wsValue);
          pXFAMetaData->SetEnum(XFA_ATTRIBUTE_Contains,
                                XFA_ATTRIBUTEENUM_MetaData);
          pXFAChild->InsertChild(pXFAMetaData);
          pXFAMetaData->SetXMLMappingNode(pXMLElement);
          pXFAMetaData->SetFlag(XFA_NodeFlag_Initialized, false);
        }

        if (!bNeedValue) {
          CFX_WideString wsNilName(L"xsi:nil");
          pXMLElement->RemoveAttribute(wsNilName.c_str());
        }
        pXFANode->InsertChild(pXFAChild);
        if (eNodeType == XFA_Element::DataGroup)
          ParseDataGroup(pXFAChild, pXMLElement, ePacketID);
        else if (bNeedValue)
          ParseDataValue(pXFAChild, pXMLChild, XFA_XDPPACKET_Datasets);

        pXFAChild->SetXMLMappingNode(pXMLElement);
        pXFAChild->SetFlag(XFA_NodeFlag_Initialized, false);
        continue;
      }
      case FDE_XMLNODE_CharData: {
        CFDE_XMLCharData* pXMLCharData =
            static_cast<CFDE_XMLCharData*>(pXMLChild);
        CFX_WideString wsCharData;
        pXMLCharData->GetCharData(wsCharData);
        if (IsStringAllWhitespace(wsCharData))
          continue;

        CXFA_Node* pXFAChild = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets,
                                                      XFA_Element::DataValue);
        if (!pXFAChild)
          return;

        pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsCharData);
        pXFANode->InsertChild(pXFAChild);
        pXFAChild->SetXMLMappingNode(pXMLCharData);
        pXFAChild->SetFlag(XFA_NodeFlag_Initialized, false);
        continue;
      }
      case FDE_XMLNODE_Text: {
        CFDE_XMLText* pXMLText = static_cast<CFDE_XMLText*>(pXMLChild);
        CFX_WideString wsText;
        pXMLText->GetText(wsText);
        if (IsStringAllWhitespace(wsText))
          continue;

        CXFA_Node* pXFAChild = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets,
                                                      XFA_Element::DataValue);
        if (!pXFAChild)
          return;

        pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsText);
        pXFANode->InsertChild(pXFAChild);
        pXFAChild->SetXMLMappingNode(pXMLText);
        pXFAChild->SetFlag(XFA_NodeFlag_Initialized, false);
        continue;
      }
      default:
        continue;
    }
  }
}

void CXFA_SimpleParser::ParseDataValue(CXFA_Node* pXFANode,
                                       CFDE_XMLNode* pXMLNode,
                                       XFA_XDPPACKET ePacketID) {
  CFX_WideTextBuf wsValueTextBuf;
  CFX_WideTextBuf wsCurValueTextBuf;
  bool bMarkAsCompound = false;
  CFDE_XMLNode* pXMLCurValueNode = nullptr;
  for (CFDE_XMLNode* pXMLChild =
           pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
       pXMLChild;
       pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
    FDE_XMLNODETYPE eNodeType = pXMLChild->GetType();
    if (eNodeType == FDE_XMLNODE_Instruction)
      continue;

    CFX_WideString wsText;
    if (eNodeType == FDE_XMLNODE_Text) {
      static_cast<CFDE_XMLText*>(pXMLChild)->GetText(wsText);
      if (!pXMLCurValueNode)
        pXMLCurValueNode = pXMLChild;

      wsCurValueTextBuf << wsText;
    } else if (eNodeType == FDE_XMLNODE_CharData) {
      static_cast<CFDE_XMLCharData*>(pXMLChild)->GetCharData(wsText);
      if (!pXMLCurValueNode)
        pXMLCurValueNode = pXMLChild;

      wsCurValueTextBuf << wsText;
    } else if (XFA_RecognizeRichText(
                   static_cast<CFDE_XMLElement*>(pXMLChild))) {
      XFA_GetPlainTextFromRichText(static_cast<CFDE_XMLElement*>(pXMLChild),
                                   wsText);
      if (!pXMLCurValueNode)
        pXMLCurValueNode = pXMLChild;

      wsCurValueTextBuf << wsText;
    } else {
      bMarkAsCompound = true;
      if (pXMLCurValueNode) {
        CFX_WideString wsCurValue = wsCurValueTextBuf.MakeString();
        if (!wsCurValue.IsEmpty()) {
          CXFA_Node* pXFAChild =
              m_pFactory->CreateNode(ePacketID, XFA_Element::DataValue);
          if (!pXFAChild)
            return;

          pXFAChild->SetCData(XFA_ATTRIBUTE_Name, L"");
          pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsCurValue);
          pXFANode->InsertChild(pXFAChild);
          pXFAChild->SetXMLMappingNode(pXMLCurValueNode);
          pXFAChild->SetFlag(XFA_NodeFlag_Initialized, false);
          wsValueTextBuf << wsCurValue;
          wsCurValueTextBuf.Clear();
        }
        pXMLCurValueNode = nullptr;
      }
      CXFA_Node* pXFAChild =
          m_pFactory->CreateNode(ePacketID, XFA_Element::DataValue);
      if (!pXFAChild)
        return;

      CFX_WideString wsNodeStr;
      static_cast<CFDE_XMLElement*>(pXMLChild)->GetLocalTagName(wsNodeStr);
      pXFAChild->SetCData(XFA_ATTRIBUTE_Name, wsNodeStr);
      ParseDataValue(pXFAChild, pXMLChild, ePacketID);
      pXFANode->InsertChild(pXFAChild);
      pXFAChild->SetXMLMappingNode(pXMLChild);
      pXFAChild->SetFlag(XFA_NodeFlag_Initialized, false);
      CFX_WideStringC wsCurValue = pXFAChild->GetCData(XFA_ATTRIBUTE_Value);
      wsValueTextBuf << wsCurValue;
    }
  }
  if (pXMLCurValueNode) {
    CFX_WideString wsCurValue = wsCurValueTextBuf.MakeString();
    if (!wsCurValue.IsEmpty()) {
      if (bMarkAsCompound) {
        CXFA_Node* pXFAChild =
            m_pFactory->CreateNode(ePacketID, XFA_Element::DataValue);
        if (!pXFAChild)
          return;

        pXFAChild->SetCData(XFA_ATTRIBUTE_Name, L"");
        pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsCurValue);
        pXFANode->InsertChild(pXFAChild);
        pXFAChild->SetXMLMappingNode(pXMLCurValueNode);
        pXFAChild->SetFlag(XFA_NodeFlag_Initialized, false);
      }
      wsValueTextBuf << wsCurValue;
      wsCurValueTextBuf.Clear();
    }
    pXMLCurValueNode = nullptr;
  }
  CFX_WideString wsNodeValue = wsValueTextBuf.MakeString();
  pXFANode->SetCData(XFA_ATTRIBUTE_Value, wsNodeValue);
}

void CXFA_SimpleParser::ParseInstruction(CXFA_Node* pXFANode,
                                         CFDE_XMLInstruction* pXMLInstruction,
                                         XFA_XDPPACKET ePacketID) {
  if (!m_bDocumentParser)
    return;

  CFX_WideString wsTargetName;
  pXMLInstruction->GetTargetName(wsTargetName);
  if (wsTargetName == L"originalXFAVersion") {
    CFX_WideString wsData;
    if (pXMLInstruction->GetData(0, wsData) &&
        (pXFANode->GetDocument()->RecognizeXFAVersionNumber(wsData) !=
         XFA_VERSION_UNKNOWN)) {
      wsData.clear();
      if (pXMLInstruction->GetData(1, wsData) &&
          wsData == L"v2.7-scripting:1") {
        pXFANode->GetDocument()->SetFlag(XFA_DOCFLAG_Scripting, true);
      }
    }
  } else if (wsTargetName == L"acrobat") {
    CFX_WideString wsData;
    if (pXMLInstruction->GetData(0, wsData) && wsData == L"JavaScript") {
      if (pXMLInstruction->GetData(1, wsData) && wsData == L"strictScoping") {
        pXFANode->GetDocument()->SetFlag(XFA_DOCFLAG_StrictScoping, true);
      }
    }
  }
}

void CXFA_SimpleParser::CloseParser() {
  m_pXMLDoc.reset();
  m_pStream.Reset();
}
