## @file
# parse FDF file
#
#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
#  Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
#
#  SPDX-License-Identifier: BSD-2-Clause-Patent
#

##
# Import Modules
#
from __future__ import print_function
from __future__ import absolute_import
from re import compile, DOTALL
from string import hexdigits
from uuid import UUID

from Common.BuildToolError import *
from Common import EdkLogger
from Common.Misc import PathClass, tdict, ProcessDuplicatedInf
from Common.StringUtils import NormPath, ReplaceMacro
from Common import GlobalData
from Common.Expression import *
from Common.DataType import *
from Common.MultipleWorkspace import MultipleWorkspace as mws
import Common.LongFilePathOs as os
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.RangeExpression import RangeExpression
from collections import OrderedDict

from .Fd import FD
from .Region import Region
from .Fv import FV
from .AprioriSection import AprioriSection
from .FfsInfStatement import FfsInfStatement
from .FfsFileStatement import FileStatement
from .VerSection import VerSection
from .UiSection import UiSection
from .FvImageSection import FvImageSection
from .DataSection import DataSection
from .DepexSection import DepexSection
from .CompressSection import CompressSection
from .GuidSection import GuidSection
from .Capsule import EFI_CERT_TYPE_PKCS7_GUID, EFI_CERT_TYPE_RSA2048_SHA256_GUID, Capsule
from .CapsuleData import CapsuleFfs, CapsulePayload, CapsuleFv, CapsuleFd, CapsuleAnyFile, CapsuleAfile
from .RuleComplexFile import RuleComplexFile
from .RuleSimpleFile import RuleSimpleFile
from .EfiSection import EfiSection
from .OptionRom import OPTIONROM
from .OptRomInfStatement import OptRomInfStatement, OverrideAttribs
from .OptRomFileStatement import OptRomFileStatement
from .GenFdsGlobalVariable import GenFdsGlobalVariable

T_CHAR_CR = '\r'
T_CHAR_TAB = '\t'
T_CHAR_DOUBLE_QUOTE = '\"'
T_CHAR_SINGLE_QUOTE = '\''
T_CHAR_BRACE_R = '}'

SEPARATORS = {TAB_EQUAL_SPLIT, TAB_VALUE_SPLIT, TAB_COMMA_SPLIT, '{', T_CHAR_BRACE_R}
ALIGNMENTS = {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",
                                    "256K", "512K", "1M", "2M", "4M", "8M", "16M"}
ALIGNMENT_NOAUTO = ALIGNMENTS - {"Auto"}
CR_LB_SET = {T_CHAR_CR, TAB_LINE_BREAK}

RegionSizePattern = compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
RegionSizeGuidPattern = compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
RegionOffsetPcdPattern = compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
ShortcutPcdPattern = compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
BaseAddrValuePattern = compile('^0[xX][0-9a-fA-F]+')
FileExtensionPattern = compile(r'([a-zA-Z][a-zA-Z0-9]*)')
TokenFindPattern = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
AllIncludeFileList = []

# Get the closest parent
def GetParentAtLine (Line):
    for Profile in AllIncludeFileList:
        if Profile.IsLineInFile(Line):
            return Profile
    return None

# Check include loop
def IsValidInclude (File, Line):
    for Profile in AllIncludeFileList:
        if Profile.IsLineInFile(Line) and Profile.FileName == File:
            return False

    return True

def GetRealFileLine (File, Line):
    InsertedLines = 0
    for Profile in AllIncludeFileList:
        if Profile.IsLineInFile(Line):
            return Profile.GetLineInFile(Line)
        elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1:
            InsertedLines += Profile.GetTotalLines()

    return (File, Line - InsertedLines)

## The exception class that used to report error messages when parsing FDF
#
# Currently the "ToolName" is set to be "FdfParser".
#
class Warning (Exception):
    ## The constructor
    #
    #   @param  self        The object pointer
    #   @param  Str         The message to record
    #   @param  File        The FDF name
    #   @param  Line        The Line number that error occurs
    #
    def __init__(self, Str, File = None, Line = None):
        FileLineTuple = GetRealFileLine(File, Line)
        self.FileName = FileLineTuple[0]
        self.LineNumber = FileLineTuple[1]
        self.OriginalLineNumber = Line
        self.Message = Str
        self.ToolName = 'FdfParser'

    def __str__(self):
        return self.Message

    # helper functions to facilitate consistency in warnings
    # each function is for a different common warning
    @staticmethod
    def Expected(Str, File, Line):
        return Warning("expected {}".format(Str), File, Line)
    @staticmethod
    def ExpectedEquals(File, Line):
        return Warning.Expected("'='", File, Line)
    @staticmethod
    def ExpectedCurlyOpen(File, Line):
        return Warning.Expected("'{'", File, Line)
    @staticmethod
    def ExpectedCurlyClose(File, Line):
        return Warning.Expected("'}'", File, Line)
    @staticmethod
    def ExpectedBracketClose(File, Line):
        return Warning.Expected("']'", File, Line)

## The Include file content class that used to record file data when parsing include file
#
# May raise Exception when opening file.
#
class IncludeFileProfile:
    ## The constructor
    #
    #   @param  self        The object pointer
    #   @param  FileName    The file that to be parsed
    #
    def __init__(self, FileName):
        self.FileName = FileName
        self.FileLinesList = []
        try:
            with open(FileName, "r") as fsock:
                self.FileLinesList = fsock.readlines()
                for index, line in enumerate(self.FileLinesList):
                    if not line.endswith(TAB_LINE_BREAK):
                        self.FileLinesList[index] += TAB_LINE_BREAK
        except:
            EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)

        self.InsertStartLineNumber = None
        self.InsertAdjust = 0
        self.IncludeFileList = []
        self.Level = 1 # first level include file

    def GetTotalLines(self):
        TotalLines = self.InsertAdjust + len(self.FileLinesList)

        for Profile in self.IncludeFileList:
            TotalLines += Profile.GetTotalLines()

        return TotalLines

    def IsLineInFile(self, Line):
        if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines():
            return True

        return False

    def GetLineInFile(self, Line):
        if not self.IsLineInFile (Line):
            return (self.FileName, -1)

        InsertedLines = self.InsertStartLineNumber

        for Profile in self.IncludeFileList:
            if Profile.IsLineInFile(Line):
                return Profile.GetLineInFile(Line)
            elif Line >= Profile.InsertStartLineNumber:
                InsertedLines += Profile.GetTotalLines()

        return (self.FileName, Line - InsertedLines + 1)

## The FDF content class that used to record file data when parsing FDF
#
# May raise Exception when opening file.
#
class FileProfile:
    ## The constructor
    #
    #   @param  self        The object pointer
    #   @param  FileName    The file that to be parsed
    #
    def __init__(self, FileName):
        self.FileLinesList = []
        try:
            with open(FileName, "r") as fsock:
                self.FileLinesList = fsock.readlines()

        except:
            EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)

        self.FileName = FileName
        self.PcdDict = OrderedDict()
        self.PcdLocalDict = OrderedDict()
        self.InfList = []
        self.InfDict = {'ArchTBD':[]}
        # ECC will use this Dict and List information
        self.PcdFileLineDict = {}
        self.InfFileLineList = []

        self.FdDict = {}
        self.FdNameNotSet = False
        self.FvDict = {}
        self.CapsuleDict = {}
        self.RuleDict = {}
        self.OptRomDict = {}
        self.FmpPayloadDict = {}

## The syntax parser for FDF
#
# PreprocessFile method should be called prior to ParseFile
# CycleReferenceCheck method can detect cycles in FDF contents
#
# GetNext*** procedures mean these procedures will get next token first, then make judgement.
# Get*** procedures mean these procedures will make judgement on current token only.
#
class FdfParser:
    ## The constructor
    #
    #   @param  self        The object pointer
    #   @param  FileName    The file that to be parsed
    #
    def __init__(self, FileName):
        self.Profile = FileProfile(FileName)
        self.FileName = FileName
        self.CurrentLineNumber = 1
        self.CurrentOffsetWithinLine = 0
        self.CurrentFdName = None
        self.CurrentFvName = None
        self._Token = ""
        self._SkippedChars = ""
        GlobalData.gFdfParser = self

        # Used to section info
        self._CurSection = []
        # Key: [section name, UI name, arch]
        # Value: {MACRO_NAME: MACRO_VALUE}
        self._MacroDict = tdict(True, 3)
        self._PcdDict = OrderedDict()

        self._WipeOffArea = []
        if GenFdsGlobalVariable.WorkSpaceDir == '':
            GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")

    ## _SkipWhiteSpace() method
    #
    #   Skip white spaces from current char.
    #
    #   @param  self        The object pointer
    #
    def _SkipWhiteSpace(self):
        while not self._EndOfFile():
            if self._CurrentChar() in {TAB_PRINTCHAR_NUL, T_CHAR_CR, TAB_LINE_BREAK, TAB_SPACE_SPLIT, T_CHAR_TAB}:
                self._SkippedChars += str(self._CurrentChar())
                self._GetOneChar()
            else:
                return
        return

    ## _EndOfFile() method
    #
    #   Judge current buffer pos is at file end
    #
    #   @param  self        The object pointer
    #   @retval True        Current File buffer position is at file end
    #   @retval False       Current File buffer position is NOT at file end
    #
    def _EndOfFile(self):
        NumberOfLines = len(self.Profile.FileLinesList)
        SizeOfLastLine = len(self.Profile.FileLinesList[-1])
        if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:
            return True
        if self.CurrentLineNumber > NumberOfLines:
            return True
        return False

    ## _EndOfLine() method
    #
    #   Judge current buffer pos is at line end
    #
    #   @param  self        The object pointer
    #   @retval True        Current File buffer position is at line end
    #   @retval False       Current File buffer position is NOT at line end
    #
    def _EndOfLine(self):
        if self.CurrentLineNumber > len(self.Profile.FileLinesList):
            return True
        SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
        if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:
            return True
        return False

    ## Rewind() method
    #
    #   Reset file data buffer to the initial state
    #
    #   @param  self        The object pointer
    #   @param  DestLine    Optional new destination line number.
    #   @param  DestOffset  Optional new destination offset.
    #
    def Rewind(self, DestLine = 1, DestOffset = 0):
        self.CurrentLineNumber = DestLine
        self.CurrentOffsetWithinLine = DestOffset

    ## _UndoOneChar() method
    #
    #   Go back one char in the file buffer
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully go back one char
    #   @retval False       Not able to go back one char as file beginning reached
    #
    def _UndoOneChar(self):
        if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:
            return False
        elif self.CurrentOffsetWithinLine == 0:
            self.CurrentLineNumber -= 1
            self.CurrentOffsetWithinLine = len(self._CurrentLine()) - 1
        else:
            self.CurrentOffsetWithinLine -= 1
        return True

    ## _GetOneChar() method
    #
    #   Move forward one char in the file buffer
    #
    #   @param  self        The object pointer
    #
    def _GetOneChar(self):
        if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
            self.CurrentLineNumber += 1
            self.CurrentOffsetWithinLine = 0
        else:
            self.CurrentOffsetWithinLine += 1

    ## _CurrentChar() method
    #
    #   Get the char pointed to by the file buffer pointer
    #
    #   @param  self        The object pointer
    #   @retval Char        Current char
    #
    def _CurrentChar(self):
        return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]

    ## _NextChar() method
    #
    #   Get the one char pass the char pointed to by the file buffer pointer
    #
    #   @param  self        The object pointer
    #   @retval Char        Next char
    #
    def _NextChar(self):
        if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
            return self.Profile.FileLinesList[self.CurrentLineNumber][0]
        return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]

    ## _SetCurrentCharValue() method
    #
    #   Modify the value of current char
    #
    #   @param  self        The object pointer
    #   @param  Value       The new value of current char
    #
    def _SetCurrentCharValue(self, Value):
        self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value

    ## _CurrentLine() method
    #
    #   Get the list that contains current line contents
    #
    #   @param  self        The object pointer
    #   @retval List        current line contents
    #
    def _CurrentLine(self):
        return self.Profile.FileLinesList[self.CurrentLineNumber - 1]

    def _StringToList(self):
        self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]
        if not self.Profile.FileLinesList:
            EdkLogger.error('FdfParser', FILE_READ_FAILURE, 'The file is empty!', File=self.FileName)
        self.Profile.FileLinesList[-1].append(' ')

    def _ReplaceFragment(self, StartPos, EndPos, Value = ' '):
        if StartPos[0] == EndPos[0]:
            Offset = StartPos[1]
            while Offset <= EndPos[1]:
                self.Profile.FileLinesList[StartPos[0]][Offset] = Value
                Offset += 1
            return

        Offset = StartPos[1]
        while self.Profile.FileLinesList[StartPos[0]][Offset] not in CR_LB_SET:
            self.Profile.FileLinesList[StartPos[0]][Offset] = Value
            Offset += 1

        Line = StartPos[0]
        while Line < EndPos[0]:
            Offset = 0
            while self.Profile.FileLinesList[Line][Offset] not in CR_LB_SET:
                self.Profile.FileLinesList[Line][Offset] = Value
                Offset += 1
            Line += 1

        Offset = 0
        while Offset <= EndPos[1]:
            self.Profile.FileLinesList[EndPos[0]][Offset] = Value
            Offset += 1

    def _SetMacroValue(self, Macro, Value):
        if not self._CurSection:
            return

        MacroDict = {}
        if not self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]]:
            self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]] = MacroDict
        else:
            MacroDict = self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]]
        MacroDict[Macro] = Value

    def _GetMacroValue(self, Macro):
        # Highest priority
        if Macro in GlobalData.gCommandLineDefines:
            return GlobalData.gCommandLineDefines[Macro]
        if Macro in GlobalData.gGlobalDefines:
            return GlobalData.gGlobalDefines[Macro]

        if self._CurSection:
            MacroDict = self._MacroDict[
                        self._CurSection[0],
                        self._CurSection[1],
                        self._CurSection[2]
            ]
            if MacroDict and Macro in MacroDict:
                return MacroDict[Macro]

        # Lowest priority
        if Macro in GlobalData.gPlatformDefines:
            return GlobalData.gPlatformDefines[Macro]
        return None

    def _SectionHeaderParser(self, Section):
        # [Defines]
        # [FD.UiName]: use dummy instead if UI name is optional
        # [FV.UiName]
        # [Capsule.UiName]
        # [Rule]: don't take rule section into account, macro is not allowed in this section
        # [OptionRom.DriverName]
        self._CurSection = []
        Section = Section.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT)
        ItemList = Section.split(TAB_SPLIT)
        Item = ItemList[0]
        if Item == '' or Item == 'RULE':
            return

        if Item == TAB_COMMON_DEFINES.upper():
            self._CurSection = [TAB_COMMON, TAB_COMMON, TAB_COMMON]
        elif len(ItemList) > 1:
            self._CurSection = [ItemList[0], ItemList[1], TAB_COMMON]
        elif len(ItemList) > 0:
            self._CurSection = [ItemList[0], 'DUMMY', TAB_COMMON]

    ## PreprocessFile() method
    #
    #   Preprocess file contents, replace comments with spaces.
    #   In the end, rewind the file buffer pointer to the beginning
    #   BUGBUG: No !include statement processing contained in this procedure
    #   !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
    #
    #   @param  self        The object pointer
    #
    def PreprocessFile(self):
        self.Rewind()
        InComment = False
        DoubleSlashComment = False
        HashComment = False
        # HashComment in quoted string " " is ignored.
        InString = False

        while not self._EndOfFile():

            if self._CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:
                InString = not InString
            # meet new line, then no longer in a comment for // and '#'
            if self._CurrentChar() == TAB_LINE_BREAK:
                self.CurrentLineNumber += 1
                self.CurrentOffsetWithinLine = 0
                if InComment and DoubleSlashComment:
                    InComment = False
                    DoubleSlashComment = False
                if InComment and HashComment:
                    InComment = False
                    HashComment = False
            # check for */ comment end
            elif InComment and not DoubleSlashComment and not HashComment and self._CurrentChar() == TAB_STAR and self._NextChar() == TAB_BACK_SLASH:
                self._SetCurrentCharValue(TAB_SPACE_SPLIT)
                self._GetOneChar()
                self._SetCurrentCharValue(TAB_SPACE_SPLIT)
                self._GetOneChar()
                InComment = False
            # set comments to spaces
            elif InComment:
                self._SetCurrentCharValue(TAB_SPACE_SPLIT)
                self._GetOneChar()
            # check for // comment
            elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == TAB_BACK_SLASH and not self._EndOfLine():
                InComment = True
                DoubleSlashComment = True
            # check for '#' comment
            elif self._CurrentChar() == TAB_COMMENT_SPLIT and not self._EndOfLine() and not InString:
                InComment = True
                HashComment = True
            # check for /* comment start
            elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == TAB_STAR:
                self._SetCurrentCharValue(TAB_SPACE_SPLIT)
                self._GetOneChar()
                self._SetCurrentCharValue(TAB_SPACE_SPLIT)
                self._GetOneChar()
                InComment = True
            else:
                self._GetOneChar()

        # restore from ListOfList to ListOfString
        self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
        self.Rewind()

    ## PreprocessIncludeFile() method
    #
    #   Preprocess file contents, replace !include statements with file contents.
    #   In the end, rewind the file buffer pointer to the beginning
    #
    #   @param  self        The object pointer
    #
    def PreprocessIncludeFile(self):
      # nested include support
        Processed = False
        MacroDict = {}
        while self._GetNextToken():

            if self._Token == TAB_DEFINE:
                if not self._GetNextToken():
                    raise Warning.Expected("Macro name", self.FileName, self.CurrentLineNumber)
                Macro = self._Token
                if not self._IsToken(TAB_EQUAL_SPLIT):
                    raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                Value = self._GetExpression()
                MacroDict[Macro] = Value

            elif self._Token == TAB_INCLUDE:
                Processed = True
                IncludeLine = self.CurrentLineNumber
                IncludeOffset = self.CurrentOffsetWithinLine - len(TAB_INCLUDE)
                if not self._GetNextToken():
                    raise Warning.Expected("include file name", self.FileName, self.CurrentLineNumber)
                IncFileName = self._Token
                PreIndex = 0
                StartPos = IncFileName.find('$(', PreIndex)
                EndPos = IncFileName.find(')', StartPos+2)
                while StartPos != -1 and EndPos != -1:
                    Macro = IncFileName[StartPos+2: EndPos]
                    MacroVal = self._GetMacroValue(Macro)
                    if not MacroVal:
                        if Macro in MacroDict:
                            MacroVal = MacroDict[Macro]
                    if MacroVal is not None:
                        IncFileName = IncFileName.replace('$(' + Macro + ')', MacroVal, 1)
                        if MacroVal.find('$(') != -1:
                            PreIndex = StartPos
                        else:
                            PreIndex = StartPos + len(MacroVal)
                    else:
                        raise Warning("The Macro %s is not defined" %Macro, self.FileName, self.CurrentLineNumber)
                    StartPos = IncFileName.find('$(', PreIndex)
                    EndPos = IncFileName.find(')', StartPos+2)

                IncludedFile = NormPath(IncFileName)
                #
                # First search the include file under the same directory as FDF file
                #
                IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName))
                ErrorCode = IncludedFile1.Validate()[0]
                if ErrorCode != 0:
                    #
                    # Then search the include file under the same directory as DSC file
                    #
                    PlatformDir = ''
                    if GenFdsGlobalVariable.ActivePlatform:
                        PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir
                    elif GlobalData.gActivePlatform:
                        PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir
                    IncludedFile1 = PathClass(IncludedFile, PlatformDir)
                    ErrorCode = IncludedFile1.Validate()[0]
                    if ErrorCode != 0:
                        #
                        # Also search file under the WORKSPACE directory
                        #
                        IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)
                        ErrorCode = IncludedFile1.Validate()[0]
                        if ErrorCode != 0:
                            raise Warning("The include file does not exist under below directories: \n%s\n%s\n%s\n"%(os.path.dirname(self.FileName), PlatformDir, GlobalData.gWorkspace),
                                          self.FileName, self.CurrentLineNumber)

                if not IsValidInclude (IncludedFile1.Path, self.CurrentLineNumber):
                    raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1.Path), self.FileName, self.CurrentLineNumber)

                IncFileProfile = IncludeFileProfile(IncludedFile1.Path)

                CurrentLine = self.CurrentLineNumber
                CurrentOffset = self.CurrentOffsetWithinLine
                # list index of the insertion, note that line number is 'CurrentLine + 1'
                InsertAtLine = CurrentLine
                ParentProfile = GetParentAtLine (CurrentLine)
                if ParentProfile is not None:
                    ParentProfile.IncludeFileList.insert(0, IncFileProfile)
                    IncFileProfile.Level = ParentProfile.Level + 1
                IncFileProfile.InsertStartLineNumber = InsertAtLine + 1
                # deal with remaining portions after "!include filename", if exists.
                if self._GetNextToken():
                    if self.CurrentLineNumber == CurrentLine:
                        RemainingLine = self._CurrentLine()[CurrentOffset:]
                        self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)
                        IncFileProfile.InsertAdjust += 1
                        self.CurrentLineNumber += 1
                        self.CurrentOffsetWithinLine = 0

                for Line in IncFileProfile.FileLinesList:
                    self.Profile.FileLinesList.insert(InsertAtLine, Line)
                    self.CurrentLineNumber += 1
                    InsertAtLine += 1

                # reversely sorted to better determine error in file
                AllIncludeFileList.insert(0, IncFileProfile)

                # comment out the processed include file statement
                TempList = list(self.Profile.FileLinesList[IncludeLine - 1])
                TempList.insert(IncludeOffset, TAB_COMMENT_SPLIT)
                self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
            if Processed: # Nested and back-to-back support
                self.Rewind(DestLine = IncFileProfile.InsertStartLineNumber - 1)
                Processed = False
        # Preprocess done.
        self.Rewind()

    @staticmethod
    def _GetIfListCurrentItemStat(IfList):
        if len(IfList) == 0:
            return True

        for Item in IfList:
            if Item[1] == False:
                return False

        return True

    ## PreprocessConditionalStatement() method
    #
    #   Preprocess conditional statement.
    #   In the end, rewind the file buffer pointer to the beginning
    #
    #   @param  self        The object pointer
    #
    def PreprocessConditionalStatement(self):
        # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
        IfList = []
        RegionLayoutLine = 0
        ReplacedLine = -1
        while self._GetNextToken():
            # Determine section name and the location dependent macro
            if self._GetIfListCurrentItemStat(IfList):
                if self._Token.startswith(TAB_SECTION_START):
                    Header = self._Token
                    if not self._Token.endswith(TAB_SECTION_END):
                        self._SkipToToken(TAB_SECTION_END)
                        Header += self._SkippedChars
                    if Header.find('$(') != -1:
                        raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber)
                    self._SectionHeaderParser(Header)
                    continue
                # Replace macros except in RULE section or out of section
                elif self._CurSection and ReplacedLine != self.CurrentLineNumber:
                    ReplacedLine = self.CurrentLineNumber
                    self._UndoToken()
                    CurLine = self.Profile.FileLinesList[ReplacedLine - 1]
                    PreIndex = 0
                    StartPos = CurLine.find('$(', PreIndex)
                    EndPos = CurLine.find(')', StartPos+2)
                    while StartPos != -1 and EndPos != -1 and self._Token not in {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF, TAB_ELSE_IF}:
                        MacroName = CurLine[StartPos+2: EndPos]
                        MacroValue = self._GetMacroValue(MacroName)
                        if MacroValue is not None:
                            CurLine = CurLine.replace('$(' + MacroName + ')', MacroValue, 1)
                            if MacroValue.find('$(') != -1:
                                PreIndex = StartPos
                            else:
                                PreIndex = StartPos + len(MacroValue)
                        else:
                            PreIndex = EndPos + 1
                        StartPos = CurLine.find('$(', PreIndex)
                        EndPos = CurLine.find(')', StartPos+2)
                    self.Profile.FileLinesList[ReplacedLine - 1] = CurLine
                    continue

            if self._Token == TAB_DEFINE:
                if self._GetIfListCurrentItemStat(IfList):
                    if not self._CurSection:
                        raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber)
                    DefineLine = self.CurrentLineNumber - 1
                    DefineOffset = self.CurrentOffsetWithinLine - len(TAB_DEFINE)
                    if not self._GetNextToken():
                        raise Warning.Expected("Macro name", self.FileName, self.CurrentLineNumber)
                    Macro = self._Token
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

                    Value = self._GetExpression()
                    self._SetMacroValue(Macro, Value)
                    self._WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
            elif self._Token == 'SET':
                if not self._GetIfListCurrentItemStat(IfList):
                    continue
                SetLine = self.CurrentLineNumber - 1
                SetOffset = self.CurrentOffsetWithinLine - len('SET')
                PcdPair = self._GetNextPcdSettings()
                PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])
                if not self._IsToken(TAB_EQUAL_SPLIT):
                    raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

                Value = self._GetExpression()
                Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)

                self._PcdDict[PcdName] = Value

                self.Profile.PcdDict[PcdPair] = Value
                self.SetPcdLocalation(PcdPair)
                FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple

                self._WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
            elif self._Token in {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF}:
                IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self._Token))
                IfList.append([IfStartPos, None, None])

                CondLabel = self._Token
                Expression = self._GetExpression()

                if CondLabel == TAB_IF:
                    ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
                else:
                    ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')
                    if CondLabel == TAB_IF_N_DEF:
                        ConditionSatisfied = not ConditionSatisfied

                BranchDetermined = ConditionSatisfied
                IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
                if ConditionSatisfied:
                    self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
            elif self._Token in {TAB_ELSE_IF, TAB_ELSE}:
                ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self._Token))
                if len(IfList) <= 0:
                    raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)

                if IfList[-1][1]:
                    IfList[-1] = [ElseStartPos, False, True]
                    self._WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
                else:
                    self._WipeOffArea.append((IfList[-1][0], ElseStartPos))
                    IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
                    if self._Token == TAB_ELSE_IF:
                        Expression = self._GetExpression()
                        ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
                        IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]

                    if IfList[-1][1]:
                        if IfList[-1][2]:
                            IfList[-1][1] = False
                        else:
                            IfList[-1][2] = True
                            self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
            elif self._Token == '!endif':
                if len(IfList) <= 0:
                    raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
                if IfList[-1][1]:
                    self._WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
                else:
                    self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))

                IfList.pop()
            elif not IfList:    # Don't use PCDs inside conditional directive
                if self.CurrentLineNumber <= RegionLayoutLine:
                    # Don't try the same line twice
                    continue
                SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
                if SetPcd:
                    self._PcdDict[SetPcd.group('name')] = SetPcd.group('value')
                    RegionLayoutLine = self.CurrentLineNumber
                    continue
                RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
                if not RegionSize:
                    RegionLayoutLine = self.CurrentLineNumber
                    continue
                RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])
                if not RegionSizeGuid:
                    RegionLayoutLine = self.CurrentLineNumber + 1
                    continue
                self._PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')
                self._PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')
                RegionLayoutLine = self.CurrentLineNumber + 1

        if IfList:
            raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)
        self.Rewind()

    def _CollectMacroPcd(self):
        MacroDict = {}

        # PCD macro
        MacroDict.update(GlobalData.gPlatformPcds)
        MacroDict.update(self._PcdDict)

        # Lowest priority
        MacroDict.update(GlobalData.gPlatformDefines)

        if self._CurSection:
            # Defines macro
            ScopeMacro = self._MacroDict[TAB_COMMON, TAB_COMMON, TAB_COMMON]
            if ScopeMacro:
                MacroDict.update(ScopeMacro)

            # Section macro
            ScopeMacro = self._MacroDict[
                        self._CurSection[0],
                        self._CurSection[1],
                        self._CurSection[2]
            ]
            if ScopeMacro:
                MacroDict.update(ScopeMacro)

        MacroDict.update(GlobalData.gGlobalDefines)
        MacroDict.update(GlobalData.gCommandLineDefines)
        for Item in GlobalData.BuildOptionPcd:
            if isinstance(Item, tuple):
                continue
            PcdName, TmpValue = Item.split(TAB_EQUAL_SPLIT)
            TmpValue = BuildOptionValue(TmpValue, {})
            MacroDict[PcdName.strip()] = TmpValue
        # Highest priority

        return MacroDict

    def _EvaluateConditional(self, Expression, Line, Op = None, Value = None):
        MacroPcdDict = self._CollectMacroPcd()
        if Op == 'eval':
            try:
                if Value:
                    return ValueExpression(Expression, MacroPcdDict)(True)
                else:
                    return ValueExpression(Expression, MacroPcdDict)()
            except WrnExpression as Excpt:
                #
                # Catch expression evaluation warning here. We need to report
                # the precise number of line and return the evaluation result
                #
                EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
                                File=self.FileName, ExtraData=self._CurrentLine(),
                                Line=Line)
                return Excpt.result
            except Exception as Excpt:
                if hasattr(Excpt, 'Pcd'):
                    if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
                        Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]
                        raise Warning("Cannot use this PCD (%s) in an expression as"
                                      " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
                                      " of the DSC file (%s), and it is currently defined in this section:"
                                      " %s, line #: %d." % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE'], Info[0], Info[1]),
                                      self.FileName, Line)
                    else:
                        raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']),
                                      self.FileName, Line)
                else:
                    raise Warning(str(Excpt), self.FileName, Line)
        else:
            if Expression.startswith('$(') and Expression[-1] == ')':
                Expression = Expression[2:-1]
            return Expression in MacroPcdDict

    ## _IsToken() method
    #
    #   Check whether input string is found from current char position along
    #   If found, the string value is put into self._Token
    #
    #   @param  self        The object pointer
    #   @param  String      The string to search
    #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive
    #   @retval True        Successfully find string, file buffer pointer moved forward
    #   @retval False       Not able to find string, file buffer pointer not changed
    #
    def _IsToken(self, String, IgnoreCase = False):
        self._SkipWhiteSpace()

        # Only consider the same line, no multi-line token allowed
        StartPos = self.CurrentOffsetWithinLine
        index = -1
        if IgnoreCase:
            index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(String.upper())
        else:
            index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(String)
        if index == 0:
            self.CurrentOffsetWithinLine += len(String)
            self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
            return True
        return False

    ## _IsKeyword() method
    #
    #   Check whether input keyword is found from current char position along, whole word only!
    #   If found, the string value is put into self._Token
    #
    #   @param  self        The object pointer
    #   @param  Keyword     The string to search
    #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive
    #   @retval True        Successfully find string, file buffer pointer moved forward
    #   @retval False       Not able to find string, file buffer pointer not changed
    #
    def _IsKeyword(self, KeyWord, IgnoreCase = False):
        self._SkipWhiteSpace()

        # Only consider the same line, no multi-line token allowed
        StartPos = self.CurrentOffsetWithinLine
        index = -1
        if IgnoreCase:
            index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(KeyWord.upper())
        else:
            index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(KeyWord)
        if index == 0:
            followingChar = self._CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]
            if not str(followingChar).isspace() and followingChar not in SEPARATORS:
                return False
            self.CurrentOffsetWithinLine += len(KeyWord)
            self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
            return True
        return False

    def _GetExpression(self):
        Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]
        Index = len(Line) - 1
        while Line[Index] in CR_LB_SET:
            Index -= 1
        ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]
        self.CurrentOffsetWithinLine += len(ExpressionString)
        ExpressionString = ExpressionString.strip()
        return ExpressionString

    ## _GetNextWord() method
    #
    #   Get next C name from file lines
    #   If found, the string value is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a C name string, file buffer pointer moved forward
    #   @retval False       Not able to find a C name string, file buffer pointer not changed
    #
    def _GetNextWord(self):
        self._SkipWhiteSpace()
        if self._EndOfFile():
            return False

        TempChar = self._CurrentChar()
        StartPos = self.CurrentOffsetWithinLine
        if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':
            self._GetOneChar()
            while not self._EndOfLine():
                TempChar = self._CurrentChar()
                if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
                or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':
                    self._GetOneChar()

                else:
                    break

            self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
            return True

        return False

    def _GetNextPcdWord(self):
        self._SkipWhiteSpace()
        if self._EndOfFile():
            return False

        TempChar = self._CurrentChar()
        StartPos = self.CurrentOffsetWithinLine
        if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_' or TempChar == TAB_SECTION_START or TempChar == TAB_SECTION_END:
            self._GetOneChar()
            while not self._EndOfLine():
                TempChar = self._CurrentChar()
                if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
                or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-' or TempChar == TAB_SECTION_START or TempChar == TAB_SECTION_END:
                    self._GetOneChar()

                else:
                    break

            self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
            return True

        return False

    ## _GetNextToken() method
    #
    #   Get next token unit before a separator
    #   If found, the string value is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a token unit, file buffer pointer moved forward
    #   @retval False       Not able to find a token unit, file buffer pointer not changed
    #
    def _GetNextToken(self):
        # Skip leading spaces, if exist.
        self._SkipWhiteSpace()
        if self._EndOfFile():
            return False
        # Record the token start position, the position of the first non-space char.
        StartPos = self.CurrentOffsetWithinLine
        StartLine = self.CurrentLineNumber
        while StartLine == self.CurrentLineNumber:
            TempChar = self._CurrentChar()
            # Try to find the end char that is not a space and not in separator tuple.
            # That is, when we got a space or any char in the tuple, we got the end of token.
            if not str(TempChar).isspace() and TempChar not in SEPARATORS:
                self._GetOneChar()
            # if we happen to meet a separator as the first char, we must proceed to get it.
            # That is, we get a token that is a separator char. normally it is the boundary of other tokens.
            elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPARATORS:
                self._GetOneChar()
                break
            else:
                break
#        else:
#            return False

        EndPos = self.CurrentOffsetWithinLine
        if self.CurrentLineNumber != StartLine:
            EndPos = len(self.Profile.FileLinesList[StartLine-1])
        self._Token = self.Profile.FileLinesList[StartLine-1][StartPos: EndPos]
        if self._Token.lower() in {TAB_IF, TAB_END_IF, TAB_ELSE_IF, TAB_ELSE, TAB_IF_DEF, TAB_IF_N_DEF, TAB_ERROR, TAB_INCLUDE}:
            self._Token = self._Token.lower()
        if StartPos != self.CurrentOffsetWithinLine:
            return True
        else:
            return False

    ## _GetNextGuid() method
    #
    #   Get next token unit before a separator
    #   If found, the GUID string is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a registry format GUID, file buffer pointer moved forward
    #   @retval False       Not able to find a registry format GUID, file buffer pointer not changed
    #
    def _GetNextGuid(self):
        if not self._GetNextToken():
            return False
        if GlobalData.gGuidPattern.match(self._Token) is not None:
            return True
        else:
            self._UndoToken()
            return False

    @staticmethod
    def _Verify(Name, Value, Scope):
        # value verification only applies to numeric values.
        if Scope not in TAB_PCD_NUMERIC_TYPES:
            return

        ValueNumber = 0
        try:
            ValueNumber = int(Value, 0)
        except:
            EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name)
        if ValueNumber < 0:
            EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name)
        if ValueNumber > MAX_VAL_TYPE[Scope]:
            EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)
        return True

    ## _UndoToken() method
    #
    #   Go back one token unit in file buffer
    #
    #   @param  self        The object pointer
    #
    def _UndoToken(self):
        self._UndoOneChar()
        while self._CurrentChar().isspace():
            if not self._UndoOneChar():
                self._GetOneChar()
                return


        StartPos = self.CurrentOffsetWithinLine
        CurrentLine = self.CurrentLineNumber
        while CurrentLine == self.CurrentLineNumber:

            TempChar = self._CurrentChar()
            # Try to find the end char that is not a space and not in separator tuple.
            # That is, when we got a space or any char in the tuple, we got the end of token.
            if not str(TempChar).isspace() and not TempChar in SEPARATORS:
                if not self._UndoOneChar():
                    return
            # if we happen to meet a separator as the first char, we must proceed to get it.
            # That is, we get a token that is a separator char. normally it is the boundary of other tokens.
            elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPARATORS:
                return
            else:
                break

        self._GetOneChar()

    ## _GetNextHexNumber() method
    #
    #   Get next HEX data before a separator
    #   If found, the HEX data is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a HEX data, file buffer pointer moved forward
    #   @retval False       Not able to find a HEX data, file buffer pointer not changed
    #
    def _GetNextHexNumber(self):
        if not self._GetNextToken():
            return False
        if GlobalData.gHexPatternAll.match(self._Token):
            return True
        else:
            self._UndoToken()
            return False

    ## _GetNextDecimalNumber() method
    #
    #   Get next decimal data before a separator
    #   If found, the decimal data is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a decimal data, file buffer pointer moved forward
    #   @retval False       Not able to find a decimal data, file buffer pointer not changed
    #
    def _GetNextDecimalNumber(self):
        if not self._GetNextToken():
            return False
        if self._Token.isdigit():
            return True
        else:
            self._UndoToken()
            return False

    def _GetNextPcdSettings(self):
        if not self._GetNextWord():
            raise Warning.Expected("<PcdTokenSpaceCName>", self.FileName, self.CurrentLineNumber)
        pcdTokenSpaceCName = self._Token

        if not self._IsToken(TAB_SPLIT):
            raise Warning.Expected(".", self.FileName, self.CurrentLineNumber)

        if not self._GetNextWord():
            raise Warning.Expected("<PcdCName>", self.FileName, self.CurrentLineNumber)
        pcdCName = self._Token

        Fields = []
        while self._IsToken(TAB_SPLIT):
            if not self._GetNextPcdWord():
                raise Warning.Expected("Pcd Fields", self.FileName, self.CurrentLineNumber)
            Fields.append(self._Token)

        return (pcdCName, pcdTokenSpaceCName,TAB_SPLIT.join(Fields))

    ## _GetStringData() method
    #
    #   Get string contents quoted in ""
    #   If found, the decimal data is put into self._Token
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a string data, file buffer pointer moved forward
    #   @retval False       Not able to find a string data, file buffer pointer not changed
    #
    def _GetStringData(self):
        QuoteToUse = None
        if self._Token.startswith(T_CHAR_DOUBLE_QUOTE) or self._Token.startswith("L\""):
            QuoteToUse = T_CHAR_DOUBLE_QUOTE
        elif self._Token.startswith(T_CHAR_SINGLE_QUOTE) or self._Token.startswith("L\'"):
            QuoteToUse = T_CHAR_SINGLE_QUOTE
        else:
            return False

        self._UndoToken()
        self._SkipToToken(QuoteToUse)
        currentLineNumber = self.CurrentLineNumber

        if not self._SkipToToken(QuoteToUse):
            raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber)
        if currentLineNumber != self.CurrentLineNumber:
            raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber)
        self._Token = self._SkippedChars.rstrip(QuoteToUse)
        return True

    ## _SkipToToken() method
    #
    #   Search forward in file buffer for the string
    #   The skipped chars are put into self._SkippedChars
    #
    #   @param  self        The object pointer
    #   @param  String      The string to search
    #   @param  IgnoreCase  Indicate case sensitive/non-sensitive search, default is case sensitive
    #   @retval True        Successfully find the string, file buffer pointer moved forward
    #   @retval False       Not able to find the string, file buffer pointer not changed
    #
    def _SkipToToken(self, String, IgnoreCase = False):
        StartPos = self.GetFileBufferPos()

        self._SkippedChars = ""
        while not self._EndOfFile():
            index = -1
            if IgnoreCase:
                index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(String.upper())
            else:
                index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(String)
            if index == 0:
                self.CurrentOffsetWithinLine += len(String)
                self._SkippedChars += String
                return True
            self._SkippedChars += str(self._CurrentChar())
            self._GetOneChar()

        self.SetFileBufferPos(StartPos)
        self._SkippedChars = ""
        return False

    ## GetFileBufferPos() method
    #
    #   Return the tuple of current line and offset within the line
    #
    #   @param  self        The object pointer
    #   @retval Tuple       Line number and offset pair
    #
    def GetFileBufferPos(self):
        return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)

    ## SetFileBufferPos() method
    #
    #   Restore the file buffer position
    #
    #   @param  self        The object pointer
    #   @param  Pos         The new file buffer position
    #
    def SetFileBufferPos(self, Pos):
        (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos

    ## Preprocess() method
    #
    #   Preprocess comment, conditional directive, include directive, replace macro.
    #   Exception will be raised if syntax error found
    #
    #   @param  self        The object pointer
    #
    def Preprocess(self):
        self._StringToList()
        self.PreprocessFile()
        self.PreprocessIncludeFile()
        self._StringToList()
        self.PreprocessFile()
        self.PreprocessConditionalStatement()
        self._StringToList()
        for Pos in self._WipeOffArea:
            self._ReplaceFragment(Pos[0], Pos[1])
        self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]

        while self._GetDefines():
            pass

    ## ParseFile() method
    #
    #   Parse the file profile buffer to extract fd, fv ... information
    #   Exception will be raised if syntax error found
    #
    #   @param  self        The object pointer
    #
    def ParseFile(self):
        try:
            self.Preprocess()
            self._GetError()
            #
            # Keep processing sections of the FDF until no new sections or a syntax error is found
            #
            while self._GetFd() or self._GetFv() or self._GetFmp() or self._GetCapsule() or self._GetRule() or self._GetOptionRom():
                pass

        except Warning as X:
            self._UndoToken()
            #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \
            # At this point, the closest parent would be the included file itself
            Profile = GetParentAtLine(X.OriginalLineNumber)
            if Profile is not None:
                X.Message += ' near line %d, column %d: %s' \
                % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1])
            else:
                FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                X.Message += ' near line %d, column %d: %s' \
                % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:].rstrip(TAB_LINE_BREAK).rstrip(T_CHAR_CR))
            raise

    ## SectionParser() method
    #
    #   Parse the file section info
    #   Exception will be raised if syntax error found
    #
    #   @param  self          The object pointer
    #   @param  section       The section string

    def SectionParser(self, section):
        S = section.upper()
        if not S.startswith("[DEFINES") and not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
             and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM.") and not S.startswith('[FMPPAYLOAD.'):
            raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self.FileName, self.CurrentLineNumber)

    ## _GetDefines() method
    #
    #   Get Defines section contents and store its data into AllMacrosList
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a Defines
    #   @retval False       Not able to find a Defines
    #
    def _GetDefines(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[DEFINES"):
            self.SectionParser(S)
            self._UndoToken()
            return False

        self._UndoToken()
        if not self._IsToken("[DEFINES", True):
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
            #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
            raise Warning.Expected("[DEFINES", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        while self._GetNextWord():
            # handle the SET statement
            if self._Token == 'SET':
                self._UndoToken()
                self._GetSetStatement(None)
                continue

            Macro = self._Token

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken() or self._Token.startswith(TAB_SECTION_START):
                raise Warning.Expected("MACRO value", self.FileName, self.CurrentLineNumber)
            Value = self._Token

        return False

    ##_GetError() method
    def _GetError(self):
        #save the Current information
        CurrentLine = self.CurrentLineNumber
        CurrentOffset = self.CurrentOffsetWithinLine
        while self._GetNextToken():
            if self._Token == TAB_ERROR:
                EdkLogger.error('FdfParser', ERROR_STATEMENT, self._CurrentLine().replace(TAB_ERROR, '', 1), File=self.FileName, Line=self.CurrentLineNumber)
        self.CurrentLineNumber = CurrentLine
        self.CurrentOffsetWithinLine = CurrentOffset

    ## _GetFd() method
    #
    #   Get FD section contents and store its data into FD dictionary of self.Profile
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a FD
    #   @retval False       Not able to find a FD
    #
    def _GetFd(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[FD."):
            if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \
                and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
                raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)
            self._UndoToken()
            return False

        self._UndoToken()
        if not self._IsToken("[FD.", True):
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
            #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
            raise Warning.Expected("[FD.]", self.FileName, self.CurrentLineNumber)

        FdName = self._GetUiName()
        if FdName == "":
            if len (self.Profile.FdDict) == 0:
                FdName = GenFdsGlobalVariable.PlatformName
                if FdName == "" and GlobalData.gActivePlatform:
                    FdName = GlobalData.gActivePlatform.PlatformName
                self.Profile.FdNameNotSet = True
            else:
                raise Warning.Expected("FdName in [FD.] section", self.FileName, self.CurrentLineNumber)
        self.CurrentFdName = FdName.upper()

        if self.CurrentFdName in self.Profile.FdDict:
            raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        FdObj = FD()
        FdObj.FdUiName = self.CurrentFdName
        self.Profile.FdDict[self.CurrentFdName] = FdObj

        if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:
            raise Warning.Expected("all FDs have their name", self.FileName, self.CurrentLineNumber)

        Status = self._GetCreateFile(FdObj)
        if not Status:
            raise Warning("FD name error", self.FileName, self.CurrentLineNumber)

        while self._GetTokenStatements(FdObj):
            pass
        for Attr in ("BaseAddress", "Size", "ErasePolarity"):
            if getattr(FdObj, Attr) is None:
                self._GetNextToken()
                raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)

        if not FdObj.BlockSizeList:
            FdObj.BlockSizeList.append((1, FdObj.Size, None))

        self._GetDefineStatements(FdObj)

        self._GetSetStatements(FdObj)

        if not self._GetRegionLayout(FdObj):
            raise Warning.Expected("region layout", self.FileName, self.CurrentLineNumber)

        while self._GetRegionLayout(FdObj):
            pass
        return True

    ## _GetUiName() method
    #
    #   Return the UI name of a section
    #
    #   @param  self        The object pointer
    #   @retval FdName      UI name
    #
    def _GetUiName(self):
        Name = ""
        if self._GetNextWord():
            Name = self._Token

        return Name

    ## _GetCreateFile() method
    #
    #   Return the output file name of object
    #
    #   @param  self        The object pointer
    #   @param  Obj         object whose data will be stored in file
    #   @retval FdName      UI name
    #
    def _GetCreateFile(self, Obj):
        if self._IsKeyword("CREATE_FILE"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber)

            FileName = self._Token
            Obj.CreateFileName = FileName

        return True

    def SetPcdLocalation(self,pcdpair):
        self.Profile.PcdLocalDict[pcdpair] = (self.Profile.FileName,self.CurrentLineNumber)

    ## _GetTokenStatements() method
    #
    #   Get token statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom token statement is got
    #
    def _GetTokenStatements(self, Obj):
        if self._IsKeyword("BaseAddress"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextHexNumber():
                raise Warning.Expected("Hex base address", self.FileName, self.CurrentLineNumber)

            Obj.BaseAddress = self._Token

            if self._IsToken(TAB_VALUE_SPLIT):
                pcdPair = self._GetNextPcdSettings()
                Obj.BaseAddressPcd = pcdPair
                self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
                self.SetPcdLocalation(pcdPair)
                FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
            return True

        if self._IsKeyword("Size"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextHexNumber():
                raise Warning.Expected("Hex size", self.FileName, self.CurrentLineNumber)

            Size = self._Token
            if self._IsToken(TAB_VALUE_SPLIT):
                pcdPair = self._GetNextPcdSettings()
                Obj.SizePcd = pcdPair
                self.Profile.PcdDict[pcdPair] = Size
                self.SetPcdLocalation(pcdPair)
                FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
            Obj.Size = int(Size, 0)
            return True

        if self._IsKeyword("ErasePolarity"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("Erase Polarity", self.FileName, self.CurrentLineNumber)

            if not self._Token in {"1", "0"}:
                raise Warning.Expected("1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)

            Obj.ErasePolarity = self._Token
            return True

        return self._GetBlockStatements(Obj)

    ## _GetAddressStatements() method
    #
    #   Get address statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom address statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetAddressStatements(self, Obj):
        if self._IsKeyword("BsBaseAddress"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():
                raise Warning.Expected("address", self.FileName, self.CurrentLineNumber)

            BsAddress = int(self._Token, 0)
            Obj.BsBaseAddress = BsAddress

        if self._IsKeyword("RtBaseAddress"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():
                raise Warning.Expected("address", self.FileName, self.CurrentLineNumber)

            RtAddress = int(self._Token, 0)
            Obj.RtBaseAddress = RtAddress

    ## _GetBlockStatements() method
    #
    #   Get block statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom block statement is got
    #
    def _GetBlockStatements(self, Obj):
        IsBlock = False
        while self._GetBlockStatement(Obj):
            IsBlock = True

            Item = Obj.BlockSizeList[-1]
            if Item[0] is None or Item[1] is None:
                raise Warning.Expected("block statement", self.FileName, self.CurrentLineNumber)
        return IsBlock

    ## _GetBlockStatement() method
    #
    #   Get block statement
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom block statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetBlockStatement(self, Obj):
        if not self._IsKeyword("BlockSize"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextHexNumber() and not self._GetNextDecimalNumber():
            raise Warning.Expected("Hex or Integer block size", self.FileName, self.CurrentLineNumber)

        BlockSize = self._Token
        BlockSizePcd = None
        if self._IsToken(TAB_VALUE_SPLIT):
            PcdPair = self._GetNextPcdSettings()
            BlockSizePcd = PcdPair
            self.Profile.PcdDict[PcdPair] = BlockSize
            self.SetPcdLocalation(PcdPair)
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
        BlockSize = int(BlockSize, 0)

        BlockNumber = None
        if self._IsKeyword("NumBlocks"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():
                raise Warning.Expected("block numbers", self.FileName, self.CurrentLineNumber)

            BlockNumber = int(self._Token, 0)

        Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))
        return True

    ## _GetDefineStatements() method
    #
    #   Get define statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom define statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetDefineStatements(self, Obj):
        while self._GetDefineStatement(Obj):
            pass

    ## _GetDefineStatement() method
    #
    #   Get define statement
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom define statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetDefineStatement(self, Obj):
        if self._IsKeyword(TAB_DEFINE):
            self._GetNextToken()
            Macro = self._Token
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)

            Value = self._Token
            Macro = '$(' + Macro + ')'
            Obj.DefineVarDict[Macro] = Value
            return True

        return False

    ## _GetSetStatements() method
    #
    #   Get set statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom set statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetSetStatements(self, Obj):
        while self._GetSetStatement(Obj):
            pass

    ## _GetSetStatement() method
    #
    #   Get set statement
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom set statement is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetSetStatement(self, Obj):
        if self._IsKeyword("SET"):
            PcdPair = self._GetNextPcdSettings()

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            Value = self._GetExpression()
            Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)

            if Obj:
                Obj.SetVarDict[PcdPair] = Value
            self.Profile.PcdDict[PcdPair] = Value
            self.SetPcdLocalation(PcdPair)
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
            return True

        return False

    ## _CalcRegionExpr(self)
    #
    #   Calculate expression for offset or size of a region
    #
    #   @return: None if invalid expression
    #            Calculated number if successfully
    #
    def _CalcRegionExpr(self):
        StartPos = self.GetFileBufferPos()
        Expr = ''
        PairCount = 0
        while not self._EndOfFile():
            CurCh = self._CurrentChar()
            if CurCh == '(':
                PairCount += 1
            elif CurCh == ')':
                PairCount -= 1

            if CurCh in '|\r\n' and PairCount == 0:
                break
            Expr += CurCh
            self._GetOneChar()
        try:
            return int(
                ValueExpression(Expr,
                                self._CollectMacroPcd()
                                )(True), 0)
        except Exception:
            self.SetFileBufferPos(StartPos)
            return None

    ## _GetRegionLayout() method
    #
    #   Get region layout for FD
    #
    #   @param  self        The object pointer
    #   @param  theFd       for whom region is got
    #   @retval True        Successfully find
    #   @retval False       Not able to find
    #
    def _GetRegionLayout(self, theFd):
        Offset = self._CalcRegionExpr()
        if Offset is None:
            return False

        RegionObj = Region()
        RegionObj.Offset = Offset
        theFd.RegionList.append(RegionObj)

        if not self._IsToken(TAB_VALUE_SPLIT):
            raise Warning.Expected("'|'", self.FileName, self.CurrentLineNumber)

        Size = self._CalcRegionExpr()
        if Size is None:
            raise Warning.Expected("Region Size", self.FileName, self.CurrentLineNumber)
        RegionObj.Size = Size

        if not self._GetNextWord():
            return True

        if not self._Token in {"SET", BINARY_FILE_TYPE_FV, "FILE", "DATA", "CAPSULE", "INF"}:
            #
            # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
            # Or it might be next region's offset described by an expression which starts with a PCD.
            #    PcdOffset[|PcdSize] or OffsetPcdExpression|Size
            #
            self._UndoToken()
            IsRegionPcd = (RegionSizeGuidPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:]) or
                           RegionOffsetPcdPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:]))
            if IsRegionPcd:
                RegionObj.PcdOffset = self._GetNextPcdSettings()
                self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + int(theFd.BaseAddress, 0))
                self.SetPcdLocalation(RegionObj.PcdOffset)
                self._PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset
                FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple
                if self._IsToken(TAB_VALUE_SPLIT):
                    RegionObj.PcdSize = self._GetNextPcdSettings()
                    self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size
                    self.SetPcdLocalation(RegionObj.PcdSize)
                    self._PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size
                    FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
                    self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple

            if not self._GetNextWord():
                return True

        if self._Token == "SET":
            self._UndoToken()
            self._GetSetStatements(RegionObj)
            if not self._GetNextWord():
                return True

        elif self._Token == BINARY_FILE_TYPE_FV:
            self._UndoToken()
            self._GetRegionFvType(RegionObj)

        elif self._Token == "CAPSULE":
            self._UndoToken()
            self._GetRegionCapType(RegionObj)

        elif self._Token == "FILE":
            self._UndoToken()
            self._GetRegionFileType(RegionObj)

        elif self._Token == "INF":
            self._UndoToken()
            RegionObj.RegionType = "INF"
            while self._IsKeyword("INF"):
                self._UndoToken()
                ffsInf = self._ParseInfStatement()
                if not ffsInf:
                    break
                RegionObj.RegionDataList.append(ffsInf)

        elif self._Token == "DATA":
            self._UndoToken()
            self._GetRegionDataType(RegionObj)
        else:
            self._UndoToken()
            if self._GetRegionLayout(theFd):
                return True
            raise Warning("A valid region type was not found. "
                          "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
                          self.FileName, self.CurrentLineNumber)

        return True

    ## _GetRegionFvType() method
    #
    #   Get region fv data for region
    #
    #   @param  self        The object pointer
    #   @param  RegionObj   for whom region data is got
    #
    def _GetRegionFvType(self, RegionObj):
        if not self._IsKeyword(BINARY_FILE_TYPE_FV):
            raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)

        RegionObj.RegionType = BINARY_FILE_TYPE_FV
        RegionObj.RegionDataList.append((self._Token).upper())

        while self._IsKeyword(BINARY_FILE_TYPE_FV):

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)

            RegionObj.RegionDataList.append((self._Token).upper())

    ## _GetRegionCapType() method
    #
    #   Get region capsule data for region
    #
    #   @param  self        The object pointer
    #   @param  RegionObj   for whom region data is got
    #
    def _GetRegionCapType(self, RegionObj):
        if not self._IsKeyword("CAPSULE"):
            raise Warning.Expected("'CAPSULE'", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber)

        RegionObj.RegionType = "CAPSULE"
        RegionObj.RegionDataList.append(self._Token)

        while self._IsKeyword("CAPSULE"):

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber)

            RegionObj.RegionDataList.append(self._Token)

    ## _GetRegionFileType() method
    #
    #   Get region file data for region
    #
    #   @param  self        The object pointer
    #   @param  RegionObj   for whom region data is got
    #
    def _GetRegionFileType(self, RegionObj):
        if not self._IsKeyword("FILE"):
            raise Warning.Expected("'FILE'", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)

        RegionObj.RegionType = "FILE"
        RegionObj.RegionDataList.append(self._Token)

        while self._IsKeyword("FILE"):

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("FILE name", self.FileName, self.CurrentLineNumber)

            RegionObj.RegionDataList.append(self._Token)

    ## _GetRegionDataType() method
    #
    #   Get region array data for region
    #
    #   @param  self        The object pointer
    #   @param  RegionObj   for whom region data is got
    #
    def _GetRegionDataType(self, RegionObj):
        if not self._IsKeyword("DATA"):
            raise Warning.Expected("Region Data type", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._IsToken("{"):
            raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

        if not self._GetNextHexNumber():
            raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)

        if len(self._Token) > 18:
            raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)

        # convert hex string value to byte hex string array
        AllString = self._Token
        AllStrLen = len (AllString)
        DataString = ""
        while AllStrLen > 4:
            DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT
            AllStrLen  = AllStrLen - 2
        DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT

        # byte value array
        if len (self._Token) <= 4:
            while self._IsToken(TAB_COMMA_SPLIT):
                if not self._GetNextHexNumber():
                    raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
                if len(self._Token) > 4:
                    raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
                DataString += self._Token
                DataString += TAB_COMMA_SPLIT

        if not self._IsToken(T_CHAR_BRACE_R):
            raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

        DataString = DataString.rstrip(TAB_COMMA_SPLIT)
        RegionObj.RegionType = "DATA"
        RegionObj.RegionDataList.append(DataString)

        while self._IsKeyword("DATA"):

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

            if not self._GetNextHexNumber():
                raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)

            if len(self._Token) > 18:
                raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)

            # convert hex string value to byte hex string array
            AllString = self._Token
            AllStrLen = len (AllString)
            DataString = ""
            while AllStrLen > 4:
                DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT
                AllStrLen  = AllStrLen - 2
            DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT

            # byte value array
            if len (self._Token) <= 4:
                while self._IsToken(TAB_COMMA_SPLIT):
                    if not self._GetNextHexNumber():
                        raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
                    if len(self._Token) > 4:
                        raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
                    DataString += self._Token
                    DataString += TAB_COMMA_SPLIT

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

            DataString = DataString.rstrip(TAB_COMMA_SPLIT)
            RegionObj.RegionDataList.append(DataString)

    ## _GetFv() method
    #
    #   Get FV section contents and store its data into FV dictionary of self.Profile
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a FV
    #   @retval False       Not able to find a FV
    #
    def _GetFv(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[FV."):
            self.SectionParser(S)
            self._UndoToken()
            return False

        self._UndoToken()
        if not self._IsToken("[FV.", True):
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
            #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
            raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)

        FvName = self._GetUiName()
        self.CurrentFvName = FvName.upper()

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        FvObj = FV(Name=self.CurrentFvName)
        self.Profile.FvDict[self.CurrentFvName] = FvObj

        Status = self._GetCreateFile(FvObj)
        if not Status:
            raise Warning("FV name error", self.FileName, self.CurrentLineNumber)

        self._GetDefineStatements(FvObj)

        self._GetAddressStatements(FvObj)

        while True:
            self._GetSetStatements(FvObj)

            if not (self._GetBlockStatement(FvObj) or self._GetFvBaseAddress(FvObj) or
                self._GetFvForceRebase(FvObj) or self._GetFvAlignment(FvObj) or
                self._GetFvAttributes(FvObj) or self._GetFvNameGuid(FvObj) or
                self._GetFvExtEntryStatement(FvObj) or self._GetFvNameString(FvObj)):
                break

        if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:
            raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)

        self._GetAprioriSection(FvObj)
        self._GetAprioriSection(FvObj)

        while True:
            isInf = self._GetInfStatement(FvObj)
            isFile = self._GetFileStatement(FvObj)
            if not isInf and not isFile:
                break

        return True

    ## _GetFvAlignment() method
    #
    #   Get alignment for FV
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom alignment is got
    #   @retval True        Successfully find a alignment statement
    #   @retval False       Not able to find a alignment statement
    #
    def _GetFvAlignment(self, Obj):
        if not self._IsKeyword("FvAlignment"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber)

        if self._Token.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
                                        "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
                                        "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
                                        "1G", "2G"}:
            raise Warning("Unknown alignment value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
        Obj.FvAlignment = self._Token
        return True

    ## _GetFvBaseAddress() method
    #
    #   Get BaseAddress for FV
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom FvBaseAddress is got
    #   @retval True        Successfully find a FvBaseAddress statement
    #   @retval False       Not able to find a FvBaseAddress statement
    #
    def _GetFvBaseAddress(self, Obj):
        if not self._IsKeyword("FvBaseAddress"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("FV base address value", self.FileName, self.CurrentLineNumber)

        if not BaseAddrValuePattern.match(self._Token.upper()):
            raise Warning("Unknown FV base address value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
        Obj.FvBaseAddress = self._Token
        return True

    ## _GetFvForceRebase() method
    #
    #   Get FvForceRebase for FV
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom FvForceRebase is got
    #   @retval True        Successfully find a FvForceRebase statement
    #   @retval False       Not able to find a FvForceRebase statement
    #
    def _GetFvForceRebase(self, Obj):
        if not self._IsKeyword("FvForceRebase"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("FvForceRebase value", self.FileName, self.CurrentLineNumber)

        if self._Token.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:
            raise Warning("Unknown FvForceRebase value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)

        if self._Token.upper() in {"TRUE", "1", "0X1", "0X01"}:
            Obj.FvForceRebase = True
        elif self._Token.upper() in {"FALSE", "0", "0X0", "0X00"}:
            Obj.FvForceRebase = False
        else:
            Obj.FvForceRebase = None

        return True


    ## _GetFvAttributes() method
    #
    #   Get attributes for FV
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom attribute is got
    #   @retval None
    #
    def _GetFvAttributes(self, FvObj):
        IsWordToken = False
        while self._GetNextWord():
            IsWordToken = True
            name = self._Token
            if name not in {"ERASE_POLARITY", "MEMORY_MAPPED", \
                           "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
                           "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
                           "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
                           "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
                           "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:
                self._UndoToken()
                return False

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken() or self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}:
                raise Warning.Expected("TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)

            FvObj.FvAttributeDict[name] = self._Token

        return IsWordToken

    ## _GetFvNameGuid() method
    #
    #   Get FV GUID for FV
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom GUID is got
    #   @retval None
    #
    def _GetFvNameGuid(self, FvObj):
        if not self._IsKeyword("FvNameGuid"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextGuid():
            raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber)

        FvObj.FvNameGuid = self._Token

        return True

    def _GetFvNameString(self, FvObj):
        if not self._IsKeyword("FvNameString"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken() or self._Token.upper() not in {'TRUE', 'FALSE'}:
            raise Warning.Expected("TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber)

        FvObj.FvNameString = self._Token

        return True

    def _GetFvExtEntryStatement(self, FvObj):
        if not (self._IsKeyword("FV_EXT_ENTRY") or self._IsKeyword("FV_EXT_ENTRY_TYPE")):
            return False

        if not self._IsKeyword ("TYPE"):
            raise Warning.Expected("'TYPE'", self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextHexNumber() and not self._GetNextDecimalNumber():
            raise Warning.Expected("Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)

        FvObj.FvExtEntryTypeValue.append(self._Token)

        if not self._IsToken("{"):
            raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

        if not self._IsKeyword("FILE") and not self._IsKeyword("DATA"):
            raise Warning.Expected("'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)

        FvObj.FvExtEntryType.append(self._Token)

        if self._Token == 'DATA':
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

            if not self._GetNextHexNumber():
                raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)

            if len(self._Token) > 4:
                raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)

            DataString = self._Token
            DataString += TAB_COMMA_SPLIT

            while self._IsToken(TAB_COMMA_SPLIT):
                if not self._GetNextHexNumber():
                    raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
                if len(self._Token) > 4:
                    raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
                DataString += self._Token
                DataString += TAB_COMMA_SPLIT

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

            DataString = DataString.rstrip(TAB_COMMA_SPLIT)
            FvObj.FvExtEntryData.append(DataString)

        if self._Token == 'FILE':
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)

            FvObj.FvExtEntryData.append(self._Token)

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

        return True

    ## _GetAprioriSection() method
    #
    #   Get token statements
    #
    #   @param  self        The object pointer
    #   @param  FvObj       for whom apriori is got
    #   @retval True        Successfully find apriori statement
    #   @retval False       Not able to find apriori statement
    #
    def _GetAprioriSection(self, FvObj):
        if not self._IsKeyword("APRIORI"):
            return False

        if not self._IsKeyword("PEI") and not self._IsKeyword("DXE"):
            raise Warning.Expected("Apriori file type", self.FileName, self.CurrentLineNumber)
        AprType = self._Token

        if not self._IsToken("{"):
            raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

        AprSectionObj = AprioriSection()
        AprSectionObj.AprioriType = AprType

        self._GetDefineStatements(AprSectionObj)

        while True:
            IsInf = self._GetInfStatement(AprSectionObj)
            IsFile = self._GetFileStatement(AprSectionObj)
            if not IsInf and not IsFile:
                break

        if not self._IsToken(T_CHAR_BRACE_R):
            raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

        FvObj.AprioriSectionList.append(AprSectionObj)
        return True

    def _ParseInfStatement(self):
        if not self._IsKeyword("INF"):
            return None

        ffsInf = FfsInfStatement()
        self._GetInfOptions(ffsInf)

        if not self._GetNextToken():
            raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber)
        ffsInf.InfFileName = self._Token
        if not ffsInf.InfFileName.endswith('.inf'):
            raise Warning.Expected(".inf file path", self.FileName, self.CurrentLineNumber)

        ffsInf.CurrentLineNum = self.CurrentLineNumber
        ffsInf.CurrentLineContent = self._CurrentLine()

        #Replace $(SAPCE) with real space
        ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')

        if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:
            #do case sensitive check for file path
            ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
            if ErrorCode != 0:
                EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)

        NewFileName = ffsInf.InfFileName
        if ffsInf.OverrideGuid:
            NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path

        if not NewFileName in self.Profile.InfList:
            self.Profile.InfList.append(NewFileName)
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            self.Profile.InfFileLineList.append(FileLineTuple)
            if ffsInf.UseArch:
                if ffsInf.UseArch not in self.Profile.InfDict:
                    self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]
                else:
                    self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)
            else:
                self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)

        if self._IsToken(TAB_VALUE_SPLIT):
            if self._IsKeyword('RELOCS_STRIPPED'):
                ffsInf.KeepReloc = False
            elif self._IsKeyword('RELOCS_RETAINED'):
                ffsInf.KeepReloc = True
            else:
                raise Warning("Unknown reloc strip flag '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
        return ffsInf

    ## _GetInfStatement() method
    #
    #   Get INF statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom inf statement is got
    #   @retval True        Successfully find inf statement
    #   @retval False       Not able to find inf statement
    #
    def _GetInfStatement(self, Obj, ForCapsule=False):
        ffsInf = self._ParseInfStatement()
        if not ffsInf:
            return False

        if ForCapsule:
            myCapsuleFfs = CapsuleFfs()
            myCapsuleFfs.Ffs = ffsInf
            Obj.CapsuleDataList.append(myCapsuleFfs)
        else:
            Obj.FfsList.append(ffsInf)
        return True

    ## _GetInfOptions() method
    #
    #   Get options for INF
    #
    #   @param  self        The object pointer
    #   @param  FfsInfObj   for whom option is got
    #
    def _GetInfOptions(self, FfsInfObj):
        if self._IsKeyword("FILE_GUID"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextGuid():
                raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber)
            FfsInfObj.OverrideGuid = self._Token

        if self._IsKeyword("RuleOverride"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("Rule name", self.FileName, self.CurrentLineNumber)
            FfsInfObj.Rule = self._Token

        if self._IsKeyword("VERSION"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("Version", self.FileName, self.CurrentLineNumber)

            if self._GetStringData():
                FfsInfObj.Version = self._Token

        if self._IsKeyword(BINARY_FILE_TYPE_UI):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("UI name", self.FileName, self.CurrentLineNumber)

            if self._GetStringData():
                FfsInfObj.Ui = self._Token

        if self._IsKeyword("USE"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("ARCH name", self.FileName, self.CurrentLineNumber)
            FfsInfObj.UseArch = self._Token


        if self._GetNextToken():
            p = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
            if p.match(self._Token) and p.match(self._Token).span()[1] == len(self._Token):
                FfsInfObj.KeyStringList.append(self._Token)
                if not self._IsToken(TAB_COMMA_SPLIT):
                    return
            else:
                self._UndoToken()
                return

            while self._GetNextToken():
                if not p.match(self._Token):
                    raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
                FfsInfObj.KeyStringList.append(self._Token)

                if not self._IsToken(TAB_COMMA_SPLIT):
                    break

    ## _GetFileStatement() method
    #
    #   Get FILE statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom FILE statement is got
    #   @retval True        Successfully find FILE statement
    #   @retval False       Not able to find FILE statement
    #
    def _GetFileStatement(self, Obj, ForCapsule = False):
        if not self._IsKeyword("FILE"):
            return False

        if not self._GetNextWord():
            raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)

        if ForCapsule and self._Token == 'DATA':
            self._UndoToken()
            self._UndoToken()
            return False

        FfsFileObj = FileStatement()
        FfsFileObj.FvFileType = self._Token

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextGuid():
            if not self._GetNextWord():
                raise Warning.Expected("File GUID", self.FileName, self.CurrentLineNumber)
            if self._Token == 'PCD':
                if not self._IsToken("("):
                    raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)
                PcdPair = self._GetNextPcdSettings()
                if not self._IsToken(")"):
                    raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)
                self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'

        FfsFileObj.NameGuid = self._Token

        self._GetFilePart(FfsFileObj)

        if ForCapsule:
            capsuleFfs = CapsuleFfs()
            capsuleFfs.Ffs = FfsFileObj
            Obj.CapsuleDataList.append(capsuleFfs)
        else:
            Obj.FfsList.append(FfsFileObj)

        return True

    ## _FileCouldHaveRelocFlag() method
    #
    #   Check whether reloc strip flag can be set for a file type.
    #
    #   @param  FileType    The file type to check with
    #   @retval True        This type could have relocation strip flag
    #   @retval False       No way to have it
    #
    @staticmethod
    def _FileCouldHaveRelocFlag (FileType):
        if FileType in {SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE, 'PEI_DXE_COMBO'}:
            return True
        else:
            return False

    ## _SectionCouldHaveRelocFlag() method
    #
    #   Check whether reloc strip flag can be set for a section type.
    #
    #   @param  SectionType The section type to check with
    #   @retval True        This type could have relocation strip flag
    #   @retval False       No way to have it
    #
    @staticmethod
    def _SectionCouldHaveRelocFlag (SectionType):
        if SectionType in {BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32}:
            return True
        else:
            return False

    ## _GetFilePart() method
    #
    #   Get components for FILE statement
    #
    #   @param  self        The object pointer
    #   @param  FfsFileObj   for whom component is got
    #
    def _GetFilePart(self, FfsFileObj):
        self._GetFileOpts(FfsFileObj)

        if not self._IsToken("{"):
            if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):
                if self._FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
                    if self._Token == 'RELOCS_STRIPPED':
                        FfsFileObj.KeepReloc = False
                    else:
                        FfsFileObj.KeepReloc = True
                else:
                    raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)

            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("File name or section data", self.FileName, self.CurrentLineNumber)

        if self._Token == BINARY_FILE_TYPE_FV:
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)
            FfsFileObj.FvName = self._Token

        elif self._Token == "FD":
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)
            FfsFileObj.FdName = self._Token

        elif self._Token in {TAB_DEFINE, "APRIORI", "SECTION"}:
            self._UndoToken()
            self._GetSectionData(FfsFileObj)

        elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW':
            self._UndoToken()
            self._GetRAWData(FfsFileObj)

        else:
            FfsFileObj.CurrentLineNum = self.CurrentLineNumber
            FfsFileObj.CurrentLineContent = self._CurrentLine()
            FfsFileObj.FileName = self._Token.replace('$(SPACE)', ' ')
            self._VerifyFile(FfsFileObj.FileName)

        if not self._IsToken(T_CHAR_BRACE_R):
            raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

    ## _GetRAWData() method
    #
    #   Get RAW data for FILE statement
    #
    #   @param  self         The object pointer
    #   @param  FfsFileObj   for whom section is got
    #
    def _GetRAWData(self, FfsFileObj):
        FfsFileObj.FileName = []
        FfsFileObj.SubAlignment = []
        while True:
            AlignValue = None
            if self._GetAlignment():
                if self._Token not in ALIGNMENTS:
                    raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
                #For FFS, Auto is default option same to ""
                if not self._Token == "Auto":
                    AlignValue = self._Token
            if not self._GetNextToken():
                raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)

            FileName = self._Token.replace('$(SPACE)', ' ')
            if FileName == T_CHAR_BRACE_R:
                self._UndoToken()
                raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)

            self._VerifyFile(FileName)
            File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir)
            FfsFileObj.FileName.append(File.Path)
            FfsFileObj.SubAlignment.append(AlignValue)

            if self._IsToken(T_CHAR_BRACE_R):
                self._UndoToken()
                break

        if len(FfsFileObj.SubAlignment) == 1:
            FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0]
        if len(FfsFileObj.FileName) == 1:
            FfsFileObj.FileName = FfsFileObj.FileName[0]

    ## _GetFileOpts() method
    #
    #   Get options for FILE statement
    #
    #   @param  self        The object pointer
    #   @param  FfsFileObj   for whom options is got
    #
    def _GetFileOpts(self, FfsFileObj):
        if self._GetNextToken():
            if TokenFindPattern.match(self._Token):
                FfsFileObj.KeyStringList.append(self._Token)
                if self._IsToken(TAB_COMMA_SPLIT):
                    while self._GetNextToken():
                        if not TokenFindPattern.match(self._Token):
                            raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
                        FfsFileObj.KeyStringList.append(self._Token)

                        if not self._IsToken(TAB_COMMA_SPLIT):
                            break

            else:
                self._UndoToken()

        if self._IsKeyword("FIXED", True):
            FfsFileObj.Fixed = True

        if self._IsKeyword("CHECKSUM", True):
            FfsFileObj.CheckSum = True

        if self._GetAlignment():
            if self._Token not in ALIGNMENTS:
                raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            #For FFS, Auto is default option same to ""
            if not self._Token == "Auto":
                FfsFileObj.Alignment = self._Token

    ## _GetAlignment() method
    #
    #   Return the alignment value
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find alignment
    #   @retval False       Not able to find alignment
    #
    def _GetAlignment(self):
        if self._IsKeyword("Align", True):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber)
            return True

        return False

    ## _GetSectionData() method
    #
    #   Get section data for FILE statement
    #
    #   @param  self        The object pointer
    #   @param  FfsFileObj   for whom section is got
    #
    def _GetSectionData(self, FfsFileObj):
        self._GetDefineStatements(FfsFileObj)

        while True:
            IsLeafSection = self._GetLeafSection(FfsFileObj)
            IsEncapSection = self._GetEncapsulationSec(FfsFileObj)
            if not IsLeafSection and not IsEncapSection:
                break

    ## _GetLeafSection() method
    #
    #   Get leaf section for Obj
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom leaf section is got
    #   @retval True        Successfully find section statement
    #   @retval False       Not able to find section statement
    #
    def _GetLeafSection(self, Obj):
        OldPos = self.GetFileBufferPos()

        if not self._IsKeyword("SECTION"):
            if len(Obj.SectionList) == 0:
                raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)
            else:
                return False

        AlignValue = None
        if self._GetAlignment():
            if self._Token not in ALIGNMENTS:
                raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            AlignValue = self._Token

        BuildNum = None
        if self._IsKeyword("BUILD_NUM"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("Build number value", self.FileName, self.CurrentLineNumber)

            BuildNum = self._Token

        if self._IsKeyword("VERSION"):
            if AlignValue == 'Auto':
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("version", self.FileName, self.CurrentLineNumber)
            VerSectionObj = VerSection()
            VerSectionObj.Alignment = AlignValue
            VerSectionObj.BuildNum = BuildNum
            if self._GetStringData():
                VerSectionObj.StringData = self._Token
            else:
                VerSectionObj.FileName = self._Token
            Obj.SectionList.append(VerSectionObj)

        elif self._IsKeyword(BINARY_FILE_TYPE_UI):
            if AlignValue == 'Auto':
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("UI", self.FileName, self.CurrentLineNumber)
            UiSectionObj = UiSection()
            UiSectionObj.Alignment = AlignValue
            if self._GetStringData():
                UiSectionObj.StringData = self._Token
            else:
                UiSectionObj.FileName = self._Token
            Obj.SectionList.append(UiSectionObj)

        elif self._IsKeyword("FV_IMAGE"):
            if AlignValue == 'Auto':
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("FV name or FV file path", self.FileName, self.CurrentLineNumber)

            FvName = self._Token
            FvObj = None

            if self._IsToken("{"):
                FvObj = FV()
                FvObj.UiFvName = FvName.upper()
                self._GetDefineStatements(FvObj)

                self._GetBlockStatement(FvObj)
                self._GetSetStatements(FvObj)
                self._GetFvAlignment(FvObj)
                self._GetFvAttributes(FvObj)

                while True:
                    IsInf = self._GetInfStatement(FvObj)
                    IsFile = self._GetFileStatement(FvObj)
                    if not IsInf and not IsFile:
                        break

                if not self._IsToken(T_CHAR_BRACE_R):
                    raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

            FvImageSectionObj = FvImageSection()
            FvImageSectionObj.Alignment = AlignValue
            if FvObj is not None:
                FvImageSectionObj.Fv = FvObj
                FvImageSectionObj.FvName = None
            else:
                FvImageSectionObj.FvName = FvName.upper()
                FvImageSectionObj.FvFileName = FvName

            Obj.SectionList.append(FvImageSectionObj)

        elif self._IsKeyword("PEI_DEPEX_EXP") or self._IsKeyword("DXE_DEPEX_EXP") or self._IsKeyword("SMM_DEPEX_EXP"):
            if AlignValue == 'Auto':
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
            DepexSectionObj = DepexSection()
            DepexSectionObj.Alignment = AlignValue
            DepexSectionObj.DepexType = self._Token

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
            if not self._SkipToToken(T_CHAR_BRACE_R):
                raise Warning.Expected("Depex expression ending '}'", self.FileName, self.CurrentLineNumber)

            DepexSectionObj.Expression = self._SkippedChars.rstrip(T_CHAR_BRACE_R)
            Obj.SectionList.append(DepexSectionObj)

        else:
            if not self._GetNextWord():
                raise Warning.Expected("section type", self.FileName, self.CurrentLineNumber)

            # Encapsulation section appear, UndoToken and return
            if self._Token == "COMPRESS" or self._Token == "GUIDED":
                self.SetFileBufferPos(OldPos)
                return False

            if self._Token not in {"COMPAT16", BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\
                               BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}:
                raise Warning("Unknown section type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32) and (not self._Token == BINARY_FILE_TYPE_TE):
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)

            # DataSection
            DataSectionObj = DataSection()
            DataSectionObj.Alignment = AlignValue
            DataSectionObj.SecType = self._Token

            if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):
                if self._FileCouldHaveRelocFlag(Obj.FvFileType) and self._SectionCouldHaveRelocFlag(DataSectionObj.SecType):
                    if self._Token == 'RELOCS_STRIPPED':
                        DataSectionObj.KeepReloc = False
                    else:
                        DataSectionObj.KeepReloc = True
                else:
                    raise Warning("File type %s, section type %s, could not have reloc strip flag%d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)

            if self._IsToken(TAB_EQUAL_SPLIT):
                if not self._GetNextToken():
                    raise Warning.Expected("section file path", self.FileName, self.CurrentLineNumber)
                DataSectionObj.SectFileName = self._Token
                self._VerifyFile(DataSectionObj.SectFileName)
            else:
                if not self._GetCglSection(DataSectionObj):
                    return False

            Obj.SectionList.append(DataSectionObj)

        return True

    ## _VerifyFile
    #
    #    Check if file exists or not:
    #      If current phase if GenFds, the file must exist;
    #      If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
    #    @param FileName: File path to be verified.
    #
    def _VerifyFile(self, FileName):
        if FileName.replace(TAB_WORKSPACE, '').find('$') != -1:
            return
        if not GlobalData.gAutoGenPhase or not self._GetMacroValue(TAB_DSC_DEFINES_OUTPUT_DIRECTORY) in FileName:
            ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
            if ErrorCode != 0:
                EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)

    ## _GetCglSection() method
    #
    #   Get compressed or GUIDed section for Obj
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom leaf section is got
    #   @param  AlignValue  alignment value for complex section
    #   @retval True        Successfully find section statement
    #   @retval False       Not able to find section statement
    #
    def _GetCglSection(self, Obj, AlignValue = None):

        if self._IsKeyword("COMPRESS"):
            type = "PI_STD"
            if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):
                type = self._Token

            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

            CompressSectionObj = CompressSection()
            CompressSectionObj.Alignment = AlignValue
            CompressSectionObj.CompType = type
            # Recursive sections...
            while True:
                IsLeafSection = self._GetLeafSection(CompressSectionObj)
                IsEncapSection = self._GetEncapsulationSec(CompressSectionObj)
                if not IsLeafSection and not IsEncapSection:
                    break


            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
            Obj.SectionList.append(CompressSectionObj)
            return True

        elif self._IsKeyword("GUIDED"):
            GuidValue = None
            if self._GetNextGuid():
                GuidValue = self._Token

            AttribDict = self._GetGuidAttrib()
            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
            GuidSectionObj = GuidSection()
            GuidSectionObj.Alignment = AlignValue
            GuidSectionObj.NameGuid = GuidValue
            GuidSectionObj.SectionType = "GUIDED"
            GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
            GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
            GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
            # Recursive sections...
            while True:
                IsLeafSection = self._GetLeafSection(GuidSectionObj)
                IsEncapSection = self._GetEncapsulationSec(GuidSectionObj)
                if not IsLeafSection and not IsEncapSection:
                    break

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
            Obj.SectionList.append(GuidSectionObj)

            return True

        return False

    ## _GetGuidAttri() method
    #
    #   Get attributes for GUID section
    #
    #   @param  self        The object pointer
    #   @retval AttribDict  Dictionary of key-value pair of section attributes
    #
    def _GetGuidAttrib(self):
        AttribDict = {}
        AttribDict["PROCESSING_REQUIRED"] = "NONE"
        AttribDict["AUTH_STATUS_VALID"] = "NONE"
        AttribDict["EXTRA_HEADER_SIZE"] = -1
        while self._IsKeyword("PROCESSING_REQUIRED") or self._IsKeyword("AUTH_STATUS_VALID") \
            or self._IsKeyword("EXTRA_HEADER_SIZE"):
            AttribKey = self._Token

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)
            elif AttribKey == "EXTRA_HEADER_SIZE":
                Base = 10
                if self._Token[0:2].upper() == "0X":
                    Base = 16
                try:
                    AttribDict[AttribKey] = int(self._Token, Base)
                    continue
                except ValueError:
                    raise Warning.Expected("Number", self.FileName, self.CurrentLineNumber)
            elif self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}:
                raise Warning.Expected("TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
            AttribDict[AttribKey] = self._Token

        return AttribDict

    ## _GetEncapsulationSec() method
    #
    #   Get encapsulation section for FILE
    #
    #   @param  self        The object pointer
    #   @param  FfsFile     for whom section is got
    #   @retval True        Successfully find section statement
    #   @retval False       Not able to find section statement
    #
    def _GetEncapsulationSec(self, FfsFileObj):
        OldPos = self.GetFileBufferPos()
        if not self._IsKeyword("SECTION"):
            if len(FfsFileObj.SectionList) == 0:
                raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)
            else:
                return False

        AlignValue = None
        if self._GetAlignment():
            if self._Token not in ALIGNMENT_NOAUTO:
                raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            AlignValue = self._Token

        if not self._GetCglSection(FfsFileObj, AlignValue):
            self.SetFileBufferPos(OldPos)
            return False
        else:
            return True

    def _GetFmp(self):
        if not self._GetNextToken():
            return False
        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[FMPPAYLOAD."):
            self.SectionParser(S)
            self._UndoToken()
            return False

        self._UndoToken()
        self._SkipToToken("[FMPPAYLOAD.", True)
        FmpUiName = self._GetUiName().upper()
        if FmpUiName in self.Profile.FmpPayloadDict:
            raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)

        FmpData = CapsulePayload()
        FmpData.UiName = FmpUiName

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)
        FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
        while self._Token in FmpKeyList:
            Name = self._Token
            FmpKeyList.remove(Name)
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if Name == 'IMAGE_TYPE_ID':
                if not self._GetNextGuid():
                    raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber)
                FmpData.ImageTypeId = self._Token
            elif Name == 'CERTIFICATE_GUID':
                if not self._GetNextGuid():
                    raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)
                FmpData.Certificate_Guid = self._Token
                if UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID:
                    raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)
            else:
                if not self._GetNextToken():
                    raise Warning.Expected("value of %s" % Name, self.FileName, self.CurrentLineNumber)
                Value = self._Token
                if Name == 'IMAGE_HEADER_INIT_VERSION':
                    if FdfParser._Verify(Name, Value, 'UINT8'):
                        FmpData.Version = Value
                elif Name == 'IMAGE_INDEX':
                    if FdfParser._Verify(Name, Value, 'UINT8'):
                        FmpData.ImageIndex = Value
                elif Name == 'HARDWARE_INSTANCE':
                    if FdfParser._Verify(Name, Value, 'UINT8'):
                        FmpData.HardwareInstance = Value
                elif Name == 'MONOTONIC_COUNT':
                    if FdfParser._Verify(Name, Value, 'UINT64'):
                        FmpData.MonotonicCount = Value
                        if FmpData.MonotonicCount.upper().startswith('0X'):
                            FmpData.MonotonicCount = int(FmpData.MonotonicCount, 16)
                        else:
                            FmpData.MonotonicCount = int(FmpData.MonotonicCount)
            if not self._GetNextToken():
                break
        else:
            self._UndoToken()

        if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid):
            EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")

        # Only the IMAGE_TYPE_ID is required item
        if FmpKeyList and 'IMAGE_TYPE_ID' in FmpKeyList:
            raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self.FileName, self.CurrentLineNumber)
        # get the Image file and Vendor code file
        self._GetFMPCapsuleData(FmpData)
        if not FmpData.ImageFile:
            raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber)
        # check whether more than one Vendor code file
        if len(FmpData.VendorCodeFile) > 1:
            raise Warning("Vendor code file max of 1 per FMP payload section.", self.FileName, self.CurrentLineNumber)
        self.Profile.FmpPayloadDict[FmpUiName] = FmpData
        return True

    ## _GetCapsule() method
    #
    #   Get capsule section contents and store its data into capsule list of self.Profile
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a capsule
    #   @retval False       Not able to find a capsule
    #
    def _GetCapsule(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[CAPSULE."):
            self.SectionParser(S)
            self._UndoToken()
            return False

        self._UndoToken()
        if not self._IsToken("[CAPSULE.", True):
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
            #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
            raise Warning.Expected("[Capsule.]", self.FileName, self.CurrentLineNumber)

        CapsuleObj = Capsule()

        CapsuleName = self._GetUiName()
        if not CapsuleName:
            raise Warning.Expected("capsule name", self.FileName, self.CurrentLineNumber)

        CapsuleObj.UiCapsuleName = CapsuleName.upper()

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        if self._IsKeyword("CREATE_FILE"):
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber)

            CapsuleObj.CreateFile = self._Token

        self._GetCapsuleStatements(CapsuleObj)
        self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj
        return True

    ## _GetCapsuleStatements() method
    #
    #   Get statements for capsule
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom statements are got
    #
    def _GetCapsuleStatements(self, Obj):
        self._GetCapsuleTokens(Obj)
        self._GetDefineStatements(Obj)
        self._GetSetStatements(Obj)
        self._GetCapsuleData(Obj)

    ## _GetCapsuleTokens() method
    #
    #   Get token statements for capsule
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom token statements are got
    #
    def _GetCapsuleTokens(self, Obj):
        if not self._GetNextToken():
            return False
        while self._Token in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:
            Name = self._Token.strip()
            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
            if not self._GetNextToken():
                raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)
            if Name == 'CAPSULE_FLAGS':
                if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
                    raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
                Value = self._Token.strip()
                while self._IsToken(TAB_COMMA_SPLIT):
                    Value += TAB_COMMA_SPLIT
                    if not self._GetNextToken():
                        raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)
                    if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
                        raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
                    Value += self._Token.strip()
            elif Name == 'OEM_CAPSULE_FLAGS':
                Value = self._Token.strip()
                if not Value.upper().startswith('0X'):
                    raise Warning.Expected("hex value starting with 0x", self.FileName, self.CurrentLineNumber)
                try:
                    Value = int(Value, 0)
                except ValueError:
                    raise Warning.Expected("hex string failed to convert to value", self.FileName, self.CurrentLineNumber)
                if not 0x0000 <= Value <= 0xFFFF:
                    raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
                Value = self._Token.strip()
            else:
                Value = self._Token.strip()
            Obj.TokensDict[Name] = Value
            if not self._GetNextToken():
                return False
        self._UndoToken()

    ## _GetCapsuleData() method
    #
    #   Get capsule data for capsule
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom capsule data are got
    #
    def _GetCapsuleData(self, Obj):
        while True:
            IsInf = self._GetInfStatement(Obj, True)
            IsFile = self._GetFileStatement(Obj, True)
            IsFv = self._GetFvStatement(Obj)
            IsFd = self._GetFdStatement(Obj)
            IsAnyFile = self._GetAnyFileStatement(Obj)
            IsAfile = self._GetAfileStatement(Obj)
            IsFmp = self._GetFmpStatement(Obj)
            if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):
                break

    ## _GetFMPCapsuleData() method
    #
    #   Get capsule data for FMP capsule
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom capsule data are got
    #
    def _GetFMPCapsuleData(self, Obj):
        while True:
            IsFv = self._GetFvStatement(Obj, True)
            IsFd = self._GetFdStatement(Obj, True)
            IsAnyFile = self._GetAnyFileStatement(Obj, True)
            if not (IsFv or IsFd or IsAnyFile):
                break

    ## _GetFvStatement() method
    #
    #   Get FV for capsule
    #
    #   @param  self        The object pointer
    #   @param  CapsuleObj  for whom FV is got
    #   @retval True        Successfully find a FV statement
    #   @retval False       Not able to find a FV statement
    #
    def _GetFvStatement(self, CapsuleObj, FMPCapsule = False):
        if not self._IsKeyword(BINARY_FILE_TYPE_FV):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)

        if self._Token.upper() not in self.Profile.FvDict:
            raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)

        myCapsuleFv = CapsuleFv()
        myCapsuleFv.FvName = self._Token
        if FMPCapsule:
            if not CapsuleObj.ImageFile:
                CapsuleObj.ImageFile.append(myCapsuleFv)
            else:
                CapsuleObj.VendorCodeFile.append(myCapsuleFv)
        else:
            CapsuleObj.CapsuleDataList.append(myCapsuleFv)
        return True

    ## _GetFdStatement() method
    #
    #   Get FD for capsule
    #
    #   @param  self        The object pointer
    #   @param  CapsuleObj  for whom FD is got
    #   @retval True        Successfully find a FD statement
    #   @retval False       Not able to find a FD statement
    #
    def _GetFdStatement(self, CapsuleObj, FMPCapsule = False):
        if not self._IsKeyword("FD"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)

        if self._Token.upper() not in self.Profile.FdDict:
            raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)

        myCapsuleFd = CapsuleFd()
        myCapsuleFd.FdName = self._Token
        if FMPCapsule:
            if not CapsuleObj.ImageFile:
                CapsuleObj.ImageFile.append(myCapsuleFd)
            else:
                CapsuleObj.VendorCodeFile.append(myCapsuleFd)
        else:
            CapsuleObj.CapsuleDataList.append(myCapsuleFd)
        return True

    def _GetFmpStatement(self, CapsuleObj):
        if not self._IsKeyword("FMP_PAYLOAD"):
            if not self._IsKeyword("FMP"):
                return False

            if not self._IsKeyword("PAYLOAD"):
                self._UndoToken()
                return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("payload name after FMP_PAYLOAD =", self.FileName, self.CurrentLineNumber)
        Payload = self._Token.upper()
        if Payload not in self.Profile.FmpPayloadDict:
            raise Warning("This FMP Payload does not exist: %s" % self._Token, self.FileName, self.CurrentLineNumber)
        CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])
        return True

    def _ParseRawFileStatement(self):
        if not self._IsKeyword("FILE"):
            return None

        if not self._IsKeyword("DATA"):
            self._UndoToken()
            return None

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)

        AnyFileName = self._Token
        self._VerifyFile(AnyFileName)

        if not os.path.isabs(AnyFileName):
            AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName)

        return AnyFileName

    ## _GetAnyFileStatement() method
    #
    #   Get AnyFile for capsule
    #
    #   @param  self        The object pointer
    #   @param  CapsuleObj  for whom AnyFile is got
    #   @retval True        Successfully find a Anyfile statement
    #   @retval False       Not able to find a AnyFile statement
    #
    def _GetAnyFileStatement(self, CapsuleObj, FMPCapsule = False):
        AnyFileName = self._ParseRawFileStatement()
        if not AnyFileName:
            return False

        myCapsuleAnyFile = CapsuleAnyFile()
        myCapsuleAnyFile.FileName = AnyFileName
        if FMPCapsule:
            if not CapsuleObj.ImageFile:
                CapsuleObj.ImageFile.append(myCapsuleAnyFile)
            else:
                CapsuleObj.VendorCodeFile.append(myCapsuleAnyFile)
        else:
            CapsuleObj.CapsuleDataList.append(myCapsuleAnyFile)
        return True

    ## _GetAfileStatement() method
    #
    #   Get Afile for capsule
    #
    #   @param  self        The object pointer
    #   @param  CapsuleObj  for whom Afile is got
    #   @retval True        Successfully find a Afile statement
    #   @retval False       Not able to find a Afile statement
    #
    def _GetAfileStatement(self, CapsuleObj):
        if not self._IsKeyword("APPEND"):
            return False

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._GetNextToken():
            raise Warning.Expected("Afile name", self.FileName, self.CurrentLineNumber)

        AfileName = self._Token
        AfileBaseName = os.path.basename(AfileName)

        if os.path.splitext(AfileBaseName)[1]  not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:
            raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \
                          self.FileName, self.CurrentLineNumber)

        if not os.path.isabs(AfileName):
            AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)
            self._VerifyFile(AfileName)
        else:
            if not os.path.exists(AfileName):
                raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)
            else:
                pass

        myCapsuleAfile = CapsuleAfile()
        myCapsuleAfile.FileName = AfileName
        CapsuleObj.CapsuleDataList.append(myCapsuleAfile)
        return True

    ## _GetRule() method
    #
    #   Get Rule section contents and store its data into rule list of self.Profile
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a Rule
    #   @retval False       Not able to find a Rule
    #
    def _GetRule(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[RULE."):
            self.SectionParser(S)
            self._UndoToken()
            return False
        self._UndoToken()
        if not self._IsToken("[Rule.", True):
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
            #        % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
            raise Warning.Expected("[Rule.]", self.FileName, self.CurrentLineNumber)

        if not self._SkipToToken(TAB_SPLIT):
            raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)

        Arch = self._SkippedChars.rstrip(TAB_SPLIT)
        if Arch.upper() not in ARCH_SET_FULL:
            raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)

        ModuleType = self._GetModuleType()

        TemplateName = ""
        if self._IsToken(TAB_SPLIT):
            if not self._GetNextWord():
                raise Warning.Expected("template name", self.FileName, self.CurrentLineNumber)
            TemplateName = self._Token

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        RuleObj = self._GetRuleFileStatements()
        RuleObj.Arch = Arch.upper()
        RuleObj.ModuleType = ModuleType
        RuleObj.TemplateName = TemplateName
        if TemplateName == '':
            self.Profile.RuleDict['RULE'             + \
                              TAB_SPLIT              + \
                              Arch.upper()           + \
                              TAB_SPLIT              + \
                              ModuleType.upper()     ] = RuleObj
        else:
            self.Profile.RuleDict['RULE'             + \
                              TAB_SPLIT              + \
                              Arch.upper()           + \
                              TAB_SPLIT              + \
                              ModuleType.upper()     + \
                              TAB_SPLIT              + \
                              TemplateName.upper() ] = RuleObj
        return True

    ## _GetModuleType() method
    #
    #   Return the module type
    #
    #   @param  self        The object pointer
    #   @retval string      module type
    #
    def _GetModuleType(self):
        if not self._GetNextWord():
            raise Warning.Expected("Module type", self.FileName, self.CurrentLineNumber)
        if self._Token.upper() not in {
                SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,
                SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER,
                SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER,
                SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_UEFI_DRIVER,
                SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED, SUP_MODULE_HOST_APPLICATION,
                TAB_DEFAULT, SUP_MODULE_BASE,
                EDK_COMPONENT_TYPE_SECURITY_CORE,
                EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER,
                EDK_COMPONENT_TYPE_PIC_PEIM,
                EDK_COMPONENT_TYPE_RELOCATABLE_PEIM, "PE32_PEIM",
                EDK_COMPONENT_TYPE_BS_DRIVER, EDK_COMPONENT_TYPE_RT_DRIVER,
                EDK_COMPONENT_TYPE_SAL_RT_DRIVER,
                EDK_COMPONENT_TYPE_APPLICATION, "ACPITABLE",
                SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,
                SUP_MODULE_MM_CORE_STANDALONE}:
            raise Warning("Unknown Module type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
        return self._Token

    ## _GetFileExtension() method
    #
    #   Return the file extension
    #
    #   @param  self        The object pointer
    #   @retval string      file name extension
    #
    def _GetFileExtension(self):
        if not self._IsToken(TAB_SPLIT):
            raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)

        Ext = ""
        if self._GetNextToken():
            if FileExtensionPattern.match(self._Token):
                Ext = self._Token
                return TAB_SPLIT + Ext
            else:
                raise Warning("Unknown file extension '%s'" % self._Token, self.FileName, self.CurrentLineNumber)

        else:
            raise Warning.Expected("file extension", self.FileName, self.CurrentLineNumber)

    ## _GetRuleFileStatement() method
    #
    #   Get rule contents
    #
    #   @param  self        The object pointer
    #   @retval Rule        Rule object
    #
    def _GetRuleFileStatements(self):
        if not self._IsKeyword("FILE"):
            raise Warning.Expected("FILE", self.FileName, self.CurrentLineNumber)

        if not self._GetNextWord():
            raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)

        Type = self._Token.strip().upper()
        if Type not in {"RAW", "FREEFORM", SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,
                        "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE, EDK_COMPONENT_TYPE_APPLICATION,
                        "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,
                        SUP_MODULE_MM_CORE_STANDALONE}:
            raise Warning("Unknown FV type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)

        if not self._IsToken(TAB_EQUAL_SPLIT):
            raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

        if not self._IsKeyword("$(NAMED_GUID)"):
            if not self._GetNextWord():
                NamedGuid = self._CurrentLine()[self.CurrentOffsetWithinLine:].split()[0].strip()
                if GlobalData.gGuidPatternEnd.match(NamedGuid):
                    self.CurrentOffsetWithinLine += len(NamedGuid)
                    self._Token = NamedGuid
                else:
                    raise Warning.Expected("$(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
            if self._Token == 'PCD':
                if not self._IsToken("("):
                    raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)
                PcdPair = self._GetNextPcdSettings()
                if not self._IsToken(")"):
                    raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)
                self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'

        NameGuid = self._Token

        KeepReloc = None
        if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):
            if self._FileCouldHaveRelocFlag(Type):
                if self._Token == 'RELOCS_STRIPPED':
                    KeepReloc = False
                else:
                    KeepReloc = True
            else:
                raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)

        KeyStringList = []
        if self._GetNextToken():
            if TokenFindPattern.match(self._Token):
                KeyStringList.append(self._Token)
                if self._IsToken(TAB_COMMA_SPLIT):
                    while self._GetNextToken():
                        if not TokenFindPattern.match(self._Token):
                            raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
                        KeyStringList.append(self._Token)

                        if not self._IsToken(TAB_COMMA_SPLIT):
                            break

            else:
                self._UndoToken()


        Fixed = False
        if self._IsKeyword("Fixed", True):
            Fixed = True

        CheckSum = False
        if self._IsKeyword("CheckSum", True):
            CheckSum = True

        AlignValue = ""
        if self._GetAlignment():
            if self._Token not in ALIGNMENTS:
                raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            #For FFS, Auto is default option same to ""
            if not self._Token == "Auto":
                AlignValue = self._Token

        if self._IsToken("{"):
            # Complex file rule expected
            NewRule = RuleComplexFile()
            NewRule.FvFileType = Type
            NewRule.NameGuid = NameGuid
            NewRule.Alignment = AlignValue
            NewRule.CheckSum = CheckSum
            NewRule.Fixed = Fixed
            NewRule.KeyStringList = KeyStringList
            if KeepReloc is not None:
                NewRule.KeepReloc = KeepReloc

            while True:
                IsEncapsulate = self._GetRuleEncapsulationSection(NewRule)
                IsLeaf = self._GetEfiSection(NewRule)
                if not IsEncapsulate and not IsLeaf:
                    break

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)

            return NewRule

        else:
            # Simple file rule expected
            if not self._GetNextWord():
                raise Warning.Expected("leaf section type", self.FileName, self.CurrentLineNumber)

            SectionName = self._Token

            if SectionName not in {
                    "COMPAT16", BINARY_FILE_TYPE_PE32,
                    BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",
                    "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,
                    BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",
                    BINARY_FILE_TYPE_SMM_DEPEX}:
                raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)


            if self._IsKeyword("Fixed", True):
                Fixed = True

            if self._IsKeyword("CheckSum", True):
                CheckSum = True

            SectAlignment = ""
            if self._GetAlignment():
                if self._Token not in ALIGNMENTS:
                    raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
                if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):
                    raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
                SectAlignment = self._Token

            Ext = None
            if self._IsToken(TAB_VALUE_SPLIT):
                Ext = self._GetFileExtension()
            elif not self._GetNextToken():
                raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)

            NewRule = RuleSimpleFile()
            NewRule.SectionType = SectionName
            NewRule.FvFileType = Type
            NewRule.NameGuid = NameGuid
            NewRule.Alignment = AlignValue
            NewRule.SectAlignment = SectAlignment
            NewRule.CheckSum = CheckSum
            NewRule.Fixed = Fixed
            NewRule.KeyStringList = KeyStringList
            if KeepReloc is not None:
                NewRule.KeepReloc = KeepReloc
            NewRule.FileExtension = Ext
            NewRule.FileName = self._Token
            return NewRule

    ## _GetEfiSection() method
    #
    #   Get section list for Rule
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom section is got
    #   @retval True        Successfully find section statement
    #   @retval False       Not able to find section statement
    #
    def _GetEfiSection(self, Obj):
        OldPos = self.GetFileBufferPos()
        EfiSectionObj = EfiSection()
        if not self._GetNextWord():
            CurrentLine = self._CurrentLine()[self.CurrentOffsetWithinLine:].split()[0].strip()
            if self._Token == '{' and Obj.FvFileType == "RAW" and TAB_SPLIT in CurrentLine:
                if self._IsToken(TAB_VALUE_SPLIT):
                    EfiSectionObj.FileExtension = self._GetFileExtension()
                elif self._GetNextToken():
                    EfiSectionObj.FileName = self._Token
                EfiSectionObj.SectionType = BINARY_FILE_TYPE_RAW
                Obj.SectionList.append(EfiSectionObj)
                return True
            else:
                return False
        SectionName = self._Token

        if SectionName not in {
                    "COMPAT16", BINARY_FILE_TYPE_PE32,
                    BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",
                    "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,
                    BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",
                    BINARY_FILE_TYPE_SMM_DEPEX, BINARY_FILE_TYPE_GUID}:
            self._UndoToken()
            return False

        if SectionName == "FV_IMAGE":
            FvImageSectionObj = FvImageSection()
            if self._IsKeyword("FV_IMAGE"):
                pass
            if self._IsToken("{"):
                FvObj = FV()
                self._GetDefineStatements(FvObj)
                self._GetBlockStatement(FvObj)
                self._GetSetStatements(FvObj)
                self._GetFvAlignment(FvObj)
                self._GetFvAttributes(FvObj)
                self._GetAprioriSection(FvObj)
                self._GetAprioriSection(FvObj)

                while True:
                    IsInf = self._GetInfStatement(FvObj)
                    IsFile = self._GetFileStatement(FvObj)
                    if not IsInf and not IsFile:
                        break

                if not self._IsToken(T_CHAR_BRACE_R):
                    raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
                FvImageSectionObj.Fv = FvObj
                FvImageSectionObj.FvName = None

            else:
                if not self._IsKeyword(BINARY_FILE_TYPE_FV):
                    raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber)
                FvImageSectionObj.FvFileType = self._Token

                if self._GetAlignment():
                    if self._Token not in ALIGNMENT_NOAUTO:
                        raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
                    FvImageSectionObj.Alignment = self._Token

                if self._IsToken(TAB_VALUE_SPLIT):
                    FvImageSectionObj.FvFileExtension = self._GetFileExtension()
                elif self._GetNextToken():
                    if self._Token not in {
                            T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,
                            BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,
                            "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,
                            BINARY_FILE_TYPE_UI, "VERSION",
                            BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,
                            BINARY_FILE_TYPE_SMM_DEPEX}:
                        FvImageSectionObj.FvFileName = self._Token
                    else:
                        self._UndoToken()
                else:
                    raise Warning.Expected("FV file name", self.FileName, self.CurrentLineNumber)

            Obj.SectionList.append(FvImageSectionObj)
            return True

        EfiSectionObj.SectionType = SectionName

        if not self._GetNextToken():
            raise Warning.Expected("file type", self.FileName, self.CurrentLineNumber)

        if self._Token == "STRING":
            if not self._RuleSectionCouldHaveString(EfiSectionObj.SectionType):
                raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)

            if not self._IsToken(TAB_EQUAL_SPLIT):
                raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)

            if not self._GetNextToken():
                raise Warning.Expected("Quoted String", self.FileName, self.CurrentLineNumber)

            if self._GetStringData():
                EfiSectionObj.StringData = self._Token

            if self._IsKeyword("BUILD_NUM"):
                if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
                    raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)

                if not self._IsToken(TAB_EQUAL_SPLIT):
                    raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                if not self._GetNextToken():
                    raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)
                EfiSectionObj.BuildNum = self._Token

        else:
            EfiSectionObj.FileType = self._Token
            self._CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)

        if self._IsKeyword("Optional"):
            if not self._RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
                raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
            EfiSectionObj.Optional = True

            if self._IsKeyword("BUILD_NUM"):
                if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
                    raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)

                if not self._IsToken(TAB_EQUAL_SPLIT):
                    raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                if not self._GetNextToken():
                    raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)
                EfiSectionObj.BuildNum = self._Token

        if self._GetAlignment():
            if self._Token not in ALIGNMENTS:
                raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
            if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):
                raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
            EfiSectionObj.Alignment = self._Token

        if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):
            if self._SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
                if self._Token == 'RELOCS_STRIPPED':
                    EfiSectionObj.KeepReloc = False
                else:
                    EfiSectionObj.KeepReloc = True
                if Obj.KeepReloc is not None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
                    raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
            else:
                raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)


        if self._IsToken(TAB_VALUE_SPLIT):
            EfiSectionObj.FileExtension = self._GetFileExtension()
        elif self._GetNextToken():
            if self._Token not in {
                    T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,
                    BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,
                    "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,
                    BINARY_FILE_TYPE_UI, "VERSION",
                    BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,
                    BINARY_FILE_TYPE_SMM_DEPEX}:

                if self._Token.startswith('PCD'):
                    self._UndoToken()
                    self._GetNextWord()

                    if self._Token == 'PCD':
                        if not self._IsToken("("):
                            raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)
                        PcdPair = self._GetNextPcdSettings()
                        if not self._IsToken(")"):
                            raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)
                        self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'

                EfiSectionObj.FileName = self._Token

            else:
                self._UndoToken()
        else:
            raise Warning.Expected("section file name", self.FileName, self.CurrentLineNumber)

        Obj.SectionList.append(EfiSectionObj)
        return True

    ## _RuleSectionCouldBeOptional() method
    #
    #   Get whether a section could be optional
    #
    #   @param  SectionType The section type to check
    #   @retval True        section could be optional
    #   @retval False       section never optional
    #
    @staticmethod
    def _RuleSectionCouldBeOptional(SectionType):
        if SectionType in {BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "RAW", BINARY_FILE_TYPE_SMM_DEPEX}:
            return True
        else:
            return False

    ## _RuleSectionCouldHaveBuildNum() method
    #
    #   Get whether a section could have build number information
    #
    #   @param  SectionType The section type to check
    #   @retval True        section could have build number information
    #   @retval False       section never have build number information
    #
    @staticmethod
    def _RuleSectionCouldHaveBuildNum(SectionType):
        if SectionType == "VERSION":
            return True
        else:
            return False

    ## _RuleSectionCouldHaveString() method
    #
    #   Get whether a section could have string
    #
    #   @param  SectionType The section type to check
    #   @retval True        section could have string
    #   @retval False       section never have string
    #
    @staticmethod
    def _RuleSectionCouldHaveString(SectionType):
        if SectionType in {BINARY_FILE_TYPE_UI, "VERSION"}:
            return True
        else:
            return False

    ## _CheckRuleSectionFileType() method
    #
    #   Get whether a section matches a file type
    #
    #   @param  self        The object pointer
    #   @param  SectionType The section type to check
    #   @param  FileType    The file type to check
    #
    def _CheckRuleSectionFileType(self, SectionType, FileType):
        WarningString = "Incorrect section file type '%s'"
        if SectionType == "COMPAT16":
            if FileType not in {"COMPAT16", "SEC_COMPAT16"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_PE32:
            if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_PE32"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_PIC:
            if FileType not in {BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_PIC}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_TE:
            if FileType not in {BINARY_FILE_TYPE_TE, "SEC_TE"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == "RAW":
            if FileType not in {BINARY_FILE_TYPE_BIN, "SEC_BIN", "RAW", "ASL", "ACPI"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_DXE_DEPEX or SectionType == BINARY_FILE_TYPE_SMM_DEPEX:
            if FileType not in {BINARY_FILE_TYPE_DXE_DEPEX, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_UI:
            if FileType not in {BINARY_FILE_TYPE_UI, "SEC_UI"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == "VERSION":
            if FileType not in {"VERSION", "SEC_VERSION"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_PEI_DEPEX:
            if FileType not in {BINARY_FILE_TYPE_PEI_DEPEX, "SEC_PEI_DEPEX"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
        elif SectionType == BINARY_FILE_TYPE_GUID:
            if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_GUID"}:
                raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)

    ## _GetRuleEncapsulationSection() method
    #
    #   Get encapsulation section for Rule
    #
    #   @param  self        The object pointer
    #   @param  theRule     for whom section is got
    #   @retval True        Successfully find section statement
    #   @retval False       Not able to find section statement
    #
    def _GetRuleEncapsulationSection(self, theRule):
        if self._IsKeyword("COMPRESS"):
            Type = "PI_STD"
            if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):
                Type = self._Token

            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)

            CompressSectionObj = CompressSection()

            CompressSectionObj.CompType = Type
            # Recursive sections...
            while True:
                IsEncapsulate = self._GetRuleEncapsulationSection(CompressSectionObj)
                IsLeaf = self._GetEfiSection(CompressSectionObj)
                if not IsEncapsulate and not IsLeaf:
                    break

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
            theRule.SectionList.append(CompressSectionObj)

            return True

        elif self._IsKeyword("GUIDED"):
            GuidValue = None
            if self._GetNextGuid():
                GuidValue = self._Token

            if self._IsKeyword("$(NAMED_GUID)"):
                GuidValue = self._Token

            AttribDict = self._GetGuidAttrib()

            if not self._IsToken("{"):
                raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
            GuidSectionObj = GuidSection()
            GuidSectionObj.NameGuid = GuidValue
            GuidSectionObj.SectionType = "GUIDED"
            GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
            GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
            GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]

            # Efi sections...
            while True:
                IsEncapsulate = self._GetRuleEncapsulationSection(GuidSectionObj)
                IsLeaf = self._GetEfiSection(GuidSectionObj)
                if not IsEncapsulate and not IsLeaf:
                    break

            if not self._IsToken(T_CHAR_BRACE_R):
                raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
            theRule.SectionList.append(GuidSectionObj)

            return True

        return False

    ## _GetOptionRom() method
    #
    #   Get OptionROM section contents and store its data into OptionROM list of self.Profile
    #
    #   @param  self        The object pointer
    #   @retval True        Successfully find a OptionROM
    #   @retval False       Not able to find a OptionROM
    #
    def _GetOptionRom(self):
        if not self._GetNextToken():
            return False

        S = self._Token.upper()
        if S.startswith(TAB_SECTION_START) and not S.startswith("[OPTIONROM."):
            self.SectionParser(S)
            self._UndoToken()
            return False

        self._UndoToken()
        if not self._IsToken("[OptionRom.", True):
            raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)

        OptRomName = self._GetUiName()

        if not self._IsToken(TAB_SECTION_END):
            raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)

        OptRomObj = OPTIONROM(OptRomName)
        self.Profile.OptRomDict[OptRomName] = OptRomObj

        while True:
            isInf = self._GetOptRomInfStatement(OptRomObj)
            isFile = self._GetOptRomFileStatement(OptRomObj)
            if not isInf and not isFile:
                break

        return True

    ## _GetOptRomInfStatement() method
    #
    #   Get INF statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom inf statement is got
    #   @retval True        Successfully find inf statement
    #   @retval False       Not able to find inf statement
    #
    def _GetOptRomInfStatement(self, Obj):
        if not self._IsKeyword("INF"):
            return False

        ffsInf = OptRomInfStatement()
        self._GetInfOptions(ffsInf)

        if not self._GetNextToken():
            raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber)
        ffsInf.InfFileName = self._Token
        if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:
            #check for file path
            ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
            if ErrorCode != 0:
                EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)

        NewFileName = ffsInf.InfFileName
        if ffsInf.OverrideGuid:
            NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path

        if not NewFileName in self.Profile.InfList:
            self.Profile.InfList.append(NewFileName)
            FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
            self.Profile.InfFileLineList.append(FileLineTuple)
            if ffsInf.UseArch:
                if ffsInf.UseArch not in self.Profile.InfDict:
                    self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]
                else:
                    self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)
            else:
                self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)


        self._GetOptRomOverrides (ffsInf)

        Obj.FfsList.append(ffsInf)
        return True

    ## _GetOptRomOverrides() method
    #
    #   Get overrides for OptROM INF & FILE
    #
    #   @param  self        The object pointer
    #   @param  FfsInfObj   for whom overrides is got
    #
    def _GetOptRomOverrides(self, Obj):
        if self._IsToken('{'):
            Overrides = OverrideAttribs()
            while True:
                if self._IsKeyword("PCI_VENDOR_ID"):
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                    if not self._GetNextHexNumber():
                        raise Warning.Expected("Hex vendor id", self.FileName, self.CurrentLineNumber)
                    Overrides.PciVendorId = self._Token
                    continue

                if self._IsKeyword("PCI_CLASS_CODE"):
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                    if not self._GetNextHexNumber():
                        raise Warning.Expected("Hex class code", self.FileName, self.CurrentLineNumber)
                    Overrides.PciClassCode = self._Token
                    continue

                if self._IsKeyword("PCI_DEVICE_ID"):
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                    # Get a list of PCI IDs
                    Overrides.PciDeviceId = ""
                    while (self._GetNextHexNumber()):
                        Overrides.PciDeviceId = "{} {}".format(Overrides.PciDeviceId, self._Token)
                    if not Overrides.PciDeviceId:
                        raise Warning.Expected("one or more Hex device ids", self.FileName, self.CurrentLineNumber)
                    continue

                if self._IsKeyword("PCI_REVISION"):
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                    if not self._GetNextHexNumber():
                        raise Warning.Expected("Hex revision", self.FileName, self.CurrentLineNumber)
                    Overrides.PciRevision = self._Token
                    continue

                if self._IsKeyword("PCI_COMPRESS"):
                    if not self._IsToken(TAB_EQUAL_SPLIT):
                        raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
                    if not self._GetNextToken():
                        raise Warning.Expected("TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)
                    Overrides.NeedCompress = self._Token.upper() == 'TRUE'
                    continue

                if self._IsToken(T_CHAR_BRACE_R):
                    break
                else:
                    EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)

            Obj.OverrideAttribs = Overrides

    ## _GetOptRomFileStatement() method
    #
    #   Get FILE statements
    #
    #   @param  self        The object pointer
    #   @param  Obj         for whom FILE statement is got
    #   @retval True        Successfully find FILE statement
    #   @retval False       Not able to find FILE statement
    #
    def _GetOptRomFileStatement(self, Obj):
        if not self._IsKeyword("FILE"):
            return False

        FfsFileObj = OptRomFileStatement()

        if not self._IsKeyword("EFI") and not self._IsKeyword(BINARY_FILE_TYPE_BIN):
            raise Warning.Expected("Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)
        FfsFileObj.FileType = self._Token

        if not self._GetNextToken():
            raise Warning.Expected("File path", self.FileName, self.CurrentLineNumber)
        FfsFileObj.FileName = self._Token
        if FfsFileObj.FileName.replace(TAB_WORKSPACE, '').find('$') == -1:
            #check for file path
            ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
            if ErrorCode != 0:
                EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)

        if FfsFileObj.FileType == 'EFI':
            self._GetOptRomOverrides(FfsFileObj)

        Obj.FfsList.append(FfsFileObj)

        return True

    ## _GetCapInFd() method
    #
    #   Get Cap list contained in FD
    #
    #   @param  self        The object pointer
    #   @param  FdName      FD name
    #   @retval CapList     List of Capsule in FD
    #
    def _GetCapInFd (self, FdName):
        CapList = []
        if FdName.upper() in self.Profile.FdDict:
            FdObj = self.Profile.FdDict[FdName.upper()]
            for elementRegion in FdObj.RegionList:
                if elementRegion.RegionType == 'CAPSULE':
                    for elementRegionData in elementRegion.RegionDataList:
                        if elementRegionData.endswith(".cap"):
                            continue
                        if elementRegionData is not None and elementRegionData.upper() not in CapList:
                            CapList.append(elementRegionData.upper())
        return CapList

    ## _GetReferencedFdCapTuple() method
    #
    #   Get FV and FD list referenced by a capsule image
    #
    #   @param  self        The object pointer
    #   @param  CapObj      Capsule section to be searched
    #   @param  RefFdList   referenced FD by section
    #   @param  RefFvList   referenced FV by section
    #
    def _GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):
        for CapsuleDataObj in CapObj.CapsuleDataList:
            if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName is not None and CapsuleDataObj.FvName.upper() not in RefFvList:
                RefFvList.append (CapsuleDataObj.FvName.upper())
            elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName is not None and CapsuleDataObj.FdName.upper() not in RefFdList:
                RefFdList.append (CapsuleDataObj.FdName.upper())
            elif CapsuleDataObj.Ffs is not None:
                if isinstance(CapsuleDataObj.Ffs, FileStatement):
                    if CapsuleDataObj.Ffs.FvName is not None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:
                        RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())
                    elif CapsuleDataObj.Ffs.FdName is not None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:
                        RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())
                    else:
                        self._GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)

    ## _GetFvInFd() method
    #
    #   Get FV list contained in FD
    #
    #   @param  self        The object pointer
    #   @param  FdName      FD name
    #   @retval FvList      list of FV in FD
    #
    def _GetFvInFd (self, FdName):
        FvList = []
        if FdName.upper() in self.Profile.FdDict:
            FdObj = self.Profile.FdDict[FdName.upper()]
            for elementRegion in FdObj.RegionList:
                if elementRegion.RegionType == BINARY_FILE_TYPE_FV:
                    for elementRegionData in elementRegion.RegionDataList:
                        if elementRegionData.endswith(".fv"):
                            continue
                        if elementRegionData is not None and elementRegionData.upper() not in FvList:
                            FvList.append(elementRegionData.upper())
        return FvList

    ## _GetReferencedFdFvTuple() method
    #
    #   Get FD and FV list referenced by a FFS file
    #
    #   @param  self        The object pointer
    #   @param  FfsFile     contains sections to be searched
    #   @param  RefFdList   referenced FD by section
    #   @param  RefFvList   referenced FV by section
    #
    def _GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
        for FfsObj in FvObj.FfsList:
            if isinstance(FfsObj, FileStatement):
                if FfsObj.FvName is not None and FfsObj.FvName.upper() not in RefFvList:
                    RefFvList.append(FfsObj.FvName.upper())
                elif FfsObj.FdName is not None and FfsObj.FdName.upper() not in RefFdList:
                    RefFdList.append(FfsObj.FdName.upper())
                else:
                    self._GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)

    ## _GetReferencedFdFvTupleFromSection() method
    #
    #   Get FD and FV list referenced by a FFS section
    #
    #   @param  self        The object pointer
    #   @param  FfsFile     contains sections to be searched
    #   @param  FdList      referenced FD by section
    #   @param  FvList      referenced FV by section
    #
    def _GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
        SectionStack = list(FfsFile.SectionList)
        while SectionStack != []:
            SectionObj = SectionStack.pop()
            if isinstance(SectionObj, FvImageSection):
                if SectionObj.FvName is not None and SectionObj.FvName.upper() not in FvList:
                    FvList.append(SectionObj.FvName.upper())
                if SectionObj.Fv is not None and SectionObj.Fv.UiFvName is not None and SectionObj.Fv.UiFvName.upper() not in FvList:
                    FvList.append(SectionObj.Fv.UiFvName.upper())
                    self._GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)

            if isinstance(SectionObj, CompressSection) or isinstance(SectionObj, GuidSection):
                SectionStack.extend(SectionObj.SectionList)

    ## CycleReferenceCheck() method
    #
    #   Check whether cycle reference exists in FDF
    #
    #   @param  self        The object pointer
    #   @retval True        cycle reference exists
    #   @retval False       Not exists cycle reference
    #
    def CycleReferenceCheck(self):
        #
        # Check the cycle between FV and FD image
        #
        MaxLength = len (self.Profile.FvDict)
        for FvName in self.Profile.FvDict:
            LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName
            RefFvStack = set(FvName)
            FdAnalyzedList = set()

            Index = 0
            while RefFvStack and Index < MaxLength:
                Index = Index + 1
                FvNameFromStack = RefFvStack.pop()
                if FvNameFromStack.upper() in self.Profile.FvDict:
                    FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
                else:
                    continue

                RefFdList = []
                RefFvList = []
                self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)

                for RefFdName in RefFdList:
                    if RefFdName in FdAnalyzedList:
                        continue

                    LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)
                    FvInFdList = self._GetFvInFd(RefFdName)
                    if FvInFdList != []:
                        for FvNameInFd in FvInFdList:
                            LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)
                            if FvNameInFd not in RefFvStack:
                                RefFvStack.add(FvNameInFd)

                            if FvName in RefFvStack or FvNameFromStack in RefFvStack:
                                EdkLogger.info(LogStr)
                                return True
                    FdAnalyzedList.add(RefFdName)

                for RefFvName in RefFvList:
                    LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)
                    if RefFvName not in RefFvStack:
                        RefFvStack.add(RefFvName)

                    if FvName in RefFvStack or FvNameFromStack in RefFvStack:
                        EdkLogger.info(LogStr)
                        return True

        #
        # Check the cycle between Capsule and FD image
        #
        MaxLength = len (self.Profile.CapsuleDict)
        for CapName in self.Profile.CapsuleDict:
            #
            # Capsule image to be checked.
            #
            LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
            RefCapStack = {CapName}
            FdAnalyzedList = set()
            FvAnalyzedList = set()

            Index = 0
            while RefCapStack and Index < MaxLength:
                Index = Index + 1
                CapNameFromStack = RefCapStack.pop()
                if CapNameFromStack.upper() in self.Profile.CapsuleDict:
                    CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]
                else:
                    continue

                RefFvList = []
                RefFdList = []
                self._GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)

                FvListLength = 0
                FdListLength = 0
                while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):
                    for RefFdName in RefFdList:
                        if RefFdName in FdAnalyzedList:
                            continue

                        LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)
                        for CapNameInFd in self._GetCapInFd(RefFdName):
                            LogStr += "FD %s contains Capsule %s\n" % (RefFdName, CapNameInFd)
                            if CapNameInFd not in RefCapStack:
                                RefCapStack.append(CapNameInFd)

                            if CapName in RefCapStack or CapNameFromStack in RefCapStack:
                                EdkLogger.info(LogStr)
                                return True

                        for FvNameInFd in self._GetFvInFd(RefFdName):
                            LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)
                            if FvNameInFd not in RefFvList:
                                RefFvList.append(FvNameInFd)

                        FdAnalyzedList.add(RefFdName)
                    #
                    # the number of the parsed FV and FD image
                    #
                    FvListLength = len (RefFvList)
                    FdListLength = len (RefFdList)
                    for RefFvName in RefFvList:
                        if RefFvName in FvAnalyzedList:
                            continue
                        LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)
                        if RefFvName.upper() in self.Profile.FvDict:
                            FvObj = self.Profile.FvDict[RefFvName.upper()]
                        else:
                            continue
                        self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
                        FvAnalyzedList.add(RefFvName)

        return False

    def GetAllIncludedFile (self):
        global AllIncludeFileList
        return AllIncludeFileList

if __name__ == "__main__":
    import sys
    try:
        test_file = sys.argv[1]
    except IndexError as v:
        print("Usage: %s filename" % sys.argv[0])
        sys.exit(1)

    parser = FdfParser(test_file)
    try:
        parser.ParseFile()
        parser.CycleReferenceCheck()
    except Warning as X:
        print(str(X))
    else:
        print("Success!")

