## @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 long(Token) > 4294967295:
                self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token)
            Token = hex(long(Token))[:-1]
        
        IntToken = long(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 extention 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, 'rb').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 UserExtention
            #
            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
