## @file InfPomAlignment.py
# This file contained the adapter for convert INF parser object to POM Object
#
# Copyright (c) 2011 - 2018, 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.
#
'''
InfPomAlignment
'''
##
# Import modules
#
import os.path
from Logger import StringTable as ST
import Logger.Log as Logger
from Library.StringUtils import FORMAT_INVALID
from Library.StringUtils import PARSER_ERROR
from Library.StringUtils import NormPath
from Library.StringUtils import GetSplitValueList
from Library.Misc import ConvertVersionToDecimal
from Library.Misc import GetHelpStringByRemoveHashKey
from Library.Misc import ConvertArchList
from Library.Misc import GetRelativePath
from Library.Misc import PathClass
from Library.Parsing import GetPkgInfoFromDec
from Library.UniClassObject import UniFileClassObject
from Library.UniClassObject import ConvertSpecialUnicodes
from Library.UniClassObject import GetLanguageCode1766
from Library import DataType as DT
from Library import GlobalData
from Library.ParserValidate import IsValidPath
from Object.POM import CommonObject
from Object.POM.ModuleObject import ModuleObject
from Object.POM.ModuleObject import ExternObject
from Object.POM.ModuleObject import HobObject
from Object.POM.ModuleObject import EventObject
from Object.POM.ModuleObject import BootModeObject
from Object.POM.ModuleObject import PackageDependencyObject
from Object.POM.ModuleObject import SourceFileObject
from Object.POM.ModuleObject import DepexObject
from Object.POM.ModuleObject import AsBuildLibraryClassObject
from Object.POM.ModuleObject import AsBuiltObject
from PomAdapter.InfPomAlignmentMisc import GenModuleHeaderUserExt
from PomAdapter.InfPomAlignmentMisc import GenBinaryData
from Parser import InfParser
from PomAdapter.DecPomAlignment import DecPomAlignment
from Common.MultipleWorkspace import MultipleWorkspace as mws

## InfPomAlignment
#
# Inherit from ModuleObject
#
class InfPomAlignment(ModuleObject):
    ## Construct of InfPomAlignment
    # Skip means that UPT don't care the syntax of INF, this may be the not 
    # distributed INF files during creation or the INF files checked for 
    # dependency rule during remove.
    #
    def __init__(self, FileName, WorkSpace=None, PackagePath='', Skip=False):
        ModuleObject.__init__(self)
        self.Parser = None
        self.FileName = FileName
        self.WorkSpace = WorkSpace
        self.CombinePath = ''
        self.LibModuleTypeList = []
        self.FullPath = ''
        self.ModulePath = ''
        self.WorkspaceDir = " "
        self.CustomMakefile = []
        self.UniFileClassObject = None
        self.SetPackagePath(PackagePath)
        #
        # Call GenInfPomObjects function to fill POM object.
        #
        if Skip:
            OrigConfig = Logger.SUPRESS_ERROR
            Logger.SUPRESS_ERROR = True
            try:
                self._GenInfPomObjects(Skip)
            finally:
                Logger.SUPRESS_ERROR = OrigConfig
        else:
            self._GenInfPomObjects(Skip)

    ##
    # Generate all POM objects, the original input comes 
    # from INF parser's output
    #
    def _GenInfPomObjects(self, Skip):
        #
        # Call INF Parser to get information from INF file  
        #
        self.Parser = InfParser.InfParser(self.FileName, self.WorkSpace)
        self.FullPath = self.Parser.FullPath
        self.GetFullPath()
        self._GenModuleHeader()
        #
        # Call GenBinaries after Module Header for Binary INF consideration.
        #
        self._GenBinaries()
        self._GenBuildOptions()
        self._GenLibraryClasses()
        self._GenPackages(Skip)
        self._GenPcds()
        self._GenSources()
        self._GenUserExtensions()
        self._GenGuidProtocolPpis(DT.TAB_GUIDS)
        self._GenGuidProtocolPpis(DT.TAB_PROTOCOLS)
        self._GenGuidProtocolPpis(DT.TAB_PPIS)
        self._GenDepexes()

    ## Convert [Defines] section content to InfDefObject
    #
    # Convert [Defines] section content to InfDefObject
    #
    # @param Defines        The content under [Defines] section
    # @param ModuleHeader   An object of ModuleHeaderClass
    # @param Arch           The supported ARCH
    #
    def _GenModuleHeader(self):
        Logger.Debug(2, "Generate ModuleHeader ...")
        #
        # Get all defines information form InfParser Object
        #
        RecordSet = self.Parser.InfDefSection.Defines
        #
        # Should only have one ArchString Item.
        #
        ArchString = RecordSet.keys()[0]
        ArchList = GetSplitValueList(ArchString, ' ')
        ArchList = ConvertArchList(ArchList)
        HasCalledFlag = False
        #
        # Get data from Sdict()
        #
        ValueList = RecordSet[ArchString]
        self.SetFileName(self.FileName)
        self.SetFullPath(self.FullPath)
        #
        # The INF's filename (without the directory path or the extension) 
        # must be used for the value of the 
        # ModuleSurfaceArea.Header.Name element
        #
        self.SetName(os.path.splitext(os.path.basename(self.FileName))[0])
        self.WorkspaceDir = " "
        #
        # CombinePath and ModulePath
        #
        CombinePath = GetRelativePath(self.FullPath, self.WorkSpace)
        self.SetCombinePath(CombinePath)
        ModulePath = os.path.split(CombinePath)[0]
        ModuleRelativePath = ModulePath
        if self.GetPackagePath() != '':
            ModuleRelativePath = GetRelativePath(ModulePath, self.GetPackagePath())
        self.SetModulePath(ModuleRelativePath)
        #
        # For Define Seciton Items.
        #
        DefineObj = ValueList
        #
        # Convert UEFI/PI version to decimal number
        #
        if DefineObj.GetUefiSpecificationVersion() is not None:
            __UefiVersion = DefineObj.GetUefiSpecificationVersion().GetValue()
            __UefiVersion = ConvertVersionToDecimal(__UefiVersion)
            self.SetUefiSpecificationVersion(str(__UefiVersion))
        if DefineObj.GetPiSpecificationVersion() is not None:
            __PiVersion = DefineObj.GetPiSpecificationVersion().GetValue()
            __PiVersion = ConvertVersionToDecimal(__PiVersion)

            self.SetPiSpecificationVersion(str(__PiVersion))
        SpecList = DefineObj.GetSpecification()
        NewSpecList = []
        for SpecItem in SpecList:
            NewSpecList.append((SpecItem[0], ConvertVersionToDecimal(SpecItem[1])))
        self.SetSpecList(NewSpecList)

        #
        # must exist items in INF define section
        # MODULE_TYPE/BASE_NAME/INF_VERSION/FILE_GUID/VERSION_STRING 
        #
        if DefineObj.GetModuleType() is None:
            Logger.Error("InfParser", FORMAT_INVALID,
                         ST.ERR_INF_PARSER_DEFINE_SECTION_MUST_ITEM_NOT_EXIST % ("MODULE_TYPE"), File=self.FullPath)
        else:
            self.SetModuleType(DefineObj.GetModuleType().GetValue())
            ModuleType = DefineObj.GetModuleType().GetValue()
            if ModuleType:
                #
                # Drivers and applications are not allowed to have a MODULE_TYPE of "BASE". Only 
                # libraries are permitted to a have a MODULE_TYPE of "BASE".
                #
                if len(DefineObj.LibraryClass) == 0 and ModuleType == 'BASE':
                    Logger.Error("InfParser",
                                 FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_MODULETYPE_INVALID,
                                 File=self.FullPath,
                                 Line=DefineObj.ModuleType.CurrentLine.LineNo,
                                 ExtraData=DefineObj.ModuleType.CurrentLine.LineString)
                self.LibModuleTypeList.append(ModuleType)
        if DefineObj.GetBaseName() is None:
            Logger.Error("InfParser", FORMAT_INVALID,
                         ST.ERR_INF_PARSER_DEFINE_SECTION_MUST_ITEM_NOT_EXIST % ("BASE_NAME"), File=self.FullPath)
        else:
            self.SetBaseName(DefineObj.GetBaseName().GetValue())
        if DefineObj.GetModuleUniFileName():
            self.UniFileClassObject = UniFileClassObject([PathClass(DefineObj.GetModuleUniFileName())])
        else:
            self.UniFileClassObject = None
        if DefineObj.GetInfVersion() is None:
            Logger.Error("InfParser", FORMAT_INVALID,
                         ST.ERR_INF_PARSER_DEFINE_SECTION_MUST_ITEM_NOT_EXIST % ("INF_VERSION"), File=self.FullPath)
        else:
            self.SetVersion(DefineObj.GetInfVersion().GetValue())
        if DefineObj.GetFileGuid() is None:
            Logger.Error("InfParser", FORMAT_INVALID,
                         ST.ERR_INF_PARSER_DEFINE_SECTION_MUST_ITEM_NOT_EXIST % ("FILE_GUID"), File=self.FullPath)
        else:
            self.SetGuid(DefineObj.GetFileGuid().GetValue())
        if DefineObj.GetVersionString() is None:
            #
            # VERSION_STRING is missing from the [Defines] section, tools must assume that the module's version is 0.
            #
            self.SetVersion('0')
        else:
            #
            # Get version of INF
            #
            if DefineObj.GetVersionString().GetValue() != "":
                #
                # EDK2 inf
                #
                VersionString = DefineObj.GetVersionString().GetValue()
                if len(VersionString) > 0:
                    VersionString = ConvertVersionToDecimal(VersionString)
                    self.SetVersion(VersionString)
            else:
                #
                # EDK1 inf
                #
                Logger.Error("Parser", PARSER_ERROR, ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF, ExtraData=self.FullPath,
                             RaiseError=Logger.IS_RAISE_ERROR)
        #
        # if there is Shadow, Should judge the MODULE_TYPE in 
        # SEC, PEI_CORE and PEIM
        #
        if DefineObj.GetShadow():
            ModuleTypeValue = DefineObj.GetModuleType().GetValue()
            if not (ModuleTypeValue == 'SEC' or ModuleTypeValue == 'PEI_CORE' or ModuleTypeValue == 'PEIM'):
                Logger.Error("InfParser", FORMAT_INVALID, ST.ERR_INF_PARSER_DEFINE_SHADOW_INVALID, File=self.FullPath)

        if DefineObj.GetPcdIsDriver() is not None:
            self.SetPcdIsDriver(DefineObj.GetPcdIsDriver().GetValue())
        #
        # LIBRARY_CLASS
        #
        self._GenModuleHeaderLibClass(DefineObj, ArchList)
        #
        # CUSTOM_MAKEFILE
        #
        self.CustomMakefile = DefineObj.GetCustomMakefile()
        #
        # Externs in Defines section
        # Only one define section, so just call once.
        #
        if not HasCalledFlag:
            self._GenModuleHeaderExterns(DefineObj)
            HasCalledFlag = True
        #
        # each module has only one module header
        #
        self.SetSupArchList(ArchList)
        #
        # Get Hob/BootMode/EventList information
        #
        self._GenSpecialComments()
        #
        # put all define statement into user-extension sections
        #     
        DefinesDictNew = GenModuleHeaderUserExt(DefineObj, ArchString)
        if DefinesDictNew:
            UserExtension = CommonObject.UserExtensionObject()
            UserExtension.SetDefinesDict(DefinesDictNew)
            UserExtension.SetIdentifier('DefineModifiers')
            UserExtension.SetUserID('EDK2')
            self.SetUserExtensionList(self.GetUserExtensionList() + [UserExtension])
        #
        # Get all meta-file header information
        # the record is list of items formated: 
        # [LineValue, Arch, StartLine, ID, Third]
        #
        InfHeaderObj = self.Parser.InfHeader
        #
        # Put header information into POM object
        #
        if self.UniFileClassObject:
            Lang = DT.TAB_LANGUAGE_EN_X
        else:
            Lang = DT.TAB_LANGUAGE_EN_US
        if InfHeaderObj.GetAbstract():
            self.SetAbstract((Lang, InfHeaderObj.GetAbstract()))
        if InfHeaderObj.GetDescription():
            self.SetDescription((Lang, InfHeaderObj.GetDescription()))
        if InfHeaderObj.GetCopyright():
            self.SetCopyright(('', InfHeaderObj.GetCopyright()))
        if InfHeaderObj.GetLicense():
            self.SetLicense(('', InfHeaderObj.GetLicense()))
        #
        # Put Binary header information into POM object
        #
        InfBinaryHeaderObj = self.Parser.InfBinaryHeader
        if InfBinaryHeaderObj.GetAbstract():
            self.SetBinaryHeaderAbstract((Lang, InfBinaryHeaderObj.GetAbstract()))
        if InfBinaryHeaderObj.GetDescription():
            self.SetBinaryHeaderDescription((Lang, InfBinaryHeaderObj.GetDescription()))
        if InfBinaryHeaderObj.GetCopyright():
            self.SetBinaryHeaderCopyright(('', InfBinaryHeaderObj.GetCopyright()))
        if InfBinaryHeaderObj.GetLicense():
            self.SetBinaryHeaderLicense(('', InfBinaryHeaderObj.GetLicense()))

    ## GenModuleHeaderLibClass
    #
    #
    def _GenModuleHeaderLibClass(self, DefineObj, ArchList):
        LibraryList = DefineObj.GetLibraryClass()
        for LibraryItem in LibraryList:
            Lib = CommonObject.LibraryClassObject()
            Lib.SetLibraryClass(LibraryItem.GetLibraryName())
            Lib.SetUsage(DT.USAGE_ITEM_PRODUCES)
            SupModuleList = LibraryItem.GetTypes()
            self.LibModuleTypeList += SupModuleList
            Lib.SetSupModuleList(SupModuleList)
            Lib.SetSupArchList(ArchList)
            self.SetLibraryClassList(self.GetLibraryClassList() + [Lib])
            self.SetIsLibrary(True)
            self.SetIsLibraryModList(self.GetIsLibraryModList() + SupModuleList)

    ## GenModuleHeaderExterns
    #
    #
    def _GenModuleHeaderExterns(self, DefineObj):
        EntryPointList = DefineObj.GetEntryPoint()
        for EntryPoint in EntryPointList:
            Image = ExternObject()
            Image.SetEntryPoint(EntryPoint.GetCName())
            #
            # Future enhancement
            #
            self.SetExternList(self.GetExternList() + [Image])
        #
        # UNLOAD_IMAGE
        # 
        UnloadImageList = DefineObj.GetUnloadImages()
        for UnloadImage in UnloadImageList:
            Image = ExternObject()
            #
            # Future enhancement
            #                
            Image.SetUnloadImage(UnloadImage.GetCName())
            self.SetExternList(self.GetExternList() + [Image])
        #
        # CONSTRUCTOR
        #
        ConstructorList = DefineObj.GetConstructor()
        for ConstructorItem in ConstructorList:
            Image = ExternObject()
            #
            # Future enhancement
            #                  
            Image.SetConstructor(ConstructorItem.GetCName())
            self.SetExternList(self.GetExternList() + [Image])
        #
        # DESTRUCTOR
        #
        DestructorList = DefineObj.GetDestructor()
        for DestructorItem in DestructorList:
            Image = ExternObject()
            #
            # Future enhancement
            #                
            Image.SetDestructor(DestructorItem.GetCName())
            self.SetExternList(self.GetExternList() + [Image])

    ## GenModuleHeaderExterns
    # BootMode/HOB/Event
    #
    def _GenSpecialComments(self):
        SpecialCommentsList = self.Parser.InfSpecialCommentSection.GetSpecialComments()
        for Key in SpecialCommentsList:
            if Key == DT.TYPE_HOB_SECTION:
                HobList = []
                for Item in SpecialCommentsList[Key]:
                    Hob = HobObject()
                    Hob.SetHobType(Item.GetHobType())
                    Hob.SetUsage(Item.GetUsage())
                    Hob.SetSupArchList(Item.GetSupArchList())
                    if Item.GetHelpString():
                        HelpTextObj = CommonObject.TextObject()
                        if self.UniFileClassObject:
                            HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X)
                        HelpTextObj.SetString(Item.GetHelpString())
                        Hob.SetHelpTextList([HelpTextObj])
                    HobList.append(Hob)
                self.SetHobList(HobList)
            elif Key == DT.TYPE_EVENT_SECTION:
                EventList = []
                for Item in SpecialCommentsList[Key]:
                    Event = EventObject()
                    Event.SetEventType(Item.GetEventType())
                    Event.SetUsage(Item.GetUsage())
                    if Item.GetHelpString():
                        HelpTextObj = CommonObject.TextObject()
                        if self.UniFileClassObject:
                            HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X)
                        HelpTextObj.SetString(Item.GetHelpString())
                        Event.SetHelpTextList([HelpTextObj])
                    EventList.append(Event)
                self.SetEventList(EventList)
            elif Key == DT.TYPE_BOOTMODE_SECTION:
                BootModeList = []
                for Item in SpecialCommentsList[Key]:
                    BootMode = BootModeObject()
                    BootMode.SetSupportedBootModes(Item.GetSupportedBootModes())
                    BootMode.SetUsage(Item.GetUsage())
                    if Item.GetHelpString():
                        HelpTextObj = CommonObject.TextObject()
                        if self.UniFileClassObject:
                            HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X)
                        HelpTextObj.SetString(Item.GetHelpString())
                        BootMode.SetHelpTextList([HelpTextObj])
                    BootModeList.append(BootMode)
                self.SetBootModeList(BootModeList)

    ## GenBuildOptions
    #
    # Gen BuildOptions of Inf
    # [<Family>:]<ToolFlag>=Flag
    #
    #
    def _GenBuildOptions(self):
        Logger.Debug(2, "Generate %s ..." % DT.TAB_BUILD_OPTIONS)
        #
        # Get all BuildOptions
        #
        BuildOptionsList = self.Parser.InfBuildOptionSection.GetBuildOptions()
        if not GlobalData.gIS_BINARY_INF:
            BuildOptionDict = {}
            for BuildOptionObj in BuildOptionsList:
                ArchList = BuildOptionObj.GetSupArchList()
                ArchList = ConvertArchList(ArchList)
                BuildOptionsContent = BuildOptionObj.GetContent()
                ArchString = ' '.join(ArchList)
                if not BuildOptionsContent:
                    continue
                BuildOptionDict[ArchString] = BuildOptionsContent
            if not BuildOptionDict:
                return
            UserExtension = CommonObject.UserExtensionObject()
            UserExtension.SetBuildOptionDict(BuildOptionDict)
            UserExtension.SetIdentifier('BuildOptionModifiers')
            UserExtension.SetUserID('EDK2')
            self.SetUserExtensionList(self.GetUserExtensionList() + [UserExtension])
        else:
            #
            # Not process this information, will be processed in GenBinaries()
            #
            pass

    ## GenLibraryClasses
    #
    # Get LibraryClass of Inf
    # <LibraryClassKeyWord>|<LibraryInstance>
    #
    # @param ContainerFile: The Inf file full path
    #
    def _GenLibraryClasses(self):
        Logger.Debug(2, "Generate %s ..." % DT.TAB_LIBRARY_CLASSES)
        if not GlobalData.gIS_BINARY_INF:
            #
            # Get all LibraryClasses
            #
            for LibraryClassData in self.Parser.InfLibraryClassSection.LibraryClasses.values():
                for Item in LibraryClassData:
                    LibraryClass = CommonObject.LibraryClassObject()
                    LibraryClass.SetUsage(DT.USAGE_ITEM_CONSUMES)
                    LibraryClass.SetLibraryClass(Item.GetLibName())
                    LibraryClass.SetRecommendedInstance(None)
                    LibraryClass.SetFeatureFlag(Item.GetFeatureFlagExp())
                    LibraryClass.SetSupArchList(ConvertArchList(Item.GetSupArchList()))
                    LibraryClass.SetSupModuleList(Item.GetSupModuleList())
                    HelpStringObj = Item.GetHelpString()
                    if HelpStringObj is not None:
                        CommentString = GetHelpStringByRemoveHashKey(HelpStringObj.HeaderComments +
                                                                     HelpStringObj.TailComments)
                        HelpTextHeaderObj = CommonObject.TextObject()
                        if self.UniFileClassObject:
                            HelpTextHeaderObj.SetLang(DT.TAB_LANGUAGE_EN_X)
                        HelpTextHeaderObj.SetString(CommentString)
                        LibraryClass.SetHelpTextList([HelpTextHeaderObj])
                    self.SetLibraryClassList(self.GetLibraryClassList() + [LibraryClass])

    ## GenPackages
    #
    # Gen Packages of Inf
    #
    #
    # @param ContainerFile: The Inf file full path
    #
    def _GenPackages(self, Skip):
        Logger.Debug(2, "Generate %s ..." % DT.TAB_PACKAGES)
        #
        # Get all Packages
        #
        PackageObj = self.Parser.InfPackageSection.Packages
        #
        # Go through each arch
        #
        for PackageItemObj in PackageObj:
            #
            # Need package information for dependency check usage
            #
            PackageDependency = PackageDependencyObject()
            PackageDependency.SetPackageFilePath(NormPath(PackageItemObj.GetPackageName()))
            PackageDependency.SetSupArchList(ConvertArchList(PackageItemObj.GetSupArchList()))
            PackageDependency.SetFeatureFlag(PackageItemObj.GetFeatureFlagExp())

            PkgInfo = GetPkgInfoFromDec(mws.join(self.WorkSpace, NormPath(PackageItemObj.GetPackageName())))
            if PkgInfo[1] and PkgInfo[2]:
                PackageDependency.SetGuid(PkgInfo[1])
                PackageDependency.SetVersion(PkgInfo[2])
            elif Skip:
                continue
            else:
                Logger.Error("\nUPT", PARSER_ERROR,
                             ST.ERR_INF_GET_PKG_DEPENDENCY_FAIL % PackageItemObj.GetPackageName(), File=self.FullPath)

            PackageDependencyList = self.GetPackageDependencyList()
            PackageDependencyList.append(PackageDependency)
            self.SetPackageDependencyList(PackageDependencyList)

    ## GenPcds
    #
    # Gen Pcds of Inf
    # <TokenSpaceGuidCName>.<PcdCName>[|<Value> [|<FFE>]]
    #
    # @param ContainerFile: The Inf file full path
    #
    def _GenPcds(self):
        if not GlobalData.gIS_BINARY_INF:
            Logger.Debug(2, "Generate %s ..." % DT.TAB_PCDS)
            #
            # Get all Pcds
            #
            PcdObj = self.Parser.InfPcdSection.Pcds
            KeysList = PcdObj.keys()
            #
            # Go through each arch
            #
            for (PcdType, PcdKey) in KeysList:
                PcdData = PcdObj[PcdType, PcdKey]
                for PcdItemObj in PcdData:
                    CommentList = PcdItemObj.GetHelpStringList()
                    if CommentList:
                        for CommentItem in CommentList:
                            Pcd = CommonObject.PcdObject()
                            Pcd.SetCName(PcdItemObj.GetCName())
                            Pcd.SetTokenSpaceGuidCName(PcdItemObj.GetTokenSpaceGuidCName())
                            Pcd.SetDefaultValue(PcdItemObj.GetDefaultValue())
                            Pcd.SetItemType(PcdType)
                            Pcd.SetValidUsage(CommentItem.GetUsageItem())
                            Pcd.SetFeatureFlag(PcdItemObj.GetFeatureFlagExp())
                            Pcd.SetSupArchList(ConvertArchList(PcdItemObj.GetSupportArchList()))
                            HelpTextObj = CommonObject.TextObject()
                            if self.UniFileClassObject:
                                HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X)
                            HelpTextObj.SetString(CommentItem.GetHelpStringItem())
                            Pcd.SetHelpTextList([HelpTextObj])
                            PcdList = self.GetPcdList()
                            PcdList.append(Pcd)
                self.SetPcdList(PcdList)

    ## GenSources
    #
    # Gen Sources of Inf
    # <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
    #
    # @param ContainerFile: The Inf file full path
    #
    def _GenSources(self):
        Logger.Debug(2, "Generate %s ..." % DT.TAB_SOURCES)

        #
        # Get all SourceFiles
        #
        SourceObj = self.Parser.InfSourcesSection.Sources
        DataList = SourceObj.keys()
        #
        # Go through each arch
        #
        SourceList = []
        for Key in DataList:
            SourceData = SourceObj[Key]
            for Item in SourceData:
                SourceFile = Item.GetSourceFileName()
                Family = Item.GetFamily()
                FeatureFlag = Item.GetFeatureFlagExp()
                SupArchList = sorted(ConvertArchList(Item.GetSupArchList()))
                Source = SourceFileObject()
                Source.SetSourceFile(SourceFile)
                Source.SetFamily(Family)
                Source.SetFeatureFlag(FeatureFlag)
                Source.SetSupArchList(SupArchList)
                SourceList.append(Source)

        self.SetSourceFileList(self.GetSourceFileList() + SourceList)


    ## GenUserExtensions
    #
    # Gen UserExtensions of Inf
    #
    def _GenUserExtensions(self):
        #
        # UserExtensions
        #
        UserExtensionObj = self.Parser.InfUserExtensionSection.UserExtension
        Keys = UserExtensionObj.keys()

        for Key in Keys:
            UserExtensionData = UserExtensionObj[Key]
            for UserExtensionDataObj in UserExtensionData:
                UserExtension = CommonObject.UserExtensionObject()
                UserId = UserExtensionDataObj.GetUserId()
                if UserId.startswith('"') and UserId.endswith('"'):
                    UserId = UserId[1:-1]                
                UserExtension.SetUserID(UserId)
                Identifier = UserExtensionDataObj.GetIdString()
                if Identifier.startswith('"') and Identifier.endswith('"'):
                    Identifier = Identifier[1:-1]
                #
                # Generate miscellaneous files on INF file
                #
                if UserId == 'TianoCore' and Identifier == 'ExtraFiles':
                    self._GenMiscFiles(UserExtensionDataObj.GetContent())
                UserExtension.SetIdentifier(Identifier)
                UserExtension.SetStatement(UserExtensionDataObj.GetContent())
                UserExtension.SetSupArchList(ConvertArchList(UserExtensionDataObj.GetSupArchList()))
                self.SetUserExtensionList(self.GetUserExtensionList() + [UserExtension])
                
        #
        #  Gen UserExtensions of TianoCore."BinaryHeader"
        #
        
        #Get Binary header from INF file
        BinaryAbstractList = self.BinaryHeaderAbstractList
        BinaryDescriptionList = self.BinaryHeaderDescriptionList
        BinaryCopyrightList = self.BinaryHeaderCopyrightList
        BinaryLicenseList = self.BinaryHeaderLicenseList
        #Get Binary header from UNI file
        # Initialize UniStrDict, the 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 == DT.TAB_INF_BINARY_ABSTRACT:
                        BinaryAbstractList.append((Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)))
                    if StringDefClassObject.StringName == DT.TAB_INF_BINARY_DESCRIPTION:
                        BinaryDescriptionList.append((Lang, ConvertSpecialUnicodes(StringDefClassObject.StringValue)))
        if BinaryAbstractList or BinaryDescriptionList or BinaryCopyrightList or BinaryLicenseList:
            BinaryUserExtension = CommonObject.UserExtensionObject()
            BinaryUserExtension.SetBinaryAbstract(BinaryAbstractList)
            BinaryUserExtension.SetBinaryDescription(BinaryDescriptionList)
            BinaryUserExtension.SetBinaryCopyright(BinaryCopyrightList)
            BinaryUserExtension.SetBinaryLicense(BinaryLicenseList)
            BinaryUserExtension.SetIdentifier(DT.TAB_BINARY_HEADER_IDENTIFIER)
            BinaryUserExtension.SetUserID(DT.TAB_BINARY_HEADER_USERID)
            self.SetUserExtensionList(self.GetUserExtensionList() + [BinaryUserExtension])
            
    def _GenDepexesList(self, SmmDepexList, DxeDepexList, PeiDepexList):
        if SmmDepexList:
            self.SetSmmDepex(SmmDepexList)
        if DxeDepexList:
            self.SetDxeDepex(DxeDepexList)
        if PeiDepexList:
            self.SetPeiDepex(PeiDepexList)

    ## GenDepexes
    #
    # Gen Depex of Inf
    #
    # @param ContainerFile: The Inf file full path
    #
    def _GenDepexes(self):
        Logger.Debug(2, "Generate %s ..." % DT.TAB_DEPEX)

        PEI_LIST = [DT.SUP_MODULE_PEIM]
        SMM_LIST = [DT.SUP_MODULE_DXE_SMM_DRIVER]
        DXE_LIST = [DT.SUP_MODULE_DXE_DRIVER, DT.SUP_MODULE_DXE_SAL_DRIVER,
                    DT.SUP_MODULE_DXE_RUNTIME_DRIVER]

        IsLibraryClass = self.GetIsLibrary()
        #
        # Get all Depexes
        #
        DepexData = self.Parser.InfDepexSection.GetDepex()
        SmmDepexList = []
        DxeDepexList = []
        PeiDepexList = []
        for Depex in DepexData:
            ModuleType = Depex.GetModuleType()
            ModuleTypeList = []
            if IsLibraryClass:
                if self.GetModuleType() == 'BASE' and not ModuleType:
                    Logger.Error("\nMkPkg", PARSER_ERROR,
                                 ST.ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_BASE_LIBRARY_CLASS,
                                 self.GetFullPath(), RaiseError=True)
                if self.GetModuleType() != 'BASE' and not self.GetIsLibraryModList():
                    Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_LIBRARY_CLASS,
                                 self.GetFullPath(), RaiseError=True)
                if self.GetModuleType() != 'BASE' and ModuleType and ModuleType not in self.GetIsLibraryModList():
                    Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_NOT_DETERMINED,
                                 self.GetFullPath(), RaiseError=True)
                if ModuleType:
                    ModuleTypeList = [ModuleType]
                else:
                    for ModuleTypeInList in self.GetIsLibraryModList():
                        if ModuleTypeInList in DT.VALID_DEPEX_MODULE_TYPE_LIST:
                            ModuleTypeList.append(ModuleTypeInList)
                if not ModuleTypeList:
                    Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_NOT_DETERMINED,
                                 self.GetFullPath(), RaiseError=True)
            else:
                if not ModuleType:
                    ModuleType = self.ModuleType
                if ModuleType not in DT.VALID_DEPEX_MODULE_TYPE_LIST:
                    Logger.Error("\nMkPkg", PARSER_ERROR,
                                 ST.ERR_INF_PARSER_DEPEX_SECTION_MODULE_TYPE_ERROR % (ModuleType),
                                 self.GetFullPath(), RaiseError=True)
                if ModuleType != self.ModuleType:
                    Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_NOT_DETERMINED,
                                 self.GetFullPath(), RaiseError=True)
                ModuleTypeList = [ModuleType]
            for ModuleType in ModuleTypeList:
                DepexIns = DepexObject()
                DepexIns.SetDepex(Depex.GetDepexContent())
                if IsLibraryClass:
                    DepexIns.SetModuleType(ModuleType)
                else:
                    if Depex.GetModuleType():
                        DepexIns.SetModuleType(Depex.GetModuleType())
                DepexIns.SetSupArchList(ConvertArchList([Depex.GetSupArch()]))
                DepexIns.SetFeatureFlag(Depex.GetFeatureFlagExp())
                if Depex.HelpString:
                    HelpIns = CommonObject.TextObject()
                    if self.UniFileClassObject:
                        HelpIns.SetLang(DT.TAB_LANGUAGE_EN_X)
                    HelpIns.SetString(GetHelpStringByRemoveHashKey(Depex.HelpString))
                    DepexIns.SetHelpText(HelpIns)

                if ModuleType in SMM_LIST:
                    SmmDepexList.append(DepexIns)
                if ModuleType in DXE_LIST:
                    DxeDepexList.append(DepexIns)
                if ModuleType in PEI_LIST:
                    PeiDepexList.append(DepexIns)
                if ModuleType == DT.SUP_MODULE_UEFI_DRIVER:
                    if IsLibraryClass:
                        DxeDepexList.append(DepexIns)
                    else:
                        Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_DRIVER,
                                     self.GetFullPath(), RaiseError=True)

            #End of for ModuleType in ModuleTypeList
            self._GenDepexesList(SmmDepexList, DxeDepexList, PeiDepexList)
        #End of for Depex in DepexData

    ## GenBinaries
    #
    # Gen Binary of Inf, must be called after Pcd/Library is generated
    # <FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]
    #
    # @param ContainerFile: The Inf file full path
    #
    def _GenBinaries(self):
        Logger.Debug(2, "Generate %s ..." % DT.TAB_BINARIES)
        BinariesDict = {}

        #
        # Get all Binary data
        #
        BinaryObj = self.Parser.InfBinariesSection.GetBinary()

        BinaryData = BinaryObj.keys()

        #
        # If the INF file does not contain a [Sources] section, and the INF file does contain a [Binaries] section, 
        # then the ModuleSurfaceArea.BinaryModule attribute must be set to true. Otherwise, do not use the attribute
        #
        if BinaryObj and not self.Parser.InfSourcesSection.GetSources():
            self.BinaryModule = True
        else:
            self.BinaryModule = False

        BinaryFileObjectList = []
        AsBuildLibraryClassList = []
        AsBuildBuildOptionList = []
        AsBuildIns = AsBuiltObject()
        #
        # Library AsBuild Info
        #
        for LibItem in self.Parser.InfLibraryClassSection.GetLibraryClasses():
            AsBuildLibIns = AsBuildLibraryClassObject()
            AsBuildLibIns.SetLibGuid(LibItem.GetFileGuid())
            AsBuildLibIns.SetLibVersion(LibItem.GetVersion())
            AsBuildLibIns.SetSupArchList(LibItem.GetSupArchList())
            AsBuildLibraryClassList.append(AsBuildLibIns)
        AsBuildIns.SetLibraryInstancesList(AsBuildLibraryClassList)

        #
        # BuildOption AsBuild Info
        #            
        for BuildOptionItem in self.Parser.InfBuildOptionSection.GetBuildOptions():
            AsBuildBuildOptionList.append(BuildOptionItem)
        AsBuildIns.SetBuildFlagsList(AsBuildBuildOptionList)

        #
        # PatchPcd and PcdEx
        #
        AsBuildIns = self._GenAsBuiltPcds(self.Parser.InfPcdSection.GetPcds(), AsBuildIns)

        #
        # Parse the DEC file that contains the GUID value of the GUID CName which is used by
        # SUBTYPE_GUID type binary file in the Binaries section in the INF file
        #
        DecObjList = []
        if not self.PackagePath:
            WorkSpace = os.path.normpath(self.WorkSpace)
            TempPath = ModulePath = os.path.normpath(self.ModulePath)
            while ModulePath:
                TempPath = ModulePath
                ModulePath = os.path.dirname(ModulePath)
            PackageName = TempPath
            DecFilePath = os.path.normpath(os.path.join(WorkSpace, PackageName))  
            if DecFilePath:
                for File in os.listdir(DecFilePath):
                    if File.upper().endswith('.DEC'):
                        DecFileFullPath = os.path.normpath(os.path.join(DecFilePath, File))
                        DecObjList.append(DecPomAlignment(DecFileFullPath, self.WorkSpace))
                        
        
        BinariesDict, AsBuildIns, BinaryFileObjectList = GenBinaryData(BinaryData, BinaryObj,
                                                                       BinariesDict,
                                                                       AsBuildIns,
                                                                       BinaryFileObjectList,
                                                                       self.GetSupArchList(),
                                                                       self.BinaryModule,
                                                                       DecObjList)
                
        BinariesDict2 = {}
        for Key in BinariesDict:
            ValueList = BinariesDict[Key]
            if len(ValueList) > 1:
                BinariesDict2[Key] = ValueList
            else:
                #
                # if there is no TagName, ToolCode, HelpStr, 
                # then do not need to put them into userextension
                #
                (Target, Family, TagName, HelpStr) = ValueList[0]
                if not (Target or Family or TagName or HelpStr):
                    continue
                else:
                    BinariesDict2[Key] = ValueList

        self.SetBinaryFileList(self.GetBinaryFileList() + BinaryFileObjectList)

        if BinariesDict2:
            UserExtension = CommonObject.UserExtensionObject()
            UserExtension.SetBinariesDict(BinariesDict2)
            UserExtension.SetIdentifier('BinaryFileModifiers')
            UserExtension.SetUserID('EDK2')
            self.SetUserExtensionList(self.GetUserExtensionList() + [UserExtension])

    ## GenAsBuiltPcds
    #
    #
    def _GenAsBuiltPcds(self, PcdList, AsBuildIns):
        AsBuildPatchPcdList = []
        AsBuildPcdExList = []
        #
        # Pcd AsBuild Info
        #
        for PcdItem in PcdList:
            if PcdItem[0].upper() == DT.TAB_INF_PATCH_PCD.upper():
                PcdItemObj = PcdItem[1]
                Pcd = CommonObject.PcdObject()
                Pcd.SetCName(PcdItemObj.GetCName())
                Pcd.SetTokenSpaceGuidCName(PcdItemObj.GetTokenSpaceGuidCName())
                if PcdItemObj.GetTokenSpaceGuidValue() == '' and self.BinaryModule:
                    Logger.Error("\nMkPkg",
                                 PARSER_ERROR,
                                 ST.ERR_ASBUILD_PCD_TOKENSPACE_GUID_VALUE_MISS % \
                                 (PcdItemObj.GetTokenSpaceGuidCName()),
                                 self.GetFullPath(), RaiseError=True)
                else:
                    Pcd.SetTokenSpaceGuidValue(PcdItemObj.GetTokenSpaceGuidValue())
                if (PcdItemObj.GetToken() == '' or PcdItemObj.GetDatumType() == '') and self.BinaryModule:
                    Logger.Error("\nMkPkg",
                                 PARSER_ERROR,
                                 ST.ERR_ASBUILD_PCD_DECLARITION_MISS % \
                                 (PcdItemObj.GetTokenSpaceGuidCName() + '.' + PcdItemObj.GetCName()),
                                 self.GetFullPath(), RaiseError=True)
                Pcd.SetToken(PcdItemObj.GetToken())
                Pcd.SetDatumType(PcdItemObj.GetDatumType())
                Pcd.SetMaxDatumSize(PcdItemObj.GetMaxDatumSize())
                Pcd.SetDefaultValue(PcdItemObj.GetDefaultValue())
                Pcd.SetOffset(PcdItemObj.GetOffset())
                Pcd.SetItemType(PcdItem[0])
                Pcd.SetFeatureFlag(PcdItemObj.GetFeatureFlagExp())
                Pcd.SetSupArchList(ConvertArchList(PcdItemObj.GetSupportArchList()))
                Pcd.SetValidUsage(PcdItemObj.GetValidUsage())
                for CommentItem in PcdItemObj.GetHelpStringList():
                    HelpTextObj = CommonObject.TextObject()
                    if self.UniFileClassObject:
                        HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X)
                    HelpTextObj.SetString(CommentItem.GetHelpStringItem())
                    Pcd.SetHelpTextList(Pcd.GetHelpTextList() + [HelpTextObj])
                AsBuildPatchPcdList.append(Pcd)
            elif PcdItem[0].upper() == DT.TAB_INF_PCD_EX.upper():
                PcdItemObj = PcdItem[1]
                Pcd = CommonObject.PcdObject()
                Pcd.SetTokenSpaceGuidValue(PcdItemObj.GetTokenSpaceGuidValue())
                Pcd.SetToken(PcdItemObj.GetToken())
                Pcd.SetDatumType(PcdItemObj.GetDatumType())
                Pcd.SetMaxDatumSize(PcdItemObj.GetMaxDatumSize())
                Pcd.SetDefaultValue(PcdItemObj.GetDefaultValue())
                Pcd.SetItemType(PcdItem[0])
                Pcd.SetFeatureFlag(PcdItemObj.GetFeatureFlagExp())
                Pcd.SetSupArchList(ConvertArchList(PcdItemObj.GetSupportArchList()))
                Pcd.SetValidUsage(PcdItemObj.GetValidUsage())
                for CommentItem in PcdItemObj.GetHelpStringList():
                    HelpTextObj = CommonObject.TextObject()
                    if self.UniFileClassObject:
                        HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X)
                    HelpTextObj.SetString(CommentItem.GetHelpStringItem())
                    Pcd.SetHelpTextList(Pcd.GetHelpTextList() + [HelpTextObj])
                AsBuildPcdExList.append(Pcd)
        AsBuildIns.SetPatchPcdList(AsBuildPatchPcdList)
        AsBuildIns.SetPcdExList(AsBuildPcdExList)

        return AsBuildIns

    ## GenGuidProtocolPpis
    #
    # Gen Guids/Protocol/Ppis of INF
    # <CName>=<GuidValue>
    #
    def _GenGuidProtocolPpis(self, Type):
        Logger.Debug(2, "Generate %s ..." % Type)
        #
        # Get all Guid/Protocol/Ppis data
        #
        GuidObj = self.Parser.InfGuidSection.GetGuid()
        ProtocolObj = self.Parser.InfProtocolSection.GetProtocol()
        PpisObj = self.Parser.InfPpiSection.GetPpi()

        GuidProtocolPpiList = []

        if Type == DT.TAB_GUIDS:
            GuidData = GuidObj.keys()
            for Item in GuidData:
                CommentList = Item.GetCommentList()
                #
                # Depend on CommentList content
                # generate muti-guid-obj
                #
                if CommentList:
                    for GuidComentItem in CommentList:
                        ListObject = CommonObject.GuidObject()
                        ListObject.SetGuidTypeList([GuidComentItem.GetGuidTypeItem()])
                        ListObject.SetVariableName(GuidComentItem.GetVariableNameItem())
                        ListObject.SetUsage(GuidComentItem.GetUsageItem())
                        ListObject.SetName(Item.GetName())
                        ListObject.SetCName(Item.GetName())
                        ListObject.SetSupArchList(ConvertArchList(Item.GetSupArchList()))
                        ListObject.SetFeatureFlag(Item.GetFeatureFlagExp())
                        HelpString = GuidComentItem.GetHelpStringItem()
                        if HelpString.strip():
                            HelpTxtTailObj = CommonObject.TextObject()
                            if self.UniFileClassObject:
                                HelpTxtTailObj.SetLang(DT.TAB_LANGUAGE_EN_X)
                            HelpTxtTailObj.SetString(HelpString)
                            ListObject.SetHelpTextList([HelpTxtTailObj])
                            
                        GuidProtocolPpiList.append(ListObject)
        elif Type == DT.TAB_PROTOCOLS:
            ProtocolData = ProtocolObj.keys()
            for Item in ProtocolData:
                CommentList = Item.GetCommentList()
                for CommentItem in CommentList:
                    ListObject = CommonObject.ProtocolObject()
                    ListObject.SetCName(Item.GetName())
                    ListObject.SetSupArchList(ConvertArchList(Item.GetSupArchList()))
                    ListObject.SetFeatureFlag(Item.GetFeatureFlagExp())
                    ListObject.SetNotify(CommentItem.GetNotify())
                    ListObject.SetUsage(CommentItem.GetUsageItem())
                    HelpString = CommentItem.GetHelpStringItem()
                    if HelpString.strip():
                        HelpTxtObj = CommonObject.TextObject()
                        if self.UniFileClassObject:
                            HelpTxtObj.SetLang(DT.TAB_LANGUAGE_EN_X)
                        HelpTxtObj.SetString(HelpString)
                        ListObject.SetHelpTextList([HelpTxtObj])
                    GuidProtocolPpiList.append(ListObject)
        elif Type == DT.TAB_PPIS:
            PpiData = PpisObj.keys()
            for Item in PpiData:
                CommentList = Item.GetCommentList()
                for CommentItem in CommentList:
                    ListObject = CommonObject.PpiObject()
                    ListObject.SetCName(Item.GetName())
                    ListObject.SetSupArchList(ConvertArchList(Item.GetSupArchList()))
                    ListObject.SetFeatureFlag(Item.GetFeatureFlagExp())
                    ListObject.SetNotify(CommentItem.GetNotify())
                    ListObject.SetUsage(CommentItem.GetUsage())
                    HelpString = CommentItem.GetHelpStringItem()
                    if HelpString.strip():
                        HelpTextObj = CommonObject.TextObject()
                        if self.UniFileClassObject:
                            HelpTextObj.SetLang(DT.TAB_LANGUAGE_EN_X)
                        HelpTextObj.SetString(HelpString)
                        ListObject.SetHelpTextList([HelpTextObj])
                    GuidProtocolPpiList.append(ListObject)

        if Type == DT.TAB_GUIDS:
            self.SetGuidList(self.GetGuidList() + GuidProtocolPpiList)
        elif Type == DT.TAB_PROTOCOLS:
            self.SetProtocolList(self.GetProtocolList() + GuidProtocolPpiList)
        elif Type == DT.TAB_PPIS:
            self.SetPpiList(self.GetPpiList() + GuidProtocolPpiList)

    ## GenMiscFiles
    #
    # Gen MiscellaneousFiles of Inf
    #
    # @param ContainerFile: The Inf file full path
    #
    def _GenMiscFiles(self, Content):
        MiscFileObj = CommonObject.MiscFileObject()
        for Line in Content.splitlines():
            FileName = ''
            if '#' in Line:
                FileName = Line[:Line.find('#')]
            else:
                FileName = Line
            if FileName:
                if IsValidPath(FileName, GlobalData.gINF_MODULE_DIR):
                    FileObj = CommonObject.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=GlobalData.gINF_MODULE_NAME,
                                 ExtraData=Line)   
        self.SetMiscFileList(self.GetMiscFileList()+[MiscFileObj]) 
        
