## @file DecPomAlignment.py
# This file contained the adapter for convert INF parser object to POM Object
#
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

'''
DecPomAlignment
'''
from __future__ import print_function

##
# Import Modules
#
import os.path
from os import sep
import platform

import re
import Logger.Log as Logger
from Logger import StringTable as ST
from Logger.ToolError import UPT_MUL_DEC_ERROR
from Logger.ToolError import FORMAT_INVALID

from Library.Parsing import NormPath
from Library.DataType import ARCH_LIST
from Library.DataType import TAB_GUIDS
from Library.DataType import TAB_PROTOCOLS
from Library.DataType import TAB_PPIS
from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME
from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID
from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION
from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION
from Library.DataType import TAB_DEC_DEFINES_PKG_UNI_FILE
from Library.DataType import TAB_ARCH_COMMON
from Library.DataType import TAB_INCLUDES
from Library.DataType import TAB_LIBRARY_CLASSES
from Library.DataType import TAB_PCDS
from Library.DataType import TAB_PCDS_FIXED_AT_BUILD_NULL
from Library.DataType import TAB_PCDS_PATCHABLE_IN_MODULE_NULL
from Library.DataType import TAB_PCDS_FEATURE_FLAG_NULL
from Library.DataType import TAB_PCDS_DYNAMIC_EX_NULL
from Library.DataType import TAB_PCDS_DYNAMIC_NULL
from Library.DataType import TAB_PTR_TYPE_PCD
from Library.DataType import ITEM_UNDEFINED
from Library.DataType import TAB_DEC_BINARY_ABSTRACT
from Library.DataType import TAB_DEC_BINARY_DESCRIPTION
from Library.DataType import TAB_LANGUAGE_EN_US
from Library.DataType import TAB_BINARY_HEADER_IDENTIFIER
from Library.DataType import TAB_BINARY_HEADER_USERID
from Library.DataType import TAB_LANGUAGE_EN_X
from Library.DataType import TAB_LANGUAGE_EN
from Library.DataType import TAB_STR_TOKENCNAME
from Library.DataType import TAB_STR_TOKENPROMPT
from Library.DataType import TAB_STR_TOKENHELP
from Library.DataType import TAB_STR_TOKENERR
from Library.DataType import TAB_HEX_START
from Library.DataType import TAB_SPLIT
import Library.DataType as DT
from Library.CommentParsing import ParseHeaderCommentSection
from Library.CommentParsing import ParseGenericComment
from Library.CommentParsing import ParseDecPcdGenericComment
from Library.CommentParsing import ParseDecPcdTailComment
from Library.Misc import GetFiles
from Library.Misc import Sdict
from Library.Misc import GetRelativePath
from Library.Misc import PathClass
from Library.Misc import ValidateUNIFilePath
from Library.UniClassObject import UniFileClassObject
from Library.UniClassObject import ConvertSpecialUnicodes
from Library.UniClassObject import GetLanguageCode1766
from Library.ParserValidate import IsValidPath
from Parser.DecParser import Dec
from Object.POM.PackageObject import PackageObject
from Object.POM.CommonObject import UserExtensionObject
from Object.POM.CommonObject import IncludeObject
from Object.POM.CommonObject import GuidObject
from Object.POM.CommonObject import ProtocolObject
from Object.POM.CommonObject import PpiObject
from Object.POM.CommonObject import LibraryClassObject
from Object.POM.CommonObject import PcdObject
from Object.POM.CommonObject import TextObject
from Object.POM.CommonObject import MiscFileObject
from Object.POM.CommonObject import FileObject


## DecPomAlignment
#
# Inherited from PackageObject
#
class DecPomAlignment(PackageObject):
    def __init__(self, Filename, WorkspaceDir = None, CheckMulDec = False):
        PackageObject.__init__(self)
        self.UserExtensions = ''
        self.WorkspaceDir = WorkspaceDir
        self.SupArchList = ARCH_LIST
        self.CheckMulDec = CheckMulDec
        self.DecParser = None
        self.UniFileClassObject = None
        self.PcdDefaultValueDict = {}

        #
        # Load Dec file
        #
        self.LoadDecFile(Filename)

        #
        # Transfer to Package Object if IsToPackage is True
        #
        self.DecToPackage()

    ## Load Dec file
    #
    # Load the file if it exists
    #
    # @param Filename:  Input value for filename of Dec file
    #
    def LoadDecFile(self, Filename):
        #
        # Insert a record for file
        #
        Filename = NormPath(Filename)
        (Path, Name) = os.path.split(Filename)
        self.SetFullPath(Filename)
        self.SetRelaPath(Path)
        self.SetFileName(Name)
        self.SetPackagePath(GetRelativePath(Path, self.WorkspaceDir))
        self.SetCombinePath(GetRelativePath(Filename, self.WorkspaceDir))

        self.DecParser = Dec(Filename)

    ## Transfer to Package Object
    #
    # Transfer all contents of a Dec file to a standard Package Object
    #
    def DecToPackage(self):
        #
        # Init global information for the file
        #
        ContainerFile = self.GetFullPath()

        #
        # Generate Package Header
        #
        self.GenPackageHeader(ContainerFile)

        #
        # Generate Includes
        #
        self.GenIncludes(ContainerFile)

        #
        # Generate Guids
        #
        self.GenGuidProtocolPpis(TAB_GUIDS, ContainerFile)

        #
        # Generate Protocols
        #
        self.GenGuidProtocolPpis(TAB_PROTOCOLS, ContainerFile)

        #
        # Generate Ppis
        #
        self.GenGuidProtocolPpis(TAB_PPIS, ContainerFile)

        #
        # Generate LibraryClasses
        #
        self.GenLibraryClasses(ContainerFile)

        #
        # Generate Pcds
        #
        self.GenPcds(ContainerFile)

        #
        # Generate Module File list, will be used later on to generate
        # distribution
        #
        self.GenModuleFileList(ContainerFile)

        #
        # Generate user extensions
        #
        self.GenUserExtensions()

    ## Generate user extension
    #
    #
    def GenUserExtensions(self):
        UEObj = self.DecParser.GetUserExtensionSectionObject()
        UEList = UEObj.GetAllUserExtensions()
        for Item in UEList:
            if not Item.UserString:
                continue
            UserExtension = UserExtensionObject()
            UserId = Item.UserId
            if UserId.startswith('"') and UserId.endswith('"'):
                UserId = UserId[1:-1]
            UserExtension.SetUserID(UserId)
            Identifier = Item.IdString
            if Identifier.startswith('"') and Identifier.endswith('"'):
                Identifier = Identifier[1:-1]
            #
            # Generate miscellaneous files of DEC file
            #
            if UserId == 'TianoCore' and Identifier == 'ExtraFiles':
                self.GenMiscFiles(Item.UserString)
            UserExtension.SetIdentifier(Identifier)
            UserExtension.SetStatement(Item.UserString)
            UserExtension.SetSupArchList(
                Item.ArchAndModuleType
            )
            self.SetUserExtensionList(
                self.GetUserExtensionList() + [UserExtension]
            )

        # Add Private sections to UserExtension
        if self.DecParser.GetPrivateSections():
            PrivateUserExtension = UserExtensionObject()
            PrivateUserExtension.SetStatement(self.DecParser.GetPrivateSections())
            PrivateUserExtension.SetIdentifier(DT.TAB_PRIVATE)
            PrivateUserExtension.SetUserID(DT.TAB_INTEL)
            self.SetUserExtensionList(self.GetUserExtensionList() + [PrivateUserExtension])

    ## Generate miscellaneous files on DEC file
    #
    #
    def GenMiscFiles(self, Content):
        MiscFileObj = MiscFileObject()
        for Line in Content.splitlines():
            FileName = ''
            if '#' in Line:
                FileName = Line[:Line.find('#')]
            else:
                FileName = Line
            if FileName:
                if IsValidPath(FileName, self.GetRelaPath()):
                    FileObj = FileObject()
                    FileObj.SetURI(FileName)
                    MiscFileObj.SetFileList(MiscFileObj.GetFileList()+[FileObj])
                else:
                    Logger.Error("InfParser",
                                 FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(Line),
                                 File=self.GetFileName(),
                                 ExtraData=Line)
        self.SetMiscFileList(self.GetMiscFileList()+[MiscFileObj])

    ## Generate Package Header
    #
    # Gen Package Header of Dec as <Key> = <Value>
    #
    # @param ContainerFile: The Dec file full path
    #
    def GenPackageHeader(self, ContainerFile):
        Logger.Debug(2, "Generate PackageHeader ...")
        DefinesDict = {}

        #
        # Update all defines item in database
        #
        DefObj = self.DecParser.GetDefineSectionObject()
        for Item in DefObj.GetDefines():
            #
            # put items into Dict except for PackageName, Guid, Version, DEC_SPECIFICATION
            #
            SkipItemList = [TAB_DEC_DEFINES_PACKAGE_NAME, \
                TAB_DEC_DEFINES_PACKAGE_GUID, TAB_DEC_DEFINES_PACKAGE_VERSION, \
                TAB_DEC_DEFINES_DEC_SPECIFICATION, TAB_DEC_DEFINES_PKG_UNI_FILE]
            if Item.Key in SkipItemList:
                continue
            DefinesDict['%s = %s' % (Item.Key, Item.Value)] = TAB_ARCH_COMMON

        self.SetBaseName(DefObj.GetPackageName())
        self.SetVersion(DefObj.GetPackageVersion())
#        self.SetName(DefObj.GetPackageName() + ' Version ' + \
#                     DefObj.GetPackageVersion())
        self.SetName(os.path.splitext(self.GetFileName())[0])
        self.SetGuid(DefObj.GetPackageGuid())
        if DefObj.GetPackageUniFile():
            ValidateUNIFilePath(DefObj.GetPackageUniFile())
            self.UniFileClassObject = \
            UniFileClassObject([PathClass(os.path.join(DefObj.GetPackagePath(), DefObj.GetPackageUniFile()))])
        else:
            self.UniFileClassObject = None

        if DefinesDict:
            UserExtension = UserExtensionObject()
            UserExtension.SetDefinesDict(DefinesDict)
            UserExtension.SetIdentifier('DefineModifiers')
            UserExtension.SetUserID('EDK2')
            self.SetUserExtensionList(
                self.GetUserExtensionList() + [UserExtension]
            )

        #
        # Get File header information
        #
        if self.UniFileClassObject:
            Lang = TAB_LANGUAGE_EN_X
        else:
            Lang = TAB_LANGUAGE_EN_US
        Abstract, Description, Copyright, License = \
            ParseHeaderCommentSection(self.DecParser.GetHeadComment(),
                                      ContainerFile)
        if Abstract:
            self.SetAbstract((Lang, Abstract))
        if Description:
            self.SetDescription((Lang, Description))
        if Copyright:
            self.SetCopyright(('', Copyright))
        if License:
            self.SetLicense(('', License))

        #
        # Get Binary header information
        #
        if self.DecParser.BinaryHeadComment:
            Abstract, Description, Copyright, License = \
                ParseHeaderCommentSection(self.DecParser.BinaryHeadComment,
                                      ContainerFile, True)

            if not Abstract  or not Description or not Copyright or not License:
                Logger.Error('MkPkg',
                             FORMAT_INVALID,
                             ST.ERR_INVALID_BINARYHEADER_FORMAT,
                             ContainerFile)
            else:
                self.SetBinaryHeaderAbstract((Lang, Abstract))
                self.SetBinaryHeaderDescription((Lang, Description))
                self.SetBinaryHeaderCopyright(('', Copyright))
                self.SetBinaryHeaderLicense(('', License))

        BinaryAbstractList = []
        BinaryDescriptionList = []

        #Get Binary header from UNI file
        # Initialize the UniStrDict dictionary, top keys are language codes
        UniStrDict = {}
        if self.UniFileClassObject:
            UniStrDict = self.UniFileClassObject.OrderedStringList
            for Lang in UniStrDict:
                for StringDefClassObject in UniStrDict[Lang]:
                    Lang = GetLanguageCode1766(Lang)
                    if StringDefClassObject.StringName == TAB_DEC_BINARY_ABSTRACT:
                        if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \
                        not in self.GetBinaryHeaderAbstract():
                            BinaryAbstractList.append((Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)))
                    if StringDefClassObject.StringName == TAB_DEC_BINARY_DESCRIPTION:
                        if (Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)) \
                        not in self.GetBinaryHeaderDescription():
                            BinaryDescriptionList.append((Lang,
                                                          ConvertSpecialUnicodes(StringDefClassObject.StringValue)))
        #Combine Binary header from DEC file and UNI file
        BinaryAbstractList = self.GetBinaryHeaderAbstract() + BinaryAbstractList
        BinaryDescriptionList = self.GetBinaryHeaderDescription() + BinaryDescriptionList
        BinaryCopyrightList = self.GetBinaryHeaderCopyright()
        BinaryLicenseList = self.GetBinaryHeaderLicense()
        #Generate the UserExtensionObject for TianoCore."BinaryHeader"
        if BinaryAbstractList or BinaryDescriptionList or BinaryCopyrightList or BinaryLicenseList:
            BinaryUserExtension = UserExtensionObject()
            BinaryUserExtension.SetBinaryAbstract(BinaryAbstractList)
            BinaryUserExtension.SetBinaryDescription(BinaryDescriptionList)
            BinaryUserExtension.SetBinaryCopyright(BinaryCopyrightList)
            BinaryUserExtension.SetBinaryLicense(BinaryLicenseList)
            BinaryUserExtension.SetIdentifier(TAB_BINARY_HEADER_IDENTIFIER)
            BinaryUserExtension.SetUserID(TAB_BINARY_HEADER_USERID)
            self.SetUserExtensionList(self.GetUserExtensionList() + [BinaryUserExtension])


    ## GenIncludes
    #
    # Gen Includes of Dec
    #
    # @param ContainerFile: The Dec file full path
    #
    def GenIncludes(self, ContainerFile):
        if ContainerFile:
            pass
        Logger.Debug(2, "Generate %s ..." % TAB_INCLUDES)
        IncludesDict = Sdict()

        IncObj = self.DecParser.GetIncludeSectionObject()
        for Item in IncObj.GetAllIncludes():
            IncludePath = os.path.normpath(Item.File)
            if platform.system() != 'Windows' and platform.system() != 'Microsoft':
                IncludePath = IncludePath.replace('\\', '/')
            if IncludePath in IncludesDict:
                if Item.GetArchList() == [TAB_ARCH_COMMON] or IncludesDict[IncludePath] == [TAB_ARCH_COMMON]:
                    IncludesDict[IncludePath] = [TAB_ARCH_COMMON]
                else:
                    IncludesDict[IncludePath] = IncludesDict[IncludePath] + Item.GetArchList()
            else:
                IncludesDict[IncludePath] = Item.GetArchList()

        #
        # get the  standardIncludeFileList(industry), packageIncludeFileList
        # (others) for PackageObject
        #
        PackagePath = os.path.split(self.GetFullPath())[0]
        IncludePathList = \
            sorted([os.path.normpath(Path) + sep for Path in IncludesDict.keys()])

        #
        # get a non-overlap set of include path, IncludePathList should be
        # sorted, and path should be end with path separator '\'
        #
        NonOverLapList = []
        for Path1 in IncludePathList:
            for Path2 in NonOverLapList:
                if Path1.startswith(Path2):
                    break
            else:
                NonOverLapList.append(Path1)
        #
        # revert the list so the longest path shown first in list, also need
        # to remove the extra path separator '\'
        # as this list is used to search the supported Arch info
        #
        for IndexN in range (0, len(IncludePathList)):
            IncludePathList[IndexN] = os.path.normpath(IncludePathList[IndexN])
        IncludePathList.sort()
        IncludePathList.reverse()
        #
        # save the include path list for later usage
        #
        self.SetIncludePathList(IncludePathList)
        StandardIncludeFileList = []
        PackageIncludeFileList = []

        IncludeFileList = []
        for Path in NonOverLapList:
            FileList = GetFiles(os.path.join(PackagePath, Path), ['CVS', '.svn'], False)
            IncludeFileList += [os.path.normpath(os.path.join(Path, File)) for File in FileList]
        for Includefile in IncludeFileList:
            ExtName = os.path.splitext(Includefile)[1]
            if ExtName.upper() == '.DEC' and self.CheckMulDec:
                Logger.Error('MkPkg',
                             UPT_MUL_DEC_ERROR,
                             ST.ERR_MUL_DEC_ERROR%(os.path.dirname(ContainerFile),
                                                   os.path.basename(ContainerFile),
                                                   Includefile))

            FileCombinePath = os.path.dirname(Includefile)
            Include = IncludeObject()
            for Path in IncludePathList:
                if FileCombinePath.startswith(Path):
                    SupArchList = IncludesDict[Path]
                    break
            Include.SetFilePath(Includefile)
            Include.SetSupArchList(SupArchList)
            if Includefile.find('IndustryStandard') != -1:
                StandardIncludeFileList.append(Include)
            else:
                PackageIncludeFileList.append(Include)

        self.SetStandardIncludeFileList(StandardIncludeFileList)

        #
        # put include path into the PackageIncludeFileList
        #
        PackagePathList = []
        IncObj = self.DecParser.GetIncludeSectionObject()
        for Item in IncObj.GetAllIncludes():
            IncludePath = Item.File
            Include = IncludeObject()
            Include.SetFilePath(IncludePath)
            Include.SetSupArchList(Item.GetArchList())
            PackagePathList.append(Include)
        self.SetPackageIncludeFileList(PackagePathList + PackageIncludeFileList)

    ## GenPpis
    #
    # Gen Ppis of Dec
    # <CName>=<GuidValue>
    #
    # @param ContainerFile: The Dec file full path
    #
    def GenGuidProtocolPpis(self, Type, ContainerFile):
        if ContainerFile:
            pass
        Logger.Debug(2, "Generate %s ..." % Type)

        Obj = None
        Factory = None
        if Type == TAB_GUIDS:
            Obj = self.DecParser.GetGuidSectionObject()
            def CreateGuidObject():
                Object = GuidObject()
                Object.SetGuidTypeList([])
                Object.SetUsage(None)
                Object.SetName(None)
                return Object
            Factory = CreateGuidObject
        elif Type == TAB_PROTOCOLS:
            Obj = self.DecParser.GetProtocolSectionObject()

            def CreateProtocolObject():
                return ProtocolObject()
            Factory = CreateProtocolObject
        elif Type == TAB_PPIS:
            Obj = self.DecParser.GetPpiSectionObject()

            def CreatePpiObject():
                return PpiObject()
            Factory = CreatePpiObject
        else:
            #
            # Should not be here
            #
            return

        DeclarationsList = []

        #
        # Go through each arch
        #
        for Item in Obj.GetGuidStyleAllItems():
            Name = Item.GuidCName
            Value = Item.GuidString
            HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
                                          Item.GetTailComment())

            ListObject = Factory()
            ListObject.SetCName(Name)
            ListObject.SetGuid(Value)
            ListObject.SetSupArchList(Item.GetArchList())
            if HelpTxt:
                if self.UniFileClassObject:
                    HelpTxt.SetLang(TAB_LANGUAGE_EN_X)
                ListObject.SetHelpTextList([HelpTxt])

            DeclarationsList.append(ListObject)

        #
        #GuidTypeList is abstracted from help
        #
        if Type == TAB_GUIDS:
            self.SetGuidList(self.GetGuidList() + DeclarationsList)
        elif Type == TAB_PROTOCOLS:
            self.SetProtocolList(self.GetProtocolList() + DeclarationsList)
        elif Type == TAB_PPIS:
            self.SetPpiList(self.GetPpiList() + DeclarationsList)

    ## GenLibraryClasses
    #
    # Gen LibraryClasses of Dec
    # <CName>=<GuidValue>
    #
    # @param ContainerFile: The Dec file full path
    #
    def GenLibraryClasses(self, ContainerFile):
        if ContainerFile:
            pass
        Logger.Debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)
        LibraryClassDeclarations = []

        LibObj = self.DecParser.GetLibraryClassSectionObject()
        for Item in LibObj.GetAllLibraryclasses():
            LibraryClass = LibraryClassObject()
            LibraryClass.SetLibraryClass(Item.Libraryclass)
            LibraryClass.SetSupArchList(Item.GetArchList())
            LibraryClass.SetIncludeHeader(Item.File)
            HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
                                          Item.GetTailComment(), None, '@libraryclass')
            if HelpTxt:
                if self.UniFileClassObject:
                    HelpTxt.SetLang(TAB_LANGUAGE_EN_X)
                LibraryClass.SetHelpTextList([HelpTxt])
            LibraryClassDeclarations.append(LibraryClass)

        self.SetLibraryClassList(self.GetLibraryClassList() + \
                                 LibraryClassDeclarations)

    ## GenPcds
    #
    # Gen Pcds of Dec
    # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
    #
    # @param ContainerFile: The Dec file full path
    #
    def GenPcds(self, ContainerFile):
        Logger.Debug(2, "Generate %s ..." % TAB_PCDS)
        PcdObj = self.DecParser.GetPcdSectionObject()
        #
        # Get all Pcds
        #
        PcdDeclarations = []
        IterList = [
            (TAB_PCDS_FIXED_AT_BUILD_NULL,      'FixedPcd'),
            (TAB_PCDS_PATCHABLE_IN_MODULE_NULL, 'PatchPcd'),
            (TAB_PCDS_FEATURE_FLAG_NULL,        'FeaturePcd'),
            (TAB_PCDS_DYNAMIC_EX_NULL,          'PcdEx'),
            (TAB_PCDS_DYNAMIC_NULL,             'Pcd')]

        PromptStrList = []
        HelpStrList = []
        PcdErrStrList = []
        # Initialize UniStrDict dictionary, top keys are language codes
        UniStrDict = {}
        StrList = []

        Language = ''
        if self.UniFileClassObject:
            Language = TAB_LANGUAGE_EN_X
        else:
            Language = TAB_LANGUAGE_EN_US

        if self.UniFileClassObject:
            UniStrDict = self.UniFileClassObject.OrderedStringList
            for Lang in UniStrDict:
                for StringDefClassObject in UniStrDict[Lang]:
                    StrList = StringDefClassObject.StringName.split('_')
                    # StringName format is STR_<TOKENSPACECNAME>_<PCDCNAME>_PROMPT
                    if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENPROMPT:
                        PromptStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
                                              StringDefClassObject.StringValue))
                    # StringName format is STR_<TOKENSPACECNAME>_<PCDCNAME>_HELP
                    if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[3] == TAB_STR_TOKENHELP:
                        HelpStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
                                            StringDefClassObject.StringValue))
                    # StringName format is STR_<TOKENSPACECNAME>_ERR_##
                    if len(StrList) == 4 and StrList[0] == TAB_STR_TOKENCNAME and StrList[2] == TAB_STR_TOKENERR:
                        PcdErrStrList.append((GetLanguageCode1766(Lang), StringDefClassObject.StringName, \
                                              StringDefClassObject.StringValue))
        #
        # For each PCD type
        #
        for PcdType, Type in IterList:
            #
            # Go through all archs
            #
            # for Arch in self.SupArchList + [TAB_ARCH_COMMON]:
            #
            for Item in PcdObj.GetPcdsByType(PcdType.upper()):
                PcdDeclaration = GenPcdDeclaration(
                        ContainerFile,
                        (Item.TokenSpaceGuidCName, Item.TokenCName,
                        Item.DefaultValue, Item.DatumType, Item.TokenValue,
                        Type, Item.GetHeadComment(), Item.GetTailComment(), ''),
                        Language,
                        self.DecParser.GetDefineSectionMacro()
                        )
                PcdDeclaration.SetSupArchList(Item.GetArchListOfType(PcdType))

                #
                # Get PCD error message from PCD error comment section in DEC file
                #
                for PcdErr in PcdDeclaration.GetPcdErrorsList():
                    if (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber()) \
                        in self.DecParser.PcdErrorCommentDict:
                        Key = (PcdDeclaration.GetTokenSpaceGuidCName(), PcdErr.GetErrorNumber())
                        PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \
                                                      [(Language, self.DecParser.PcdErrorCommentDict[Key])])

                for Index in range(0, len(PromptStrList)):
                    StrNameList = PromptStrList[Index][1].split('_')
                    if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
                    StrNameList[2].lower() == Item.TokenCName.lower():
                        TxtObj = TextObject()
                        TxtObj.SetLang(PromptStrList[Index][0])
                        TxtObj.SetString(PromptStrList[Index][2])
                        for Prompt in PcdDeclaration.GetPromptList():
                            if Prompt.GetLang() == TxtObj.GetLang() and \
                                Prompt.GetString() == TxtObj.GetString():
                                break
                        else:
                            PcdDeclaration.SetPromptList(PcdDeclaration.GetPromptList() + [TxtObj])

                for Index in range(0, len(HelpStrList)):
                    StrNameList = HelpStrList[Index][1].split('_')
                    if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
                    StrNameList[2].lower() == Item.TokenCName.lower():
                        TxtObj = TextObject()
                        TxtObj.SetLang(HelpStrList[Index][0])
                        TxtObj.SetString(HelpStrList[Index][2])
                        for HelpStrObj in PcdDeclaration.GetHelpTextList():
                            if HelpStrObj.GetLang() == TxtObj.GetLang() and \
                                HelpStrObj.GetString() == TxtObj.GetString():
                                break
                        else:
                            PcdDeclaration.SetHelpTextList(PcdDeclaration.GetHelpTextList() + [TxtObj])

                #
                # Get PCD error message from UNI file
                #
                for Index in range(0, len(PcdErrStrList)):
                    StrNameList = PcdErrStrList[Index][1].split('_')
                    if StrNameList[1].lower() == Item.TokenSpaceGuidCName.lower() and \
                        StrNameList[2].lower() == TAB_STR_TOKENERR.lower():
                        for PcdErr in PcdDeclaration.GetPcdErrorsList():
                            if PcdErr.GetErrorNumber().lower() == (TAB_HEX_START + StrNameList[3]).lower() and \
                                (PcdErrStrList[Index][0], PcdErrStrList[Index][2]) not in PcdErr.GetErrorMessageList():
                                PcdErr.SetErrorMessageList(PcdErr.GetErrorMessageList() + \
                                                            [(PcdErrStrList[Index][0], PcdErrStrList[Index][2])])

                #
                # Check to prevent missing error message if a Pcd has the error code.
                #
                for PcdErr in PcdDeclaration.GetPcdErrorsList():
                    if PcdErr.GetErrorNumber().strip():
                        if not PcdErr.GetErrorMessageList():
                            Logger.Error('UPT',
                                         FORMAT_INVALID,
                                         ST.ERR_DECPARSE_PCD_UNMATCHED_ERRORCODE % PcdErr.GetErrorNumber(),
                                         ContainerFile,
                                         PcdErr.GetLineNum(),
                                         PcdErr.GetFileLine())

                PcdDeclarations.append(PcdDeclaration)
        self.SetPcdList(self.GetPcdList() + PcdDeclarations)
        self.CheckPcdValue()

    ##
    # Get error message via language
    # @param ErrorMessageList: Error message tuple list the language and its message
    # @param Lang: the language of setting
    # @return: the error message described in the related UNI file
    def GetEnErrorMessage(self, ErrorMessageList):
        if self.FullPath:
            pass
        Lang = TAB_LANGUAGE_EN_US
        for (Language, Message) in ErrorMessageList:
            if Language == Lang:
                return Message
        for (Language, Message) in ErrorMessageList:
            if Language.find(TAB_LANGUAGE_EN) >= 0:
                return Message
        else:
            try:
                return ErrorMessageList[0][1]
            except IndexError:
                return ''
        return ''

    ##
    # Replace the strings for Python eval function.
    # @param ReplaceValue: The string that needs to be replaced.
    # @return: The string was replaced, then eval function is always making out it.
    def ReplaceForEval(self, ReplaceValue, IsRange=False, IsExpr=False):
        if self.FullPath:
            pass
        #
        # deal with "NOT EQ", "NOT LT", "NOT GT", "NOT LE", "NOT GE", "NOT NOT"
        #
        NOTNOT_Pattern = r'[\t\s]*NOT[\t\s]+NOT[\t\s]*'
        NOTGE_Pattern = r'[\t\s]*NOT[\t\s]+GE[\t\s]*'
        NOTLE_Pattern = r'[\t\s]*NOT[\t\s]+LE[\t\s]*'
        NOTGT_Pattern = r'[\t\s]*NOT[\t\s]+GT[\t\s]*'
        NOTLT_Pattern = r'[\t\s]*NOT[\t\s]+LT[\t\s]*'
        NOTEQ_Pattern = r'[\t\s]*NOT[\t\s]+EQ[\t\s]*'
        ReplaceValue = re.compile(NOTNOT_Pattern).sub('', ReplaceValue)
        ReplaceValue = re.compile(NOTLT_Pattern).sub('x >= ', ReplaceValue)
        ReplaceValue = re.compile(NOTGT_Pattern).sub('x <= ', ReplaceValue)
        ReplaceValue = re.compile(NOTLE_Pattern).sub('x > ', ReplaceValue)
        ReplaceValue = re.compile(NOTGE_Pattern).sub('x < ', ReplaceValue)
        ReplaceValue = re.compile(NOTEQ_Pattern).sub('x != ', ReplaceValue)

        if IsRange:
            ReplaceValue = ReplaceValue.replace('EQ', 'x ==')
            ReplaceValue = ReplaceValue.replace('LT', 'x <')
            ReplaceValue = ReplaceValue.replace('LE', 'x <=')
            ReplaceValue = ReplaceValue.replace('GT', 'x >')
            ReplaceValue = ReplaceValue.replace('GE', 'x >=')
            ReplaceValue = ReplaceValue.replace('XOR', 'x ^')
        elif IsExpr:
            ReplaceValue = ReplaceValue.replace('EQ', '==')
            ReplaceValue = ReplaceValue.replace('NE', '!=')
            ReplaceValue = ReplaceValue.replace('LT', '<')
            ReplaceValue = ReplaceValue.replace('LE', '<=')
            ReplaceValue = ReplaceValue.replace('GT', '>')
            ReplaceValue = ReplaceValue.replace('GE', '>=')
            ReplaceValue = ReplaceValue.replace('XOR', '^')

        ReplaceValue = ReplaceValue.replace('AND', 'and')
        ReplaceValue = ReplaceValue.replace('&&', ' and ')
        ReplaceValue = ReplaceValue.replace('xor', '^')
        ReplaceValue = ReplaceValue.replace('OR', 'or')
        ReplaceValue = ReplaceValue.replace('||', ' or ')
        ReplaceValue = ReplaceValue.replace('NOT', 'not')
        if ReplaceValue.find('!') >= 0 and ReplaceValue[ReplaceValue.index('!') + 1] != '=':
            ReplaceValue = ReplaceValue.replace('!', ' not ')
        if '.' in ReplaceValue:
            Pattern = r'[a-zA-Z0-9]{1,}\.[a-zA-Z0-9]{1,}'
            MatchedList = re.findall(Pattern, ReplaceValue)
            for MatchedItem in MatchedList:
                if MatchedItem not in self.PcdDefaultValueDict:
                    Logger.Error("Dec File Parser", FORMAT_INVALID, Message=ST.ERR_DECPARSE_PCD_NODEFINED % MatchedItem,
                                     File=self.FullPath)

                ReplaceValue = ReplaceValue.replace(MatchedItem, self.PcdDefaultValueDict[MatchedItem])

        return ReplaceValue

    ##
    # Check pcd's default value according to the pcd's description
    #
    def CheckPcdValue(self):
        for Pcd in self.GetPcdList():
            self.PcdDefaultValueDict[TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName())).strip()] = \
            Pcd.GetDefaultValue()

        for Pcd in self.GetPcdList():
            ValidationExpressions = []
            PcdGuidName = TAB_SPLIT.join((Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName()))
            Valids = Pcd.GetPcdErrorsList()
            for Valid in Valids:
                Expression = Valid.GetExpression()
                if Expression:
                    #
                    # Delete the 'L' prefix of a quoted string, this operation is for eval()
                    #
                    QUOTED_PATTERN = r'[\t\s]*L?"[^"]*"'
                    QuotedMatchedObj = re.search(QUOTED_PATTERN, Expression)
                    if QuotedMatchedObj:
                        MatchedStr = QuotedMatchedObj.group().strip()
                        if MatchedStr.startswith('L'):
                            Expression = Expression.replace(MatchedStr, MatchedStr[1:].strip())

                    Expression = self.ReplaceForEval(Expression, IsExpr=True)
                    Expression = Expression.replace(PcdGuidName, 'x')
                    Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
                    ValidationExpressions.append((Expression, Message))

                ValidList = Valid.GetValidValue()
                if ValidList:
                    ValidValue = 'x in %s' % [eval(v) for v in ValidList.split(' ') if v]
                    Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
                    ValidationExpressions.append((ValidValue, Message))

                ValidValueRange = Valid.GetValidValueRange()
                if ValidValueRange:
                    ValidValueRange = self.ReplaceForEval(ValidValueRange, IsRange=True)
                    if ValidValueRange.find('-') >= 0:
                        ValidValueRange = ValidValueRange.replace('-', '<= x <=')
                    elif not ValidValueRange.startswith('x ') and not ValidValueRange.startswith('not ') \
                        and not ValidValueRange.startswith('not(') and not ValidValueRange.startswith('('):
                        ValidValueRange = 'x %s' % ValidValueRange
                    Message = self.GetEnErrorMessage(Valid.GetErrorMessageList())
                    ValidationExpressions.append((ValidValueRange, Message))

            DefaultValue = self.PcdDefaultValueDict[PcdGuidName.strip()]
            #
            # Delete the 'L' prefix of a quoted string, this operation is for eval()
            #
            QUOTED_PATTERN = r'[\t\s]*L?"[^"]*"'
            QuotedMatchedObj = re.search(QUOTED_PATTERN, DefaultValue)
            if QuotedMatchedObj:
                MatchedStr = QuotedMatchedObj.group().strip()
                if MatchedStr.startswith('L'):
                    DefaultValue = DefaultValue.replace(MatchedStr, MatchedStr[1:].strip())

            try:
                DefaultValue = eval(DefaultValue.replace('TRUE', 'True').replace('true', 'True')
                                        .replace('FALSE', 'False').replace('false', 'False'))
            except BaseException:
                pass

            for (Expression, Msg) in ValidationExpressions:
                try:
                    if not eval(Expression, {'x':DefaultValue}):
                        Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData='%s, value = %s' %\
                                     (PcdGuidName, DefaultValue), Message=Msg, File=self.FullPath)
                except TypeError:
                    Logger.Error("Dec File Parser", FORMAT_INVALID, ExtraData=PcdGuidName, \
                                    Message=Msg, File=self.FullPath)

    ## GenModuleFileList
    #
    def GenModuleFileList(self, ContainerFile):
        ModuleFileList = []
        ContainerFileName = os.path.basename(ContainerFile)
        ContainerFilePath = os.path.dirname(ContainerFile)
        for Item in GetFiles(ContainerFilePath,
                        ['CVS', '.svn'] + self.GetIncludePathList(), False):
            ExtName = os.path.splitext(Item)[1]
            if ExtName.lower() == '.inf':
                ModuleFileList.append(Item)
            elif ExtName.upper() == '.DEC' and self.CheckMulDec:
                if Item == ContainerFileName:
                    continue
                Logger.Error('MkPkg',
                             UPT_MUL_DEC_ERROR,
                             ST.ERR_MUL_DEC_ERROR%(ContainerFilePath,
                                                   ContainerFileName,
                                                   Item))

        self.SetModuleFileList(ModuleFileList)

## GenPcdDeclaration
#
# @param ContainerFile:   File name of the DEC file
# @param PcdInfo:         Pcd information, of format (TokenGuidCName,
#                         TokenName, Value, DatumType, Token, Type,
#                         GenericComment, TailComment, Arch)
# @param Language: The language of HelpText, Prompt
#
def GenPcdDeclaration(ContainerFile, PcdInfo, Language, MacroReplaceDict):
    HelpStr = ''
    PromptStr = ''
    TailHelpStr = ''
    TokenGuidCName, TokenName, Value, DatumType, Token, Type, \
        GenericComment, TailComment, Arch = PcdInfo
    Pcd = PcdObject()
    Pcd.SetCName(TokenName)
    Pcd.SetToken(Token)
    Pcd.SetTokenSpaceGuidCName(TokenGuidCName)
    Pcd.SetDatumType(DatumType)
    Pcd.SetDefaultValue(Value)
    Pcd.SetValidUsage(Type)
    #
    #  MaxDatumSize is required field for 'VOID*' PCD
    #
    if DatumType == TAB_PTR_TYPE_PCD:
        Pcd.SetMaxDatumSize(ITEM_UNDEFINED)

    SupArchList = [Arch]
    Pcd.SetSupArchList(SupArchList)

    if GenericComment:
        HelpStr, PcdErrList, PromptStr = ParseDecPcdGenericComment(GenericComment,
                                                                   ContainerFile,
                                                                   TokenGuidCName,
                                                                   TokenName,
                                                                   MacroReplaceDict)
        if PcdErrList:
            Pcd.SetPcdErrorsList(PcdErrList)

    if TailComment:
        SupModuleList, TailHelpStr = ParseDecPcdTailComment(TailComment,
                                                        ContainerFile)
        if SupModuleList:
            Pcd.SetSupModuleList(SupModuleList)

    if HelpStr and (not HelpStr.endswith('\n')) and TailHelpStr:
        HelpStr += '\n'
    HelpStr += TailHelpStr
    if HelpStr:
        HelpTxtObj = TextObject()
        HelpTxtObj.SetLang(Language)
        HelpTxtObj.SetString(HelpStr)
        Pcd.SetHelpTextList([HelpTxtObj])
    if PromptStr:
        TxtObj = TextObject()
        TxtObj.SetLang(Language)
        TxtObj.SetString(PromptStr)
        Pcd.SetPromptList([TxtObj])

    return Pcd
