## @file
# This file is used to parse a xml file of .PKG file
#
# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available 
# under the terms and conditions of the BSD License which accompanies this 
# distribution. The full text of the license may be found at 
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

'''
XmlParser
'''

##
# Import Modules
#
import re

from Library.Xml.XmlRoutines import XmlNode
from Library.Xml.XmlRoutines import CreateXmlElement
from Library.Xml.XmlRoutines import XmlList
from Library.Xml.XmlRoutines import XmlParseFile
from Core.DistributionPackageClass import DistributionPackageClass
from Object.POM.ModuleObject import DepexObject
from Library.ParserValidate import IsValidInfMoudleType
from Library.ParserValidate import IsValidInstallPath
from Library.Misc import IsEqualList
from Library.Misc import Sdict

from Logger.StringTable import ERR_XML_INVALID_VARIABLENAME
from Logger.StringTable import ERR_XML_INVALID_LIB_SUPMODLIST
from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPARCHLIST
from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST
from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB
from Logger.StringTable import ERR_FILE_NAME_INVALIDE
from Logger.ToolError import PARSER_ERROR
from Logger.ToolError import FORMAT_INVALID

from Xml.CommonXml import DistributionPackageHeaderXml
from Xml.CommonXml import MiscellaneousFileXml
from Xml.CommonXml import UserExtensionsXml
from Xml.XmlParserMisc import ConvertVariableName
from Xml.XmlParserMisc import IsRequiredItemListNull
from Xml.ModuleSurfaceAreaXml import ModuleSurfaceAreaXml
from Xml.PackageSurfaceAreaXml import PackageSurfaceAreaXml

import Logger.Log as Logger

##
# DistributionPackageXml
#
class DistributionPackageXml(object):
    def __init__(self):
        self.DistP = DistributionPackageClass()
        self.Pkg = ''

    ## ValidateDistributionPackage
    #
    # Check if any required item is missing in DistributionPackage
    #
    def ValidateDistributionPackage(self):
        XmlTreeLevel = ['DistributionPackage']
        if self.DistP:
            #
            # Check DistributionPackage -> DistributionHeader
            #
            XmlTreeLevel = ['DistributionPackage', '']
            CheckDict = {'DistributionHeader':self.DistP.Header }
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

            if self.DistP.Header:
                DpHeader = self.DistP.Header
                XmlTreeLevel = ['DistributionPackage', 'DistributionHeader']
                CheckDict = Sdict()
                if DpHeader.GetAbstract():
                    DPAbstract = DpHeader.GetAbstract()[0][1]
                else:
                    DPAbstract = ''
                if DpHeader.GetCopyright():
                    DPCopyright = DpHeader.GetCopyright()[0][1]
                else:
                    DPCopyright = ''
                if DpHeader.GetLicense():
                    DPLicense = DpHeader.GetLicense()[0][1]
                else:
                    DPLicense = ''
                
                CheckDict['Name'] = DpHeader.GetName()
                CheckDict['GUID'] = DpHeader.GetGuid()
                CheckDict['Version'] = DpHeader.GetVersion()
                CheckDict['Copyright'] = DPCopyright
                CheckDict['License'] = DPLicense
                CheckDict['Abstract'] = DPAbstract
                CheckDict['Vendor'] = DpHeader.GetVendor()
                CheckDict['Date'] = DpHeader.GetDate()
                CheckDict['XmlSpecification'] = DpHeader.GetXmlSpecification()

                IsRequiredItemListNull(CheckDict, XmlTreeLevel)
            else:
                XmlTreeLevel = ['DistributionPackage', 'DistributionHeader']
                CheckDict = CheckDict = {'DistributionHeader': '', }
                IsRequiredItemListNull(CheckDict, XmlTreeLevel)

            #
            # Check Each Package
            #
            for Key in self.DistP.PackageSurfaceArea:
                ValidatePackageSurfaceArea(self.DistP.PackageSurfaceArea[Key])

            #
            # Check Each Module
            #
            for Key in self.DistP.ModuleSurfaceArea:
                ValidateMS(self.DistP.ModuleSurfaceArea[Key], ['DistributionPackage', 'ModuleSurfaceArea'])

            #
            # Check Each Tool   
            #
            if self.DistP.Tools:
                XmlTreeLevel = ['DistributionPackage', 'Tools', 'Header']
                CheckDict = {'Name': self.DistP.Tools.GetName(), }
                IsRequiredItemListNull(CheckDict, XmlTreeLevel)

                if not self.DistP.Tools.GetFileList():
                    XmlTreeLevel = ['DistributionPackage', 'Tools']
                    CheckDict = {'FileName': None, }
                    IsRequiredItemListNull(CheckDict, XmlTreeLevel)
                for Item in self.DistP.Tools.GetFileList():
                    XmlTreeLevel = ['DistributionPackage', 'Tools']
                    CheckDict = {'FileName': Item.GetURI(), }
                    IsRequiredItemListNull(CheckDict, XmlTreeLevel)

            #
            # Check Each Misc File
            #
            if self.DistP.MiscellaneousFiles:
                XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles', 'Header']
                CheckDict = {'Name': self.DistP.MiscellaneousFiles.GetName(), }
                IsRequiredItemListNull(CheckDict, XmlTreeLevel)

                if not self.DistP.MiscellaneousFiles.GetFileList():
                    XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles']
                    CheckDict = {'FileName': None, }
                    IsRequiredItemListNull(CheckDict, XmlTreeLevel)
                for Item in self.DistP.MiscellaneousFiles.GetFileList():
                    XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles']
                    CheckDict = {'FileName': Item.GetURI(), }
                    IsRequiredItemListNull(CheckDict, XmlTreeLevel)

            #
            # Check Each Distribution Level User Extension
            #
            for Item in self.DistP.UserExtensions:
                XmlTreeLevel = ['DistributionPackage', 'UserExtensions']
                CheckDict = {'UserId': Item.GetUserID(), }
                IsRequiredItemListNull(CheckDict, XmlTreeLevel)


    def FromXml(self, Filename=None):
        if Filename is not None:
            self.DistP = DistributionPackageClass()
            #
            # Load to XML
            #
            self.Pkg = XmlParseFile(Filename)

            #
            # Parse Header information
            #
            Tmp = DistributionPackageHeaderXml()
            DistributionPackageHeader = \
            Tmp.FromXml(XmlNode(self.Pkg, '/DistributionPackage/DistributionHeader'), 'DistributionHeader')
            self.DistP.Header = DistributionPackageHeader
            #
            # Parse each PackageSurfaceArea
            #
            for Item in XmlList(self.Pkg, '/DistributionPackage/PackageSurfaceArea'):
                Psa = PackageSurfaceAreaXml()
                Package = Psa.FromXml(Item, 'PackageSurfaceArea')
                self.DistP.PackageSurfaceArea[(Package.GetGuid(), \
                                               Package.GetVersion(), \
                                               Package.GetPackagePath())] = \
                                               Package
            #
            # Parse each ModuleSurfaceArea
            #
            for Item in XmlList(self.Pkg, '/DistributionPackage/ModuleSurfaceArea'):
                Msa = ModuleSurfaceAreaXml()
                Module = Msa.FromXml(Item, 'ModuleSurfaceArea', True)
                ModuleKey = (Module.GetGuid(), Module.GetVersion(), Module.GetName(), Module.GetModulePath())
                self.DistP.ModuleSurfaceArea[ModuleKey] = Module

            #    
            # Parse Tools
            #
            Tmp = MiscellaneousFileXml()
            self.DistP.Tools = Tmp.FromXml2(XmlNode(self.Pkg, '/DistributionPackage/Tools'), 'Tools')

            #
            # Parse MiscFiles
            #
            Tmp = MiscellaneousFileXml()
            self.DistP.MiscellaneousFiles = \
            Tmp.FromXml2(XmlNode(self.Pkg, \
                                 '/DistributionPackage/MiscellaneousFiles'), \
                                 'MiscellaneousFiles')

            #
            # Parse UserExtensions
            #
            for Item in XmlList(self.Pkg, '/DistributionPackage/UserExtensions'):
                Tmp = UserExtensionsXml()
                self.DistP.UserExtensions.append(Tmp.FromXml2(Item, 'UserExtensions'))

            #
            # Check Required Items for XML
            #
            self.ValidateDistributionPackage()

            return self.DistP

    def ToXml(self, DistP):
        if self.DistP:
            pass
        if DistP is not None:
            #
            # Parse DistributionPackageHeader
            #
            Attrs = [['xmlns', 'http://www.uefi.org/2011/1.1'],
                     ['xmlns:xsi', 'http:/www.w3.org/2001/XMLSchema-instance'],
                     ]
            Root = CreateXmlElement('DistributionPackage', '', [], Attrs)

            Tmp = DistributionPackageHeaderXml()
            Root.appendChild(Tmp.ToXml(DistP.Header, 'DistributionHeader'))
            #
            # Parse each PackageSurfaceArea
            #
            for Package in DistP.PackageSurfaceArea.values():
                Psa = PackageSurfaceAreaXml()
                DomPackage = Psa.ToXml(Package)
                Root.appendChild(DomPackage)
            #
            # Parse each ModuleSurfaceArea
            #
            for Module in DistP.ModuleSurfaceArea.values():
                Msa = ModuleSurfaceAreaXml()
                DomModule = Msa.ToXml(Module)
                Root.appendChild(DomModule)
            #    
            # Parse Tools
            #
            Tmp = MiscellaneousFileXml()
            ToolNode = Tmp.ToXml2(DistP.Tools, 'Tools')
            if ToolNode is not None:
                Root.appendChild(ToolNode)
            #
            # Parse MiscFiles
            #
            Tmp = MiscellaneousFileXml()
            MiscFileNode = Tmp.ToXml2(DistP.MiscellaneousFiles,
                                      'MiscellaneousFiles')
            if MiscFileNode is not None:
                Root.appendChild(MiscFileNode)

            XmlContent = Root.toprettyxml(indent='  ')


            #
            # Remove empty element
            #
            XmlContent = re.sub(r'[\s\r\n]*<[^<>=]*/>', '', XmlContent)

            #
            # Remove empty help text element
            #
            XmlContent = re.sub(r'[\s\r\n]*<HelpText Lang="en-US"/>', '',
                                XmlContent)

            #
            # Remove SupArchList="COMMON" or "common"
            #
            XmlContent = \
            re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
            '[\s\r\n]*"', '', XmlContent)
            XmlContent = \
            re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
            '[\s\r\n]*"', '', XmlContent)
            #
            # Remove <SupArchList> COMMON </SupArchList>
            #
            XmlContent = \
            re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*COMMON[\s\r\n]*'
            '</SupArchList>[\s\r\n]*', '', XmlContent)

            #
            # Remove <SupArchList> common </SupArchList>
            #
            XmlContent = \
            re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*'
            'common[\s\r\n]*</SupArchList>[\s\r\n]*', '', XmlContent)

            #
            # Remove SupModList="COMMON" or "common"
            #            
            XmlContent = \
            re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
            '[\s\r\n]*"', '', XmlContent)
            XmlContent = \
            re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
            '[\s\r\n]*"', '', XmlContent)

            return XmlContent

        return ''

## ValidateMS
#
# Check if any required item is missing in ModuleSurfaceArea
#
# @param Module: The ModuleSurfaceArea to be checked
# @param XmlTreeLevel: The top level of Module 
#
def ValidateMS(Module, TopXmlTreeLevel):
    ValidateMS1(Module, TopXmlTreeLevel)
    ValidateMS2(Module, TopXmlTreeLevel)
    ValidateMS3(Module, TopXmlTreeLevel)

## ValidateMS1
#
# Check if any required item is missing in ModuleSurfaceArea
#
# @param Module: The ModuleSurfaceArea to be checked
# @param XmlTreeLevel: The top level of Module 
#
def ValidateMS1(Module, TopXmlTreeLevel):
    #
    # Check Guids -> GuidCName
    #
    XmlTreeLevel = TopXmlTreeLevel + ['Guids']
    for Item in Module.GetGuidList():
        if Item is None:
            CheckDict = {'GuidCName':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = TopXmlTreeLevel + ['Guids', 'GuidCName']
    for Item in Module.GetGuidList():
        CheckDict = {'CName':Item.GetCName(),
                     'GuidType':Item.GetGuidTypeList(),
                     'Usage':Item.GetUsage()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

        if Item.GetVariableName():
            Result = ConvertVariableName(Item.GetVariableName())
            if Result is None:
                Msg = "->".join(Node for Node in XmlTreeLevel)
                ErrorMsg = ERR_XML_INVALID_VARIABLENAME % (Item.GetVariableName(), Item.GetCName(), Msg)
                Logger.Error('\nUPT', PARSER_ERROR, ErrorMsg, RaiseError=True)
            else:
                Item.SetVariableName(Result)

    #
    # Check Protocols -> Protocol
    #
    XmlTreeLevel = TopXmlTreeLevel + ['Protocols']
    for Item in Module.GetProtocolList():
        if Item is None:
            CheckDict = {'Protocol':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = TopXmlTreeLevel + ['Protocols', 'Protocol']
    for Item in Module.GetProtocolList():
        CheckDict = {'CName':Item.GetCName(),
                     'Usage':Item.GetUsage()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check PPIs -> Ppi
    #
    XmlTreeLevel = TopXmlTreeLevel + ['PPIs']
    for Item in Module.GetPpiList():
        if Item is None:
            CheckDict = {'Ppi':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = TopXmlTreeLevel + ['PPIs', 'Ppi']
    for Item in Module.GetPpiList():
        CheckDict = {'CName':Item.GetCName(),
                     'Usage':Item.GetUsage()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check PcdCoded -> Entry
    #
    XmlTreeLevel = TopXmlTreeLevel + ['PcdCoded']
    for Item in Module.GetPcdList():
        if Item is None:
            CheckDict = {'PcdEntry':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = TopXmlTreeLevel + ['PcdCoded', 'PcdEntry']
    for Item in Module.GetPcdList():
        CheckDict = {'TokenSpaceGuidCname':Item.GetTokenSpaceGuidCName(),
                     'CName':Item.GetCName(),
                     'PcdUsage':Item.GetValidUsage(),
                     'PcdItemType':Item.GetItemType()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check Externs -> Extern
    #
    XmlTreeLevel = TopXmlTreeLevel + ['Externs']
    for Item in Module.GetExternList():
        if Item is None:
            CheckDict = {'Extern':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # If SupArchList is used to identify different EntryPoint, UnloadImage, Constructor/Destructor elements and 
    # that SupArchList does not match ModuleSurfaceArea.ModuleProperties:SupArchList, the tool must exit gracefully,
    # informing the user that the EDK II Build system does not support different EntryPoint, UnloadImage, 
    # Constructor or Destructor elements based on Architecture type.  Two SupArchList attributes are considered 
    # identical if it lists the same CPU architectures in any order.
    #
    for Item in Module.GetExternList():
        if len(Item.SupArchList) > 0:
            if not IsEqualList(Item.SupArchList, Module.SupArchList):
                Logger.Error('\nUPT',
                             PARSER_ERROR,
                             ERR_XML_INVALID_EXTERN_SUPARCHLIST % (str(Item.SupArchList), str(Module.SupArchList)),
                             RaiseError=True)

    #
    # Check DistributionPackage -> ModuleSurfaceArea -> UserExtensions
    #
    XmlTreeLevel = TopXmlTreeLevel + ['UserExtensions']
    for Item in Module.GetUserExtensionList():
        CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check DistributionPackage -> PackageSurfaceArea -> MiscellaneousFiles -> Filename
    #
    XmlTreeLevel = TopXmlTreeLevel + ['MiscellaneousFiles']
    for Item in Module.GetMiscFileList():
        if not Item.GetFileList():
            CheckDict = {'Filename': '', }
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)
        for File in Item.GetFileList():
            CheckDict = {'Filename': File.GetURI(), }

## ValidateMS2
#
# Check if any required item is missing in ModuleSurfaceArea
#
# @param Module: The ModuleSurfaceArea to be checked
# @param XmlTreeLevel: The top level of Module 
#
def ValidateMS2(Module, TopXmlTreeLevel):
    #
    # Check Header
    #
    XmlTreeLevel = TopXmlTreeLevel + ['Header']
    CheckDict = Sdict()
    CheckDict['Name'] = Module.GetName()
    CheckDict['BaseName'] = Module.GetBaseName()
    CheckDict['GUID'] = Module.GetGuid()
    CheckDict['Version'] = Module.GetVersion()
    IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check ModuleProperties
    #
    XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties']
    CheckDict = {'ModuleType':Module.GetModuleType(),
                 'Path':Module.GetModulePath()}
    IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    if not IsValidInstallPath(Module.GetModulePath()):
        Logger.Error("UPT", FORMAT_INVALID, ERR_FILE_NAME_INVALIDE % Module.GetModulePath())

    #
    # Check ModuleProperties->BootMode 
    #
    XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['BootMode']
    for Item in Module.GetBootModeList():
        CheckDict = {'Usage':Item.GetUsage(),
                     'SupportedBootModes':Item.GetSupportedBootModes()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check ModuleProperties->Event 
    #
    XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['Event']
    for Item in Module.GetEventList():
        CheckDict = {'Usage':Item.GetUsage(),
                     'EventType':Item.GetEventType()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check ModuleProperties->Hob 
    #
    XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['HOB']
    for Item in Module.GetHobList():
        CheckDict = {'Usage':Item.GetUsage(),
                     'HobType':Item.GetHobType()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # The UDP Specification supports the module type of UEFI_RUNTIME_DRIVER, which is not present in the EDK II INF 
    # File Specification v. 1.23, so UPT must perform the following translation that include the generation of a 
    # [Depex] section.
    #
    if Module.ModuleType == "UEFI_RUNTIME_DRIVER":
        Module.ModuleType = "DXE_RUNTIME_DRIVER"
        DxeObj = DepexObject()
        DxeObj.SetDepex("gEfiBdsArchProtocolGuid AND \ngEfiCpuArchProtocolGuid AND\n" + \
                        "gEfiMetronomeArchProtocolGuid AND \ngEfiMonotonicCounterArchProtocolGuid AND\n" + \
                        "gEfiRealTimeClockArchProtocolGuid AND \ngEfiResetArchProtocolGuid AND\n" + \
                        "gEfiRuntimeArchProtocolGuid AND \ngEfiSecurityArchProtocolGuid AND\n" + \
                        "gEfiTimerArchProtocolGuid AND \ngEfiVariableWriteArchProtocolGuid AND\n" + \
                        "gEfiVariableArchProtocolGuid AND \ngEfiWatchdogTimerArchProtocolGuid")
        DxeObj.SetModuleType(['DXE_RUNTIME_DRIVER'])
        Module.PeiDepex = []
        Module.DxeDepex = []
        Module.SmmDepex = []
        Module.DxeDepex.append(DxeObj)

    #
    # Check LibraryClassDefinitions -> LibraryClass
    #
    XmlTreeLevel = TopXmlTreeLevel + ['LibraryClassDefinitions']
    for Item in Module.GetLibraryClassList():
        if Item is None:
            CheckDict = {'LibraryClass':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = TopXmlTreeLevel + ['LibraryClassDefinitions', 'LibraryClass']

    IsLibraryModule = False
    LibrarySupModList = []
    for Item in Module.GetLibraryClassList():
        CheckDict = {'Keyword':Item.GetLibraryClass(),
                     'Usage':Item.GetUsage()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)
        #
        # If the LibraryClass:SupModList is not "UNDEFINED" the LIBRARY_CLASS entry must have the list 
        # appended using the format:
        # LIBRARY_CLASS = <ClassName> ["|" <Edk2ModuleTypeList>]
        #
        # Edk2ModuleTypeList ::= <ModuleType> [" " <ModuleType>]{0,}
        # <ModuleTypes>      ::= {"BASE"} {"SEC"} {"PEI_CORE"} {"PEIM"}
        #                       {"DXE_CORE"} {"DXE_DRIVER"} {"SMM_CORE"}
        #                       {"DXE_SMM_DRIVER"} {"DXE_RUNTIME_DRIVER"}
        #                       {"DXE_SAL_DRIVER"} {"UEFI_DRIVER"}
        #                       {"UEFI_APPLICATION"} {"USER_DEFINED"}
        #
        if len(Item.SupModuleList) > 0:
            for SupModule in Item.SupModuleList:
                if not IsValidInfMoudleType(SupModule):
                    Logger.Error('\nUPT',
                                 PARSER_ERROR,
                                 ERR_XML_INVALID_LIB_SUPMODLIST % (Item.LibraryClass, str(SupModule)),
                                 RaiseError=True)

        if Item.Usage == 'PRODUCES' or Item.Usage == 'SOMETIMES_PRODUCES':
            IsLibraryModule = True
            LibrarySupModList = Item.SupModuleList


    #
    # For Library modules (indicated by a LIBRARY_CLASS statement in the [Defines] section)                  
    # If the SupModList attribute of the CONSTRUCTOR or DESTRUCTOR element does not match the Supported Module 
    # Types listed after "LIBRARY_CLASS = <Keyword> |", the tool should gracefully exit with an error message 
    # stating that there is a conflict in the module types the CONSTRUCTOR/DESTRUCTOR is to be used with and 
    # the Module types this Library supports.
    #
    if IsLibraryModule:
        for Item in Module.GetExternList():
            if Item.Constructor or Item.Destructor:
                if hasattr(Item, 'SupModList') and len(Item.SupModList) > 0 and \
                   not IsEqualList(Item.SupModList, LibrarySupModList):
                    Logger.Error('\nUPT',
                         PARSER_ERROR,
                         ERR_XML_INVALID_EXTERN_SUPMODLIST % (str(Item.SupModList), str(LibrarySupModList)),
                         RaiseError=True)

    #
    # If the module is not a library module, the MODULE_TYPE listed in the ModuleSurfaceArea.Header must match the 
    # SupModList attribute.  If these conditions cannot be met, the tool must exit gracefully, informing the user 
    # that the EDK II Build system does not currently support the features required by this Module.
    #                   
    if not IsLibraryModule:
        for Item in Module.GetExternList():
            if hasattr(Item, 'SupModList') and len(Item.SupModList) > 0 and \
               not IsEqualList(Item.SupModList, [Module.ModuleType]):
                Logger.Error('\nUPT',
                     PARSER_ERROR,
                     ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB % (str(Module.ModuleType), str(Item.SupModList)),
                     RaiseError=True)
    #
    # Check SourceFiles
    #
    XmlTreeLevel = TopXmlTreeLevel + ['SourceFiles']
    for Item in Module.GetSourceFileList():
        if Item is None:
            CheckDict = {'Filename':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = TopXmlTreeLevel + ['SourceFiles']
    for Item in Module.GetSourceFileList():
        CheckDict = {'Filename':Item.GetSourceFile()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    for ItemCount in range(len(Module.GetBinaryFileList())):
        Item = Module.GetBinaryFileList()[ItemCount]
        if Item and len(Item.FileNamList) > 0 and Item.FileNamList[0].FileType == 'FREEFORM':
            Item.FileNamList[0].FileType = 'SUBTYPE_GUID'
            Module.GetBinaryFileList()[ItemCount] = Item

## ValidateMS3
#
# Check if any required item is missing in ModuleSurfaceArea
#
# @param Module: The ModuleSurfaceArea to be checked
# @param XmlTreeLevel: The top level of Module 
#
def ValidateMS3(Module, TopXmlTreeLevel):
    #
    # Check PackageDependencies -> Package
    #
    XmlTreeLevel = TopXmlTreeLevel + ['PackageDependencies']
    for Item in Module.GetPackageDependencyList():
        if Item is None:
            CheckDict = {'Package':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = TopXmlTreeLevel + ['PackageDependencies', 'Package']
    for Item in Module.GetPackageDependencyList():
        CheckDict = {'GUID':Item.GetGuid()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check BinaryFiles -> BinaryFile
    #
    for Item in Module.GetBinaryFileList():
        if Item is None:
            XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles']
            CheckDict = {'BinaryFile':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)
        if not Item.GetFileNameList():
            XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile']
            CheckDict = {'Filename':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

        XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile']
        for File in Item.GetFileNameList():
            CheckDict = {'Filename':File.GetFilename(),
                         'FileType':File.GetFileType()}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)
        for AsBuilt in Item.GetAsBuiltList():
            #
            # Check LibInstance
            #                        
            if len(AsBuilt.LibraryInstancesList) == 1 and not AsBuilt.LibraryInstancesList[0]:
                CheckDict = {'GUID':''}
                XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'LibraryInstances']
                IsRequiredItemListNull(CheckDict, XmlTreeLevel)
                            
            for LibItem in AsBuilt.LibraryInstancesList:
                CheckDict = {'Guid':LibItem.Guid,
                             'Version':LibItem.Version}
                XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'LibraryInstances']
                IsRequiredItemListNull(CheckDict, XmlTreeLevel)

            #
            # Check PatchPcd
            #
            for PatchPcdItem in AsBuilt.PatchPcdList:
                CheckDict = {'TokenSpaceGuidValue':PatchPcdItem.TokenSpaceGuidValue,
                             'PcdCName':PatchPcdItem.PcdCName,
                             'Token':PatchPcdItem.Token,
                             'DatumType':PatchPcdItem.DatumType,
                             'Value':PatchPcdItem.DefaultValue,
                             'Offset':PatchPcdItem.Offset}
                XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'PatchPcdValue']
                IsRequiredItemListNull(CheckDict, XmlTreeLevel)
                #
                # Check PcdError
                #
                for PcdErrorItem in PatchPcdItem.PcdErrorsList:
                    CheckDict = {'ErrorNumber':PcdErrorItem.ErrorNumber}
                    XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt',
                                                      'PatchPcdValue', 'PcdError']
                    IsRequiredItemListNull(CheckDict, XmlTreeLevel)
            #
            # Check PcdEx
            #
            for PcdExItem in AsBuilt.PcdExValueList:
                CheckDict = {'TokenSpaceGuidValue':PcdExItem.TokenSpaceGuidValue,
                             'Token':PcdExItem.Token,
                             'DatumType':PcdExItem.DatumType}
                XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'PcdExValue']
                IsRequiredItemListNull(CheckDict, XmlTreeLevel)
                #
                # Check PcdError
                #
                for PcdErrorItem in PcdExItem.PcdErrorsList:
                    CheckDict = {'ErrorNumber':PcdErrorItem.ErrorNumber}
                    XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt',
                                                      'PcdExValue', 'PcdError']
                    IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    #
    # Check SmmDepex
    #
    XmlTreeLevel = TopXmlTreeLevel + ['SmmDepex']
    for Item in Module.GetSmmDepex():
        CheckDict = {'Expression':Item.GetDepex()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check PeiDepex
    #
    XmlTreeLevel = TopXmlTreeLevel + ['PeiDepex']
    for Item in Module.GetPeiDepex():
        CheckDict = {'Expression':Item.GetDepex()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check DxeDepex
    #
    XmlTreeLevel = TopXmlTreeLevel + ['DxeDepex']
    for Item in Module.GetDxeDepex():
        CheckDict = {'Expression':Item.GetDepex()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check <UserExtensions>
    #
    XmlTreeLevel = TopXmlTreeLevel + ['UserExtensions']
    for Item in Module.GetUserExtensionList():
        CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

## ValidatePS1
#
# ValidatePS1
#
def ValidatePS1(Package):
    #
    # Check DistributionPackage -> PackageSurfaceArea -> Header
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'Header']
    CheckDict = Sdict()
    CheckDict['Name'] = Package.GetName()
    CheckDict['BaseName'] = Package.GetBaseName()
    CheckDict['GUID'] = Package.GetGuid()
    CheckDict['Version'] = Package.GetVersion()
    CheckDict['PackagePath'] = Package.GetPackagePath()

    IsRequiredItemListNull(CheckDict, XmlTreeLevel)
    if not IsValidInstallPath(Package.GetPackagePath()):
        Logger.Error("UPT", FORMAT_INVALID, ERR_FILE_NAME_INVALIDE % Package.GetPackagePath())

    #
    # Check DistributionPackage -> PackageSurfaceArea -> ClonedFrom
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ClonedFrom']
    for Item in Package.GetClonedFromList():
        if Item is None:
            CheckDict = Sdict()
            CheckDict['GUID'] = ''
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)
        CheckDict = Sdict()
        CheckDict['GUID'] = Item.GetPackageGuid()
        CheckDict['Version'] = Item.GetPackageVersion()

        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check DistributionPackage -> PackageSurfaceArea -> LibraryClassDeclarations -> LibraryClass
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'LibraryClassDeclarations']
    for Item in Package.GetLibraryClassList():
        if Item is None:
            CheckDict = {'LibraryClass':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'LibraryClassDeclarations', 'LibraryClass']
    for Item in Package.GetLibraryClassList():
        CheckDict = {'Keyword':Item.GetLibraryClass(),
                     'HeaderFile':Item.GetIncludeHeader()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check DistributionPackage -> PackageSurfaceArea -> IndustryStandardIncludes -> IndustryStandardHeader
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'IndustryStandardIncludes']
    for Item in Package.GetStandardIncludeFileList():
        if Item is None:
            CheckDict = {'IndustryStandardHeader':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'IndustryStandardIncludes', 'IndustryStandardHeader']
    for Item in Package.GetStandardIncludeFileList():
        CheckDict = {'HeaderFile':Item.GetFilePath()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check DistributionPackage -> PackageSurfaceArea -> PackageIncludes -> PackageHeader
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PackageIncludes']
    for Item in Package.GetPackageIncludeFileList():
        if Item is None:
            CheckDict = {'PackageHeader':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PackageIncludes', 'PackageHeader']
    for Item in Package.GetPackageIncludeFileList():
        CheckDict = {'HeaderFile':Item.GetFilePath()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

## ValidatePS2
#
# ValidatePS2
#
def ValidatePS2(Package):
    #
    # Check DistributionPackage -> PackageSurfaceArea -> Modules -> ModuleSurfaceArea
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'Modules', 'ModuleSurfaceArea']
    for Item in Package.GetModuleDict().values():
        ValidateMS(Item, XmlTreeLevel)

    #
    # Check DistributionPackage -> PackageSurfaceArea -> GuidDeclarations Entry
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'GuidDeclarations']
    for Item in Package.GetGuidList():
        if Item is None:
            CheckDict = {'Entry':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'GuidDeclarations', 'Entry']
    for Item in Package.GetGuidList():
        CheckDict = {'CName':Item.GetCName(),
                     'GuidValue':Item.GetGuid()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check DistributionPackage -> PackageSurfaceArea -> ProtocolDeclarations -> Entry
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ProtocolDeclarations']
    for Item in Package.GetProtocolList():
        if Item is None:
            CheckDict = {'Entry':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ProtocolDeclarations', 'Entry']
    for Item in Package.GetProtocolList():
        CheckDict = {'CName':Item.GetCName(),
                     'GuidValue':Item.GetGuid()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check DistributionPackage -> PackageSurfaceArea -> PpiDeclarations -> Entry
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PpiDeclarations']
    for Item in Package.GetPpiList():
        if Item is None:
            CheckDict = {'Entry':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PpiDeclarations', 'Entry']
    for Item in Package.GetPpiList():
        CheckDict = {'CName':Item.GetCName(),
                     'GuidValue':Item.GetGuid()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check DistributionPackage -> PackageSurfaceArea -> PcdDeclarations -> Entry
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PcdDeclarations']
    for Item in Package.GetPcdList():
        if Item is None:
            CheckDict = {'PcdEntry':''}
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PcdDeclarations', 'PcdEntry']
    for Item in Package.GetPcdList():
        CheckDict = {'TokenSpaceGuidCname':Item.GetTokenSpaceGuidCName(),
                     'Token':Item.GetToken(),
                     'CName':Item.GetCName(),
                     'DatumType':Item.GetDatumType(),
                     'ValidUsage':Item.GetValidUsage(),
                     'DefaultValue':Item.GetDefaultValue()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check DistributionPackage -> PackageSurfaceArea -> UserExtensions
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'UserExtensions']
    for Item in Package.GetUserExtensionList():
        CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
        IsRequiredItemListNull(CheckDict, XmlTreeLevel)

    #
    # Check DistributionPackage -> PackageSurfaceArea -> MiscellaneousFiles -> Filename
    #
    XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'MiscellaneousFiles']
    for Item in Package.GetMiscFileList():
        if not Item.GetFileList():
            CheckDict = {'Filename': '', }
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)
        for File in Item.GetFileList():
            CheckDict = {'Filename': File.GetURI(), }
            IsRequiredItemListNull(CheckDict, XmlTreeLevel)

## ValidatePackageSurfaceArea
#
# Check if any required item is missing in  PackageSurfaceArea
#
# @param Package: The PackageSurfaceArea to be checked 
#
def ValidatePackageSurfaceArea(Package):
    ValidatePS1(Package)
    ValidatePS2(Package)
