## @file
# This file contained the parser for [Guids], [Ppis], [Protocols] sections in INF file 
#
# Copyright (c) 2011 - 2017, 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.
#
'''
InfGuidPpiProtocolSectionParser
'''
##
# Import Modules
#

import Logger.Log as Logger
from Logger import StringTable as ST
from Logger.ToolError import FORMAT_INVALID
from Parser.InfParserMisc import InfExpandMacro
from Library import DataType as DT
from Library import GlobalData
from Library.Parsing import MacroParser
from Library.Misc import GetSplitValueList
from Library.ParserValidate import IsValidIdString
from Library.ParserValidate import IsValidUserId
from Library.ParserValidate import IsValidArch
from Parser.InfParserMisc import InfParserSectionRoot

class InfGuidPpiProtocolSectionParser(InfParserSectionRoot):
    ## InfGuidParser
    #
    #
    def InfGuidParser(self, SectionString, InfSectionObject, FileName):
        #
        # Macro defined in this section 
        #
        SectionMacros = {}
        ValueList = []
        GuidList = []
        CommentsList = []
        CurrentLineVar = None
        #
        # Parse section content
        #
        for Line in SectionString:
            LineContent = Line[0]
            LineNo = Line[1]

            if LineContent.strip() == '':
                CommentsList = []
                continue

            if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
                CommentsList.append(Line)
                continue
            else:
                #
                # Encounter a GUID entry
                #
                if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
                    CommentsList.append((
                            LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):],
                            LineNo))
                    LineContent = \
                            LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]

            if LineContent != '':
                #
                # Find Macro
                #
                Name, Value = MacroParser((LineContent, LineNo),
                                          FileName,
                                          DT.MODEL_EFI_GUID,
                                          self.FileLocalMacros)
                if Name is not None:
                    SectionMacros[Name] = Value
                    CommentsList = []
                    ValueList = []
                    continue

                TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1)
                ValueList[0:len(TokenList)] = TokenList

                #
                # Replace with Local section Macro and [Defines] section Macro.
                #            
                ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo),
                                            self.FileLocalMacros, SectionMacros, True)
                            for Value in ValueList]

                CurrentLineVar = (LineContent, LineNo, FileName)


            if len(ValueList) >= 1:
                GuidList.append((ValueList, CommentsList, CurrentLineVar))
                CommentsList = []
                ValueList = []
            continue

        #
        # Current section archs
        #    
        ArchList = []
        LineIndex = -1
        for Item in self.LastSectionHeaderContent:
            LineIndex = Item[3]
            if Item[1] not in ArchList:
                ArchList.append(Item[1])

        if not InfSectionObject.SetGuid(GuidList, Arch=ArchList):
            Logger.Error('InfParser',
                         FORMAT_INVALID,
                         ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Guid]"),
                         File=FileName,
                         Line=LineIndex)

    ## InfPpiParser
    #
    #
    def InfPpiParser(self, SectionString, InfSectionObject, FileName):
        #
        # Macro defined in this section 
        #
        SectionMacros = {}
        ValueList = []
        PpiList = []
        CommentsList = []
        CurrentLineVar = None
        #
        # Parse section content
        #
        for Line in SectionString:
            LineContent = Line[0]
            LineNo = Line[1]

            if LineContent.strip() == '':
                CommentsList = []
                continue

            if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
                CommentsList.append(Line)
                continue
            else:
                #
                # Encounter a PPI entry
                #
                if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
                    CommentsList.append((
                            LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):],
                            LineNo))
                    LineContent = \
                            LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]

            if LineContent != '':
                #
                # Find Macro
                #
                Name, Value = MacroParser((LineContent, LineNo),
                                          FileName,
                                          DT.MODEL_EFI_PPI,
                                          self.FileLocalMacros)
                if Name is not None:
                    SectionMacros[Name] = Value
                    ValueList = []
                    CommentsList = []
                    continue

                TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1)
                ValueList[0:len(TokenList)] = TokenList

                #
                # Replace with Local section Macro and [Defines] section Macro.
                #            
                ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo), self.FileLocalMacros, SectionMacros)
                            for Value in ValueList]

                CurrentLineVar = (LineContent, LineNo, FileName)

            if len(ValueList) >= 1:
                PpiList.append((ValueList, CommentsList, CurrentLineVar))
                ValueList = []
                CommentsList = []
            continue

        #
        # Current section archs
        #    
        ArchList = []
        LineIndex = -1
        for Item in self.LastSectionHeaderContent:
            LineIndex = Item[3]
            if Item[1] not in ArchList:
                ArchList.append(Item[1])

        if not InfSectionObject.SetPpi(PpiList, Arch=ArchList):
            Logger.Error('InfParser',
                         FORMAT_INVALID,
                         ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Ppis]"),
                         File=FileName,
                         Line=LineIndex)

    ## InfUserExtensionParser
    #
    #    
    def InfUserExtensionParser(self, SectionString, InfSectionObject, FileName):

        UserExtensionContent = ''

        #
        # Parse section content
        #
        for Line in SectionString:
            LineContent = Line[0]

# Comment the code to support user extension without any statement just the section header in []
#             if LineContent.strip() == '':
#                 continue

            UserExtensionContent += LineContent + DT.END_OF_LINE
            continue

        #
        # Current section UserId, IdString
        #    
        IdContentList = []
        LastItem = ''
        SectionLineNo = None
        for Item in self.LastSectionHeaderContent:
            UserId = Item[1]
            IdString = Item[2]
            Arch = Item[3]
            SectionLineNo = Item[4]
            if not IsValidArch(Arch):
                Logger.Error(
                    'InfParser',
                    FORMAT_INVALID,
                    ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (Arch),
                    File=GlobalData.gINF_MODULE_NAME,
                    Line=SectionLineNo,
                    ExtraData=None)

            if (UserId, IdString, Arch) not in IdContentList:
                #
                # To check the UserId and IdString valid or not.
                #
                if not IsValidUserId(UserId):
                    Logger.Error('InfParser',
                                 FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_UE_SECTION_USER_ID_ERROR % (Item[1]),
                                 File=GlobalData.gINF_MODULE_NAME,
                                 Line=SectionLineNo,
                                 ExtraData=None)

                if not IsValidIdString(IdString):
                    Logger.Error('InfParser',
                                 FORMAT_INVALID,
                                 ST.ERR_INF_PARSER_UE_SECTION_ID_STRING_ERROR % (IdString),
                                 File=GlobalData.gINF_MODULE_NAME, Line=SectionLineNo,
                                 ExtraData=None)
                IdContentList.append((UserId, IdString, Arch))
            else:
                #
                # Each UserExtensions section header must have a unique set 
                # of UserId, IdString and Arch values.
                # This means that the same UserId can be used in more than one 
                # section header, provided the IdString or Arch values are 
                # different. The same IdString values can be used in more than 
                # one section header if the UserId or Arch values are 
                # different. The same UserId and the same IdString can be used 
                # in a section header if the Arch values are different in each 
                # of the section headers.
                #
                Logger.Error('InfParser',
                             FORMAT_INVALID,
                             ST.ERR_INF_PARSER_UE_SECTION_DUPLICATE_ERROR % (
                                                                    IdString),
                             File=GlobalData.gINF_MODULE_NAME,
                             Line=SectionLineNo,
                             ExtraData=None)
            LastItem = Item

        if not InfSectionObject.SetUserExtension(UserExtensionContent,
                                                 IdContent=IdContentList,
                                                 LineNo=SectionLineNo):
            Logger.Error\
            ('InfParser', FORMAT_INVALID, \
             ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[UserExtension]"), \
             File=FileName, Line=LastItem[4])

    def InfProtocolParser(self, SectionString, InfSectionObject, FileName):
        #
        # Macro defined in this section 
        #
        SectionMacros = {}
        ValueList = []
        ProtocolList = []
        CommentsList = []
        CurrentLineVar = None
        #
        # Parse section content
        #
        for Line in SectionString:
            LineContent = Line[0]
            LineNo = Line[1]

            if LineContent.strip() == '':
                CommentsList = []
                continue

            if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
                CommentsList.append(Line)
                continue
            else:
                #
                # Encounter a Protocol entry
                #
                if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
                    CommentsList.append((
                            LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):],
                            LineNo))
                    LineContent = \
                            LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]

            if LineContent != '':
                #
                # Find Macro
                #
                Name, Value = MacroParser((LineContent, LineNo),
                                          FileName,
                                          DT.MODEL_EFI_PROTOCOL,
                                          self.FileLocalMacros)
                if Name is not None:
                    SectionMacros[Name] = Value
                    ValueList = []
                    CommentsList = []
                    continue

                TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1)
                ValueList[0:len(TokenList)] = TokenList

                #
                # Replace with Local section Macro and [Defines] section Macro.
                #            
                ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo), self.FileLocalMacros, SectionMacros)
                            for Value in ValueList]

                CurrentLineVar = (LineContent, LineNo, FileName)

            if len(ValueList) >= 1:
                ProtocolList.append((ValueList, CommentsList, CurrentLineVar))
                ValueList = []
                CommentsList = []
            continue

        #
        # Current section archs
        #    
        ArchList = []
        LineIndex = -1
        for Item in self.LastSectionHeaderContent:
            LineIndex = Item[3]
            if Item[1] not in ArchList:
                ArchList.append(Item[1])

        if not InfSectionObject.SetProtocol(ProtocolList, Arch=ArchList):
            Logger.Error\
            ('InfParser', FORMAT_INVALID, \
             ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Protocol]"), \
             File=FileName, Line=LineIndex)
