## @file
# This file is used to parse DEC file. It will consumed by DecParser
#
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
'''
DecParser
'''
## Import modules
#
import Logger.Log as Logger
from Logger.ToolError import FILE_PARSE_FAILURE
from Logger.ToolError import FILE_OPEN_FAILURE
from Logger import StringTable as ST
from Logger.ToolError import FORMAT_INVALID

import Library.DataType as DT
from Library.ParserValidate import IsValidToken
from Library.ParserValidate import IsValidPath
from Library.ParserValidate import IsValidCFormatGuid
from Library.ParserValidate import IsValidIdString
from Library.ParserValidate import IsValidUserId
from Library.ParserValidate import IsValidArch
from Library.ParserValidate import IsValidWord
from Library.ParserValidate import IsValidDecVersionVal
from Parser.DecParserMisc import TOOL_NAME
from Parser.DecParserMisc import CleanString
from Parser.DecParserMisc import IsValidPcdDatum
from Parser.DecParserMisc import ParserHelper
from Parser.DecParserMisc import StripRoot
from Parser.DecParserMisc import VERSION_PATTERN
from Parser.DecParserMisc import CVAR_PATTERN
from Parser.DecParserMisc import PCD_TOKEN_PATTERN
from Parser.DecParserMisc import MACRO_PATTERN
from Parser.DecParserMisc import FileContent
from Object.Parser.DecObject import _DecComments
from Object.Parser.DecObject import DecDefineObject
from Object.Parser.DecObject import DecDefineItemObject
from Object.Parser.DecObject import DecIncludeObject
from Object.Parser.DecObject import DecIncludeItemObject
from Object.Parser.DecObject import DecLibraryclassObject
from Object.Parser.DecObject import DecLibraryclassItemObject
from Object.Parser.DecObject import DecGuidObject
from Object.Parser.DecObject import DecPpiObject
from Object.Parser.DecObject import DecProtocolObject
from Object.Parser.DecObject import DecGuidItemObject
from Object.Parser.DecObject import DecUserExtensionObject
from Object.Parser.DecObject import DecUserExtensionItemObject
from Object.Parser.DecObject import DecPcdObject
from Object.Parser.DecObject import DecPcdItemObject
from Library.Misc import GuidStructureStringToGuidString
from Library.Misc import CheckGuidRegFormat
from Library.StringUtils import ReplaceMacro
from Library.StringUtils import GetSplitValueList
from Library.StringUtils import gMACRO_PATTERN
from Library.StringUtils import ConvertSpecialChar
from Library.CommentParsing import ParsePcdErrorCode

##
# _DecBase class for parsing
#
class _DecBase:
    def __init__(self, RawData):
        self._RawData = RawData
        self._ItemDict = {}
        self._LocalMacro = {}
        #
        # Data parsed by 'self' are saved to this object
        #
        self.ItemObject = None

    def GetDataObject(self):
        return self.ItemObject

    def GetLocalMacro(self):
        return self._LocalMacro

    ## BlockStart
    #
    # Called if a new section starts
    #
    def BlockStart(self):
        self._LocalMacro = {}

    ## _CheckReDefine
    #
    # @param Key: to be checked if multi-defined
    # @param Scope: Format: [[SectionName, Arch], ...].
    #               If scope is none, use global scope
    #
    def _CheckReDefine(self, Key, Scope = None):
        if not Scope:
            Scope = self._RawData.CurrentScope
            return

        SecArch = []
        #
        # Copy scope to SecArch, avoid Scope be changed outside
        #
        SecArch[0:1] = Scope[:]
        if Key not in self._ItemDict:
            self._ItemDict[Key] = [[SecArch, self._RawData.LineIndex]]
            return

        for Value in self._ItemDict[Key]:
            for SubValue in Scope:
                #
                # If current is common section
                #
                if SubValue[-1] == 'COMMON':
                    for Other in Value[0]:
                        # Key in common cannot be redefined in other arches
                        # [:-1] means stripping arch info
                        if Other[:-1] == SubValue[:-1]:
                            self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
                            return
                    continue
                CommonScope = []
                CommonScope[0:1] = SubValue
                CommonScope[-1] = 'COMMON'
                #
                # Cannot be redefined if this key already defined in COMMON Or defined in same arch
                #
                if SubValue in Value[0] or CommonScope in Value[0]:
                    self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
                    return
        self._ItemDict[Key].append([SecArch, self._RawData.LineIndex])

    ## CheckRequiredFields
    # Some sections need to check if some fields exist, define section for example
    # Derived class can re-implement, top parser will call this function after all parsing done
    #
    def CheckRequiredFields(self):
        if self._RawData:
            pass
        return True

    ## IsItemRequired
    # In DEC spec, sections must have at least one statement except user
    # extension.
    # For example: "[guids" [<attribs>] "]" <EOL> <statements>+
    # sub class can override this method to indicate if statement is a must.
    #
    def _IsStatementRequired(self):
        if self._RawData:
            pass
        return False

    def _LoggerError(self, ErrorString):
        Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
                     Line = self._RawData.LineIndex,
                     ExtraData=ErrorString + ST.ERR_DECPARSE_LINE % self._RawData.CurrentLine)

    def _ReplaceMacro(self, String):
        if gMACRO_PATTERN.findall(String):
            String = ReplaceMacro(String, self._LocalMacro, False,
                                  FileName = self._RawData.Filename,
                                  Line = ['', self._RawData.LineIndex])
            String = ReplaceMacro(String, self._RawData.Macros, False,
                                  FileName = self._RawData.Filename,
                                  Line = ['', self._RawData.LineIndex])
            MacroUsed = gMACRO_PATTERN.findall(String)
            if MacroUsed:
                Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE,
                             File=self._RawData.Filename,
                             Line = self._RawData.LineIndex,
                             ExtraData = ST.ERR_DECPARSE_MACRO_RESOLVE % (str(MacroUsed), String))
        return String

    def _MacroParser(self, String):
        TokenList = GetSplitValueList(String, ' ', 1)
        if len(TokenList) < 2 or TokenList[1] == '':
            self._LoggerError(ST.ERR_DECPARSE_MACRO_PAIR)

        TokenList = GetSplitValueList(TokenList[1], DT.TAB_EQUAL_SPLIT, 1)
        if TokenList[0] == '':
            self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME)
        elif not IsValidToken(MACRO_PATTERN, TokenList[0]):
            self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME_UPPER % TokenList[0])

        if len(TokenList) == 1:
            self._LocalMacro[TokenList[0]] = ''
        else:
            self._LocalMacro[TokenList[0]] = self._ReplaceMacro(TokenList[1])

    ## _ParseItem
    #
    # Parse specified item, this function must be derived by subclass
    #
    def _ParseItem(self):
        if self._RawData:
            pass
        #
        # Should never be called
        #
        return None


    ## _TailCommentStrategy
    #
    # This function can be derived to parse tail comment
    # default is it will not consume any lines
    #
    # @param Comment: Comment of current line
    #
    def _TailCommentStrategy(self, Comment):
        if Comment:
            pass
        if self._RawData:
            pass
        return False

    ## _StopCurrentParsing
    #
    # Called in Parse if current parsing should be stopped when encounter some
    # keyword
    # Default is section start and end
    #
    # @param Line: Current line
    #
    def _StopCurrentParsing(self, Line):
        if self._RawData:
            pass
        return Line[0] == DT.TAB_SECTION_START and Line[-1] == DT.TAB_SECTION_END

    ## _TryBackSlash
    #
    # Split comment and DEC content, concatenate lines if end of char is '\'
    #
    # @param ProcessedLine: ProcessedLine line
    # @param ProcessedComments: ProcessedComments line
    #
    def _TryBackSlash(self, ProcessedLine, ProcessedComments):
        CatLine = ''
        Comment = ''
        Line = ProcessedLine
        CommentList = ProcessedComments
        while not self._RawData.IsEndOfFile():
            if Line == '':
                self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
                break

            if Comment:
                CommentList.append((Comment, self._RawData.LineIndex))
            if Line[-1] != DT.TAB_SLASH:
                CatLine += Line
                break
            elif len(Line) < 2 or Line[-2] != ' ':
                self._LoggerError(ST.ERR_DECPARSE_BACKSLASH)
            else:
                CatLine += Line[:-1]
                Line, Comment = CleanString(self._RawData.GetNextLine())
        #
        # Reach end of content
        #
        if self._RawData.IsEndOfFile():
            if not CatLine:
                if ProcessedLine[-1] == DT.TAB_SLASH:
                    self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
                CatLine = ProcessedLine
            else:
                if not Line or Line[-1] == DT.TAB_SLASH:
                    self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
                CatLine += Line

        #
        # All MACRO values defined by the DEFINE statements in any section
        # (except [Userextensions] sections for Intel) of the INF or DEC file
        # must be expanded before processing of the file.
        #
        __IsReplaceMacro = True
        Header = self._RawData.CurrentScope[0] if self._RawData.CurrentScope else None
        if Header and len(Header) > 2:
            if Header[0].upper() == 'USEREXTENSIONS' and not (Header[1] == 'TianoCore' and Header[2] == '"ExtraFiles"'):
                __IsReplaceMacro = False
        if __IsReplaceMacro:
            self._RawData.CurrentLine = self._ReplaceMacro(CatLine)
        else:
            self._RawData.CurrentLine = CatLine

        return CatLine, CommentList

    ## Parse
    # This is a template method in which other member functions which might
    # override by sub class are called. It is responsible for reading file
    # line by line, and call other member functions to parse. This function
    # should not be re-implement by sub class.
    #
    def Parse(self):
        HeadComments = []
        TailComments = []

        #======================================================================
        # CurComments may pointer to HeadComments or TailComments
        #======================================================================
        CurComments = HeadComments
        CurObj = None
        ItemNum = 0
        FromBuf = False

        #======================================================================
        # Used to report error information if empty section found
        #======================================================================
        Index = self._RawData.LineIndex
        LineStr = self._RawData.CurrentLine
        while not self._RawData.IsEndOfFile() or self._RawData.NextLine:
            if self._RawData.NextLine:
                #==============================================================
                # Have processed line in buffer
                #==============================================================
                Line = self._RawData.NextLine
                HeadComments.extend(self._RawData.HeadComment)
                TailComments.extend(self._RawData.TailComment)
                self._RawData.ResetNext()
                Comment = ''
                FromBuf = True
            else:
                #==============================================================
                # No line in buffer, read next line
                #==============================================================
                Line, Comment = CleanString(self._RawData.GetNextLine())
                FromBuf = False
            if Line:
                if not FromBuf and CurObj and TailComments:
                    #==========================================================
                    # Set tail comments to previous statement if not empty.
                    #==========================================================
                    CurObj.SetTailComment(CurObj.GetTailComment()+TailComments)

                if not FromBuf:
                    del TailComments[:]
                CurComments = TailComments
                Comments = []
                if Comment:
                    Comments = [(Comment, self._RawData.LineIndex)]

                #==============================================================
                # Try if last char of line has backslash
                #==============================================================
                Line, Comments = self._TryBackSlash(Line, Comments)
                CurComments.extend(Comments)

                #==============================================================
                # Macro found
                #==============================================================
                if Line.startswith('DEFINE '):
                    self._MacroParser(Line)
                    del HeadComments[:]
                    del TailComments[:]
                    CurComments = HeadComments
                    continue

                if self._StopCurrentParsing(Line):
                    #==========================================================
                    # This line does not belong to this parse,
                    # Save it, can be used by next parse
                    #==========================================================
                    self._RawData.SetNext(Line, HeadComments, TailComments)
                    break

                Obj = self._ParseItem()
                ItemNum += 1
                if Obj:
                    Obj.SetHeadComment(Obj.GetHeadComment()+HeadComments)
                    Obj.SetTailComment(Obj.GetTailComment()+TailComments)
                    del HeadComments[:]
                    del TailComments[:]
                    CurObj = Obj
                else:
                    CurObj = None
            else:
                if id(CurComments) == id(TailComments):
                    #==========================================================
                    # Check if this comment belongs to tail comment
                    #==========================================================
                    if not self._TailCommentStrategy(Comment):
                        CurComments = HeadComments

                if Comment:
                    CurComments.append(((Comment, self._RawData.LineIndex)))
                else:
                    del CurComments[:]

        if self._IsStatementRequired() and ItemNum == 0:
            Logger.Error(
                    TOOL_NAME, FILE_PARSE_FAILURE,
                    File=self._RawData.Filename,
                    Line=Index,
                    ExtraData=ST.ERR_DECPARSE_STATEMENT_EMPTY % LineStr
            )

## _DecDefine
# Parse define section
#
class _DecDefine(_DecBase):
    def __init__(self, RawData):
        _DecBase.__init__(self, RawData)
        self.ItemObject = DecDefineObject(RawData.Filename)
        self._LocalMacro = self._RawData.Macros
        self._DefSecNum = 0

        #
        # Each field has a function to validate
        #
        self.DefineValidation = {
            DT.TAB_DEC_DEFINES_DEC_SPECIFICATION   :   self._SetDecSpecification,
            DT.TAB_DEC_DEFINES_PACKAGE_NAME        :   self._SetPackageName,
            DT.TAB_DEC_DEFINES_PACKAGE_GUID        :   self._SetPackageGuid,
            DT.TAB_DEC_DEFINES_PACKAGE_VERSION     :   self._SetPackageVersion,
            DT.TAB_DEC_DEFINES_PKG_UNI_FILE        :   self._SetPackageUni,
        }

    def BlockStart(self):
        self._DefSecNum += 1
        if self._DefSecNum > 1:
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_MULTISEC)

    ## CheckRequiredFields
    #
    # Check required fields: DEC_SPECIFICATION, PACKAGE_NAME
    #                        PACKAGE_GUID, PACKAGE_VERSION
    #
    def CheckRequiredFields(self):
        Ret = False
        if self.ItemObject.GetPackageSpecification() == '':
            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
                         ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
        elif self.ItemObject.GetPackageName() == '':
            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
                         ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
        elif self.ItemObject.GetPackageGuid() == '':
            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
                         ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
        elif self.ItemObject.GetPackageVersion() == '':
            Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
                         ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
        else:
            Ret = True
        return Ret

    def _ParseItem(self):
        Line = self._RawData.CurrentLine
        TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
        if TokenList[0] == DT.TAB_DEC_DEFINES_PKG_UNI_FILE:
            self.DefineValidation[TokenList[0]](TokenList[1])
        elif len(TokenList) < 2:
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_FORMAT)
        elif TokenList[0] not in self.DefineValidation:
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_UNKNOWKEY % TokenList[0])
        else:
            self.DefineValidation[TokenList[0]](TokenList[1])

        DefineItem = DecDefineItemObject()
        DefineItem.Key   = TokenList[0]
        DefineItem.Value = TokenList[1]
        self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope)
        return DefineItem

    def _SetDecSpecification(self, Token):
        if self.ItemObject.GetPackageSpecification():
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
        if not IsValidToken('0[xX][0-9a-fA-F]{8}', Token):
            if not IsValidDecVersionVal(Token):
                self._LoggerError(ST.ERR_DECPARSE_DEFINE_SPEC)
        self.ItemObject.SetPackageSpecification(Token)

    def _SetPackageName(self, Token):
        if self.ItemObject.GetPackageName():
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
        if not IsValidWord(Token):
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGNAME)
        self.ItemObject.SetPackageName(Token)

    def _SetPackageGuid(self, Token):
        if self.ItemObject.GetPackageGuid():
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
        if not CheckGuidRegFormat(Token):
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)
        self.ItemObject.SetPackageGuid(Token)

    def _SetPackageVersion(self, Token):
        if self.ItemObject.GetPackageVersion():
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
        if not IsValidToken(VERSION_PATTERN, Token):
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGVERSION)
        else:
            if not DT.TAB_SPLIT in Token:
                Token = Token + '.0'
            self.ItemObject.SetPackageVersion(Token)

    def _SetPackageUni(self, Token):
        if self.ItemObject.GetPackageUniFile():
            self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PKG_UNI_FILE)
        self.ItemObject.SetPackageUniFile(Token)

## _DecInclude
#
# Parse include section
#
class _DecInclude(_DecBase):
    def __init__(self, RawData):
        _DecBase.__init__(self, RawData)
        self.ItemObject = DecIncludeObject(RawData.Filename)

    def _ParseItem(self):
        Line = self._RawData.CurrentLine

        if not IsValidPath(Line, self._RawData.PackagePath):
            self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Line)

        Item = DecIncludeItemObject(StripRoot(self._RawData.PackagePath, Line), self._RawData.PackagePath)
        self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
        return Item

## _DecLibraryclass
#
# Parse library class section
#
class _DecLibraryclass(_DecBase):
    def __init__(self, RawData):
        _DecBase.__init__(self, RawData)
        self.ItemObject = DecLibraryclassObject(RawData.Filename)

    def _ParseItem(self):
        Line = self._RawData.CurrentLine
        TokenList = GetSplitValueList(Line, DT.TAB_VALUE_SPLIT)
        if len(TokenList) != 2:
            self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_SPLIT)
        if TokenList[0] == '' or TokenList[1] == '':
            self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_EMPTY)
        if not IsValidToken('[A-Z][0-9A-Za-z]*', TokenList[0]):
            self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_LIB)

        self._CheckReDefine(TokenList[0])

        Value = TokenList[1]
        #
        # Must end with .h
        #
        if not Value.endswith('.h'):
            self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_PATH_EXT)

        #
        # Path must be existed
        #
        if not IsValidPath(Value, self._RawData.PackagePath):
            self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Value)

        Item = DecLibraryclassItemObject(TokenList[0], StripRoot(self._RawData.PackagePath, Value),
                                         self._RawData.PackagePath)
        self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
        return Item

## _DecPcd
#
# Parse PCD section
#
class _DecPcd(_DecBase):
    def __init__(self, RawData):
        _DecBase.__init__(self, RawData)
        self.ItemObject = DecPcdObject(RawData.Filename)
        #
        # Used to check duplicate token
        # Key is token space and token number (integer), value is C name
        #
        self.TokenMap = {}

    def _ParseItem(self):
        Line = self._RawData.CurrentLine
        TokenList = Line.split(DT.TAB_VALUE_SPLIT)
        if len(TokenList) < 4:
            self._LoggerError(ST.ERR_DECPARSE_PCD_SPLIT)

        #
        # Token space guid C name
        #
        PcdName = GetSplitValueList(TokenList[0], DT.TAB_SPLIT)
        if len(PcdName) != 2 or PcdName[0] == '' or PcdName[1] == '':
            self._LoggerError(ST.ERR_DECPARSE_PCD_NAME)

        Guid = PcdName[0]
        if not IsValidToken(CVAR_PATTERN, Guid):
            self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)

        #
        # PCD C name
        #
        CName = PcdName[1]
        if not IsValidToken(CVAR_PATTERN, CName):
            self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_PCDCNAME)

        self._CheckReDefine(Guid + DT.TAB_SPLIT + CName)

        #
        # Default value, may be C array, string or number
        #
        Data = DT.TAB_VALUE_SPLIT.join(TokenList[1:-2]).strip()

        #
        # PCD data type
        #
        DataType = TokenList[-2].strip()
        Valid, Cause = IsValidPcdDatum(DataType, Data)
        if not Valid:
            self._LoggerError(Cause)
        PcdType = self._RawData.CurrentScope[0][0]
        if PcdType == DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() and DataType != 'BOOLEAN':
            self._LoggerError(ST.ERR_DECPARSE_PCD_FEATUREFLAG)
        #
        # Token value is the last element in list.
        #
        Token = TokenList[-1].strip()
        if not IsValidToken(PCD_TOKEN_PATTERN, Token):
            self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN % Token)
        elif not Token.startswith('0x') and not Token.startswith('0X'):
            if int(Token) > 4294967295:
                self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token)
            Token = '0x%x' % int(Token)

        IntToken = int(Token, 0)
        if (Guid, IntToken) in self.TokenMap:
            if self.TokenMap[Guid, IntToken] != CName:
                self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_UNIQUE%(Token))
        else:
            self.TokenMap[Guid, IntToken] = CName

        Item = DecPcdItemObject(Guid, CName, Data, DataType, Token)
        self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
        return Item

## _DecGuid
#
# Parse GUID, PPI, Protocol section
#
class _DecGuid(_DecBase):
    def __init__(self, RawData):
        _DecBase.__init__(self, RawData)
        self.GuidObj = DecGuidObject(RawData.Filename)
        self.PpiObj = DecPpiObject(RawData.Filename)
        self.ProtocolObj = DecProtocolObject(RawData.Filename)
        self.ObjectDict = \
        {
            DT.TAB_GUIDS.upper()     :   self.GuidObj,
            DT.TAB_PPIS.upper()      :   self.PpiObj,
            DT.TAB_PROTOCOLS.upper() :   self.ProtocolObj
        }

    def GetDataObject(self):
        if self._RawData.CurrentScope:
            return self.ObjectDict[self._RawData.CurrentScope[0][0]]
        return None

    def GetGuidObject(self):
        return self.GuidObj

    def GetPpiObject(self):
        return self.PpiObj

    def GetProtocolObject(self):
        return self.ProtocolObj

    def _ParseItem(self):
        Line = self._RawData.CurrentLine
        TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
        if len(TokenList) < 2:
            self._LoggerError(ST.ERR_DECPARSE_CGUID)
        if TokenList[0] == '':
            self._LoggerError(ST.ERR_DECPARSE_CGUID_NAME)
        if TokenList[1] == '':
            self._LoggerError(ST.ERR_DECPARSE_CGUID_GUID)
        if not IsValidToken(CVAR_PATTERN, TokenList[0]):
            self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)

        self._CheckReDefine(TokenList[0])

        if TokenList[1][0] != '{':
            if not CheckGuidRegFormat(TokenList[1]):
                self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)
            GuidString = TokenList[1]
        else:
            #
            # Convert C format GUID to GUID string and Simple error check
            #
            GuidString = GuidStructureStringToGuidString(TokenList[1])
            if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidString == '':
                self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)

            #
            # Check C format GUID
            #
            if not IsValidCFormatGuid(TokenList[1]):
                self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)

        Item = DecGuidItemObject(TokenList[0], TokenList[1], GuidString)
        ItemObject = self.ObjectDict[self._RawData.CurrentScope[0][0]]
        ItemObject.AddItem(Item, self._RawData.CurrentScope)
        return Item

## _DecUserExtension
#
# Parse user extension section
#
class _DecUserExtension(_DecBase):
    def __init__(self, RawData):
        _DecBase.__init__(self, RawData)
        self.ItemObject = DecUserExtensionObject(RawData.Filename)
        self._Headers = []
        self._CurItems = []

    def BlockStart(self):
        self._CurItems = []
        for Header in self._RawData.CurrentScope:
            if Header in self._Headers:
                self._LoggerError(ST.ERR_DECPARSE_UE_DUPLICATE)
            else:
                self._Headers.append(Header)

            for Item in self._CurItems:
                if Item.UserId == Header[1] and Item.IdString == Header[2]:
                    Item.ArchAndModuleType.append(Header[3])
                    break
            else:
                Item = DecUserExtensionItemObject()
                Item.UserId = Header[1]
                Item.IdString = Header[2]
                Item.ArchAndModuleType.append(Header[3])
                self._CurItems.append(Item)
                self.ItemObject.AddItem(Item, None)
        self._LocalMacro = {}

    def _ParseItem(self):
        Line = self._RawData.CurrentLine
        Item = None
        for Item in self._CurItems:
            if Item.UserString:
                Item.UserString = '\n'.join([Item.UserString, Line])
            else:
                Item.UserString = Line
        return Item

## Dec
#
# Top dec parser
#
class Dec(_DecBase, _DecComments):
    def __init__(self, DecFile, Parse = True):
        try:
            Content = ConvertSpecialChar(open(DecFile, 'r').readlines())
        except BaseException:
            Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile,
                         ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile)

        #
        # Pre-parser for Private section
        #
        self._Private = ''
        __IsFoundPrivate = False
        NewContent = []
        for Line in Content:
            Line = Line.strip()
            if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):
                __IsFoundPrivate = True
            if Line.startswith(DT.TAB_SECTION_START) and Line.endswith(DT.TAB_SECTION_END)\
               and not Line.endswith(DT.TAB_PRIVATE + DT.TAB_SECTION_END):
                __IsFoundPrivate = False
            if __IsFoundPrivate:
                self._Private += Line + '\r'
            if not __IsFoundPrivate:
                NewContent.append(Line + '\r')

        RawData = FileContent(DecFile, NewContent)

        _DecComments.__init__(self)
        _DecBase.__init__(self, RawData)

        self.BinaryHeadComment = []
        self.PcdErrorCommentDict = {}

        self._Define    = _DecDefine(RawData)
        self._Include   = _DecInclude(RawData)
        self._Guid      = _DecGuid(RawData)
        self._LibClass  = _DecLibraryclass(RawData)
        self._Pcd       = _DecPcd(RawData)
        self._UserEx    = _DecUserExtension(RawData)

        #
        # DEC file supported data types (one type per section)
        #
        self._SectionParser = {
            DT.TAB_DEC_DEFINES.upper()                     :   self._Define,
            DT.TAB_INCLUDES.upper()                        :   self._Include,
            DT.TAB_LIBRARY_CLASSES.upper()                 :   self._LibClass,
            DT.TAB_GUIDS.upper()                           :   self._Guid,
            DT.TAB_PPIS.upper()                            :   self._Guid,
            DT.TAB_PROTOCOLS.upper()                       :   self._Guid,
            DT.TAB_PCDS_FIXED_AT_BUILD_NULL.upper()        :   self._Pcd,
            DT.TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper()   :   self._Pcd,
            DT.TAB_PCDS_FEATURE_FLAG_NULL.upper()          :   self._Pcd,
            DT.TAB_PCDS_DYNAMIC_NULL.upper()               :   self._Pcd,
            DT.TAB_PCDS_DYNAMIC_EX_NULL.upper()            :   self._Pcd,
            DT.TAB_USER_EXTENSIONS.upper()                 :   self._UserEx
        }

        if Parse:
            self.ParseDecComment()
            self.Parse()
            #
            # Parsing done, check required fields
            #
            self.CheckRequiredFields()

    def CheckRequiredFields(self):
        for SectionParser in self._SectionParser.values():
            if not SectionParser.CheckRequiredFields():
                return False
        return True

    ##
    # Parse DEC file
    #
    def ParseDecComment(self):
        IsFileHeader = False
        IsBinaryHeader = False
        FileHeaderLineIndex = -1
        BinaryHeaderLineIndex = -1
        TokenSpaceGuidCName = ''

        #
        # Parse PCD error comment section
        #
        while not self._RawData.IsEndOfFile():
            self._RawData.CurrentLine = self._RawData.GetNextLine()
            if self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT) and \
                DT.TAB_SECTION_START in self._RawData.CurrentLine and \
                DT.TAB_SECTION_END in self._RawData.CurrentLine:
                self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()

                if self._RawData.CurrentLine[0] == DT.TAB_SECTION_START and \
                    self._RawData.CurrentLine[-1] == DT.TAB_SECTION_END:
                    RawSection = self._RawData.CurrentLine[1:-1].strip()
                    if RawSection.upper().startswith(DT.TAB_PCD_ERROR.upper()+'.'):
                        TokenSpaceGuidCName = RawSection.split(DT.TAB_PCD_ERROR+'.')[1].strip()
                        continue

            if TokenSpaceGuidCName and self._RawData.CurrentLine.startswith(DT.TAB_COMMENT_SPLIT):
                self._RawData.CurrentLine = self._RawData.CurrentLine.replace(DT.TAB_COMMENT_SPLIT, '').strip()
                if self._RawData.CurrentLine != '':
                    if DT.TAB_VALUE_SPLIT not in self._RawData.CurrentLine:
                        self._LoggerError(ST.ERR_DECPARSE_PCDERRORMSG_MISS_VALUE_SPLIT)

                    PcdErrorNumber, PcdErrorMsg = GetSplitValueList(self._RawData.CurrentLine, DT.TAB_VALUE_SPLIT, 1)
                    PcdErrorNumber = ParsePcdErrorCode(PcdErrorNumber, self._RawData.Filename, self._RawData.LineIndex)
                    if not PcdErrorMsg.strip():
                        self._LoggerError(ST.ERR_DECPARSE_PCD_MISS_ERRORMSG)

                    self.PcdErrorCommentDict[(TokenSpaceGuidCName, PcdErrorNumber)] = PcdErrorMsg.strip()
            else:
                TokenSpaceGuidCName = ''

        self._RawData.LineIndex = 0
        self._RawData.CurrentLine = ''
        self._RawData.NextLine = ''

        while not self._RawData.IsEndOfFile():
            Line, Comment = CleanString(self._RawData.GetNextLine())

            #
            # Header must be pure comment
            #
            if Line != '':
                self._RawData.UndoNextLine()
                break

            if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) and Comment.find(DT.TAB_HEADER_COMMENT) > 0 \
                and not Comment[2:Comment.find(DT.TAB_HEADER_COMMENT)].strip():
                IsFileHeader = True
                IsBinaryHeader = False
                FileHeaderLineIndex = self._RawData.LineIndex

            #
            # Get license information before '@file'
            #
            if not IsFileHeader and not IsBinaryHeader and Comment and Comment.startswith(DT.TAB_COMMENT_SPLIT) and \
            DT.TAB_BINARY_HEADER_COMMENT not in Comment:
                self._HeadComment.append((Comment, self._RawData.LineIndex))

            if Comment and IsFileHeader and \
            not(Comment.startswith(DT.TAB_SPECIAL_COMMENT) \
            and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0):
                self._HeadComment.append((Comment, self._RawData.LineIndex))
            #
            # Double '#' indicates end of header comments
            #
            if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsFileHeader:
                IsFileHeader = False
                continue

            if Comment and Comment.startswith(DT.TAB_SPECIAL_COMMENT) \
            and Comment.find(DT.TAB_BINARY_HEADER_COMMENT) > 0:
                IsBinaryHeader = True
                IsFileHeader = False
                BinaryHeaderLineIndex = self._RawData.LineIndex

            if Comment and IsBinaryHeader:
                self.BinaryHeadComment.append((Comment, self._RawData.LineIndex))
            #
            # Double '#' indicates end of header comments
            #
            if (not Comment or Comment == DT.TAB_SPECIAL_COMMENT) and IsBinaryHeader:
                IsBinaryHeader = False
                break

            if FileHeaderLineIndex > -1 and not IsFileHeader and not IsBinaryHeader:
                break

        if FileHeaderLineIndex > BinaryHeaderLineIndex and FileHeaderLineIndex > -1 and BinaryHeaderLineIndex > -1:
            self._LoggerError(ST.ERR_BINARY_HEADER_ORDER)

        if FileHeaderLineIndex == -1:
#            self._LoggerError(ST.ERR_NO_SOURCE_HEADER)
            Logger.Error(TOOL_NAME, FORMAT_INVALID,
                         ST.ERR_NO_SOURCE_HEADER,
                         File=self._RawData.Filename)
        return

    def _StopCurrentParsing(self, Line):
        return False

    def _ParseItem(self):
        self._SectionHeaderParser()
        if len(self._RawData.CurrentScope) == 0:
            self._LoggerError(ST.ERR_DECPARSE_SECTION_EMPTY)
        SectionObj = self._SectionParser[self._RawData.CurrentScope[0][0]]
        SectionObj.BlockStart()
        SectionObj.Parse()
        return SectionObj.GetDataObject()

    def _UserExtentionSectionParser(self):
        self._RawData.CurrentScope = []
        ArchList = set()
        Section = self._RawData.CurrentLine[1:-1]
        Par = ParserHelper(Section, self._RawData.Filename)
        while not Par.End():
            #
            # User extention
            #
            Token = Par.GetToken()
            if Token.upper() != DT.TAB_USER_EXTENSIONS.upper():
                self._LoggerError(ST.ERR_DECPARSE_SECTION_UE)
            UserExtension = Token.upper()
            Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)

            #
            # UserID
            #
            Token = Par.GetToken()
            if not IsValidUserId(Token):
                self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_USERID)
            UserId = Token
            Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
            #
            # IdString
            #
            Token = Par.GetToken()
            if not IsValidIdString(Token):
                self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_IDSTRING)
            IdString = Token
            Arch = 'COMMON'
            if Par.Expect(DT.TAB_SPLIT):
                Token = Par.GetToken()
                Arch = Token.upper()
                if not IsValidArch(Arch):
                    self._LoggerError(ST.ERR_DECPARSE_ARCH)
            ArchList.add(Arch)
            if [UserExtension, UserId, IdString, Arch] not in \
                self._RawData.CurrentScope:
                self._RawData.CurrentScope.append(
                    [UserExtension, UserId, IdString, Arch]
                )
            if not Par.Expect(DT.TAB_COMMA_SPLIT):
                break
            elif Par.End():
                self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMA)
        Par.AssertEnd(ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
        if 'COMMON' in ArchList and len(ArchList) > 1:
            self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)

    ## Section header parser
    #
    # The section header is always in following format:
    #
    # [section_name.arch<.platform|module_type>]
    #
    def _SectionHeaderParser(self):
        if self._RawData.CurrentLine[0] != DT.TAB_SECTION_START or self._RawData.CurrentLine[-1] != DT.TAB_SECTION_END:
            self._LoggerError(ST.ERR_DECPARSE_SECTION_IDENTIFY)

        RawSection = self._RawData.CurrentLine[1:-1].strip().upper()
        #
        # Check defines section which is only allowed to occur once and
        # no arch can be followed
        #
        if RawSection.startswith(DT.TAB_DEC_DEFINES.upper()):
            if RawSection != DT.TAB_DEC_DEFINES.upper():
                self._LoggerError(ST.ERR_DECPARSE_DEFINE_SECNAME)
        #
        # Check user extension section
        #
        if RawSection.startswith(DT.TAB_USER_EXTENSIONS.upper()):
            return self._UserExtentionSectionParser()
        self._RawData.CurrentScope = []
        SectionNames = []
        ArchList = set()
        for Item in GetSplitValueList(RawSection, DT.TAB_COMMA_SPLIT):
            if Item == '':
                self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)

            ItemList = GetSplitValueList(Item, DT.TAB_SPLIT)
            #
            # different types of PCD are permissible in one section
            #
            SectionName = ItemList[0]
            if SectionName not in self._SectionParser:
                self._LoggerError(ST.ERR_DECPARSE_SECTION_UNKNOW % SectionName)
            if SectionName not in SectionNames:
                SectionNames.append(SectionName)
            #
            # In DEC specification, all section headers have at most two part:
            # SectionName.Arch except UserExtension
            #
            if len(ItemList) > 2:
                self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBTOOMANY % Item)

            if DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() in SectionNames and len(SectionNames) > 1:
                self._LoggerError(ST.ERR_DECPARSE_SECTION_FEATUREFLAG % DT.TAB_PCDS_FEATURE_FLAG_NULL)
            #
            # S1 is always Arch
            #
            if len(ItemList) > 1:
                Str1 = ItemList[1]
                if not IsValidArch(Str1):
                    self._LoggerError(ST.ERR_DECPARSE_ARCH)
            else:
                Str1 = 'COMMON'
            ArchList.add(Str1)

            if [SectionName, Str1] not in self._RawData.CurrentScope:
                self._RawData.CurrentScope.append([SectionName, Str1])
        #
        # 'COMMON' must not be used with specific ARCHs at the same section
        #
        if 'COMMON' in ArchList and len(ArchList) > 1:
            self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)
        if len(SectionNames) == 0:
            self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)
        if len(SectionNames) != 1:
            for Sec in SectionNames:
                if not Sec.startswith(DT.TAB_PCDS.upper()):
                    self._LoggerError(ST.ERR_DECPARSE_SECTION_NAME % str(SectionNames))

    def GetDefineSectionMacro(self):
        return self._Define.GetLocalMacro()
    def GetDefineSectionObject(self):
        return self._Define.GetDataObject()
    def GetIncludeSectionObject(self):
        return self._Include.GetDataObject()
    def GetGuidSectionObject(self):
        return self._Guid.GetGuidObject()
    def GetProtocolSectionObject(self):
        return self._Guid.GetProtocolObject()
    def GetPpiSectionObject(self):
        return self._Guid.GetPpiObject()
    def GetLibraryClassSectionObject(self):
        return self._LibClass.GetDataObject()
    def GetPcdSectionObject(self):
        return self._Pcd.GetDataObject()
    def GetUserExtensionSectionObject(self):
        return self._UserEx.GetDataObject()
    def GetPackageSpecification(self):
        return self._Define.GetDataObject().GetPackageSpecification()
    def GetPackageName(self):
        return self._Define.GetDataObject().GetPackageName()
    def GetPackageGuid(self):
        return self._Define.GetDataObject().GetPackageGuid()
    def GetPackageVersion(self):
        return self._Define.GetDataObject().GetPackageVersion()
    def GetPackageUniFile(self):
        return self._Define.GetDataObject().GetPackageUniFile()
    def GetPrivateSections(self):
        return self._Private
