## @file
# This file is used to parse DEC file. It will consumed by DecParser
#
# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available
# under the terms and conditions of the BSD License which accompanies this
# distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
'''
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
