text: ## @file
  # This file is used to create a database used by build tool
  #
  # Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>
  # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
  # SPDX-License-Identifier: BSD-2-Clause-Patent
  #
  
  ## Platform build information from DSC file
  #
  #  This class is used to retrieve information stored in database and convert them
  # into PlatformBuildClassObject form for easier use for AutoGen.
  #
  from __future__ import print_function
  from __future__ import absolute_import
  from Common.StringUtils import *
  from Common.DataType import *
  from Common.Misc import *
  from types import *
  from Common.Expression import *
  from CommonDataClass.CommonClass import SkuInfoClass
  from Common.TargetTxtClassObject import TargetTxt
  from Common.ToolDefClassObject import ToolDef
  from .MetaDataTable import *
  from .MetaFileTable import *
  from .MetaFileParser import *
  
  from .WorkspaceCommon import GetDeclaredPcd
  from Common.Misc import AnalyzeDscPcd
  from Common.Misc import ProcessDuplicatedInf,RemoveCComments,ArrayIndex
  import re
  from Common.Parsing import IsValidWord
  from Common.VariableAttributes import VariableAttributes
  import Common.GlobalData as GlobalData
  import subprocess
  from functools import reduce
  from Common.Misc import SaveFileOnChange
  from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
  from collections import OrderedDict, defaultdict
  
  def _IsFieldValueAnArray (Value):
      Value = Value.strip()
      if Value.startswith(TAB_GUID) and Value.endswith(')'):
          return True
      if Value.startswith('L"') and Value.endswith('"')  and len(list(Value[2:-1])) > 1:
          return True
      if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:
          return True
      if Value[0] == '{' and Value[-1] == '}':
          return True
      if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
          return True
      if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
          return True
      return False
  
  PcdValueInitName = 'PcdValueInit'
  
  PcdMainCHeader = '''
  /**
    DO NOT EDIT
    FILE auto-generated
  **/
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <PcdValueCommon.h>
  '''
  
  PcdMainCEntry = '''
  int
  main (
    int   argc,
    char  *argv[]
    )
  {
    return PcdValueMain (argc, argv);
  }
  '''
  
  PcdMakefileHeader = '''
  #
  # DO NOT EDIT
  # This file is auto-generated by build utility
  #
  
  '''
  
  WindowsCFLAGS = 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
  LinuxCFLAGS = 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
  PcdMakefileEnd = '''
  !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
  
  LIBS = $(LIB_PATH)\Common.lib
  
  !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
  '''
  
  AppTarget = '''
  all: $(APPFILE)
  $(APPFILE): $(OBJECTS)
  %s
  '''
  
  PcdGccMakefile = '''
  MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
  LIBS = -lCommon
  '''
  
  variablePattern = re.compile(r'[\t\s]*0[xX][a-fA-F0-9]+$')
  SkuIdPattern = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$')
  ## regular expressions for finding decimal and hex numbers
  Pattern = re.compile('^[1-9]\d*|0$')
  HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')
  ## Regular expression for finding header file inclusions
  from AutoGen.GenMake import gIncludePattern
  
  ## Find dependencies for one source file
  #
  #  By searching recursively "#include" directive in file, find out all the
  #  files needed by given source file. The dependecies will be only searched
  #  in given search path list.
  #
  #   @param      SearchPathList  The list of search path
  #
  #   @retval     list            The list of files the given source file depends on
  #
  def GetDependencyList(FileStack, SearchPathList):
      DepDb = dict()
      DependencySet = set(FileStack)
      while len(FileStack) > 0:
          F = FileStack.pop()
          FullPathDependList = []
          CurrentFileDependencyList = []
          if F in DepDb:
              CurrentFileDependencyList = DepDb[F]
          else:
              try:
                  Fd = open(F, 'r')
                  FileContent = Fd.read()
              except BaseException as X:
                  EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F + "\n\t" + str(X))
              finally:
                  if "Fd" in dir(locals()):
                      Fd.close()
  
              if len(FileContent) == 0:
                  continue
  
              try:
                  if FileContent[0] == 0xff or FileContent[0] == 0xfe:
                      FileContent = FileContent.decode('utf-16')
                  else:
                      FileContent = FileContent.decode()
              except:
                  # The file is not txt file. for example .mcb file
                  continue
              IncludedFileList = gIncludePattern.findall(FileContent)
  
              for Inc in IncludedFileList:
                  Inc = Inc.strip()
                  Inc = os.path.normpath(Inc)
                  CurrentFileDependencyList.append(Inc)
              DepDb[F] = CurrentFileDependencyList
  
          CurrentFilePath = os.path.dirname(F)
          PathList = [CurrentFilePath] + SearchPathList
          for Inc in CurrentFileDependencyList:
              for SearchPath in PathList:
                  FilePath = os.path.join(SearchPath, Inc)
                  if not os.path.exists(FilePath):
                      continue
                  if FilePath not in DependencySet:
                      FileStack.append(FilePath)
                      FullPathDependList.append(FilePath)
                  break
          DependencySet.update(FullPathDependList)
      DependencyList = list(DependencySet)  # remove duplicate ones
  
      return DependencyList
  
  class DscBuildData(PlatformBuildClassObject):
      # dict used to convert PCD type in database to string used by build tool
      _PCD_TYPE_STRING_ = {
          MODEL_PCD_FIXED_AT_BUILD        :   TAB_PCDS_FIXED_AT_BUILD,
          MODEL_PCD_PATCHABLE_IN_MODULE   :   TAB_PCDS_PATCHABLE_IN_MODULE,
          MODEL_PCD_FEATURE_FLAG          :   TAB_PCDS_FEATURE_FLAG,
          MODEL_PCD_DYNAMIC               :   TAB_PCDS_DYNAMIC,
          MODEL_PCD_DYNAMIC_DEFAULT       :   TAB_PCDS_DYNAMIC,
          MODEL_PCD_DYNAMIC_HII           :   TAB_PCDS_DYNAMIC_HII,
          MODEL_PCD_DYNAMIC_VPD           :   TAB_PCDS_DYNAMIC_VPD,
          MODEL_PCD_DYNAMIC_EX            :   TAB_PCDS_DYNAMIC_EX,
          MODEL_PCD_DYNAMIC_EX_DEFAULT    :   TAB_PCDS_DYNAMIC_EX,
          MODEL_PCD_DYNAMIC_EX_HII        :   TAB_PCDS_DYNAMIC_EX_HII,
          MODEL_PCD_DYNAMIC_EX_VPD        :   TAB_PCDS_DYNAMIC_EX_VPD,
      }
  
      # dict used to convert part of [Defines] to members of DscBuildData directly
      _PROPERTY_ = {
          #
          # Required Fields
          #
          TAB_DSC_DEFINES_PLATFORM_NAME           :   "_PlatformName",
          TAB_DSC_DEFINES_PLATFORM_GUID           :   "_Guid",
          TAB_DSC_DEFINES_PLATFORM_VERSION        :   "_Version",
          TAB_DSC_DEFINES_DSC_SPECIFICATION       :   "_DscSpecification",
          # TAB_DSC_DEFINES_OUTPUT_DIRECTORY        :   "_OutputDirectory",
          # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES :   "_SupArchList",
          # TAB_DSC_DEFINES_BUILD_TARGETS           :   "_BuildTargets",
          TAB_DSC_DEFINES_SKUID_IDENTIFIER        :   "_SkuName",
          # TAB_DSC_DEFINES_FLASH_DEFINITION        :   "_FlashDefinition",
          TAB_DSC_DEFINES_BUILD_NUMBER            :   "_BuildNumber",
          TAB_DSC_DEFINES_MAKEFILE_NAME           :   "_MakefileName",
          TAB_DSC_DEFINES_BS_BASE_ADDRESS         :   "_BsBaseAddress",
          TAB_DSC_DEFINES_RT_BASE_ADDRESS         :   "_RtBaseAddress",
          # TAB_DSC_DEFINES_RFC_LANGUAGES           :   "_RFCLanguages",
          # TAB_DSC_DEFINES_ISO_LANGUAGES           :   "_ISOLanguages",
      }
  
      # used to compose dummy library class name for those forced library instances
      _NullLibraryNumber = 0
  
      ## Constructor of DscBuildData
      #
      #  Initialize object of DscBuildData
      #
      #   @param      FilePath        The path of platform description file
      #   @param      RawData         The raw data of DSC file
      #   @param      BuildDataBase   Database used to retrieve module/package information
      #   @param      Arch            The target architecture
      #   @param      Platform        (not used for DscBuildData)
      #   @param      Macros          Macros used for replacement in DSC file
      #
      def __init__(self, FilePath, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):
          self.MetaFile = FilePath
          self._RawData = RawData
          self._Bdb = BuildDataBase
          self._Arch = Arch
          self._Target = Target
          self._Toolchain = Toolchain
          self._ToolChainFamily = None
          self._Clear()
          self.WorkspaceDir = os.getenv("WORKSPACE") if os.getenv("WORKSPACE") else ""
          self.DefaultStores = None
          self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds)
  
      @property
      def OutputPath(self):
          if os.getenv("WORKSPACE"):
              return os.path.join(os.getenv("WORKSPACE"), self.OutputDirectory, self._Target + "_" + self._Toolchain, PcdValueInitName)
          else:
              return os.path.dirname(self.DscFile)
  
      ## XXX[key] = value
      def __setitem__(self, key, value):
          self.__dict__[self._PROPERTY_[key]] = value
  
      ## value = XXX[key]
      def __getitem__(self, key):
          return self.__dict__[self._PROPERTY_[key]]
  
      ## "in" test support
      def __contains__(self, key):
          return key in self._PROPERTY_
  
      ## Set all internal used members of DscBuildData to None
      def _Clear(self):
          self._Header            = None
          self._PlatformName      = None
          self._Guid              = None
          self._Version           = None
          self._DscSpecification  = None
          self._OutputDirectory   = None
          self._SupArchList       = None
          self._BuildTargets      = None
          self._SkuName           = None
          self._PcdInfoFlag       = None
          self._VarCheckFlag      = None
          self._FlashDefinition   = None
          self._Prebuild          = None
          self._Postbuild         = None
          self._BuildNumber       = None
          self._MakefileName      = None
          self._BsBaseAddress     = None
          self._RtBaseAddress     = None
          self._SkuIds            = None
          self._Modules           = None
          self._LibraryInstances  = None
          self._LibraryClasses    = None
          self._Pcds              = None
          self._DecPcds           = None
          self._BuildOptions      = None
          self._ModuleTypeOptions = None
          self._LoadFixAddress    = None
          self._RFCLanguages      = None
          self._ISOLanguages      = None
          self._VpdToolGuid       = None
          self._MacroDict         = None
          self.DefaultStores      = None
  
      ## Get current effective macros
      @property
      def _Macros(self):
          if self._MacroDict is None:
              self._MacroDict = {}
              self._MacroDict.update(GlobalData.gPlatformDefines)
              self._MacroDict.update(GlobalData.gGlobalDefines)
              self._MacroDict.update(GlobalData.gCommandLineDefines)
          return self._MacroDict
  
      ## Get architecture
      @property
      def Arch(self):
          return self._Arch
      @property
      def Dir(self):
          return self.MetaFile.Dir
  
      ## Retrieve all information in [Defines] section
      #
      #   (Retrieving all [Defines] information in one-shot is just to save time.)
      #
      def _GetHeaderInfo(self):
          RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]
          for Record in RecordList:
              Name = Record[1]
              # items defined _PROPERTY_ don't need additional processing
  
              # some special items in [Defines] section need special treatment
              if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
                  self._OutputDirectory = NormPath(Record[2], self._Macros)
                  if ' ' in self._OutputDirectory:
                      EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",
                                      File=self.MetaFile, Line=Record[-1],
                                      ExtraData=self._OutputDirectory)
              elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:
                  self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)
                  ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')
                  if ErrorCode != 0:
                      EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],
                                      ExtraData=ErrorInfo)
              elif Name == TAB_DSC_PREBUILD:
                  PrebuildValue = Record[2]
                  if Record[2][0] == '"':
                      if Record[2][-1] != '"':
                          EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,
                                      File=self.MetaFile, Line=Record[-1])
                      PrebuildValue = Record[2][1:-1]
                  self._Prebuild = PrebuildValue
              elif Name == TAB_DSC_POSTBUILD:
                  PostbuildValue = Record[2]
                  if Record[2][0] == '"':
                      if Record[2][-1] != '"':
                          EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,
                                      File=self.MetaFile, Line=Record[-1])
                      PostbuildValue = Record[2][1:-1]
                  self._Postbuild = PostbuildValue
              elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:
                  self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
              elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:
                  self._BuildTargets = GetSplitValueList(Record[2])
              elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:
                  if self._SkuName is None:
                      self._SkuName = Record[2]
                  if GlobalData.gSKUID_CMD:
                      self._SkuName = GlobalData.gSKUID_CMD
              elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:
                  self._PcdInfoFlag = Record[2]
              elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:
                  self._VarCheckFlag = Record[2]
              elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
                  try:
                      self._LoadFixAddress = int (Record[2], 0)
                  except:
                      EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))
              elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:
                  if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
                      EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
                                      File=self.MetaFile, Line=Record[-1])
                  LanguageCodes = Record[2][1:-1]
                  if not LanguageCodes:
                      EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
                                      File=self.MetaFile, Line=Record[-1])
                  LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)
                  # check whether there is empty entries in the list
                  if None in LanguageList:
                      EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',
                                      File=self.MetaFile, Line=Record[-1])
                  self._RFCLanguages = LanguageList
              elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:
                  if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
                      EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
                                      File=self.MetaFile, Line=Record[-1])
                  LanguageCodes = Record[2][1:-1]
                  if not LanguageCodes:
                      EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
                                      File=self.MetaFile, Line=Record[-1])
                  if len(LanguageCodes) % 3:
                      EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',
                                      File=self.MetaFile, Line=Record[-1])
                  LanguageList = []
                  for i in range(0, len(LanguageCodes), 3):
                      LanguageList.append(LanguageCodes[i:i + 3])
                  self._ISOLanguages = LanguageList
              elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:
                  #
                  # try to convert GUID to a real UUID value to see whether the GUID is format
                  # for VPD_TOOL_GUID is correct.
                  #
                  try:
                      uuid.UUID(Record[2])
                  except:
                      EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)
                  self._VpdToolGuid = Record[2]
              elif Name in self:
                  self[Name] = Record[2]
          # set _Header to non-None in order to avoid database re-querying
          self._Header = 'DUMMY'
  
      ## Retrieve platform name
      @property
      def PlatformName(self):
          if self._PlatformName is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._PlatformName is None:
                  EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)
          return self._PlatformName
  
      @property
      def Platform(self):
          return self.PlatformName
  
      ## Retrieve file guid
      @property
      def Guid(self):
          if self._Guid is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._Guid is None:
                  EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile)
          return self._Guid
  
      ## Retrieve platform version
      @property
      def Version(self):
          if self._Version is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._Version is None:
                  EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)
          return self._Version
  
      ## Retrieve platform description file version
      @property
      def DscSpecification(self):
          if self._DscSpecification is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._DscSpecification is None:
                  EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)
          return self._DscSpecification
  
      ## Retrieve OUTPUT_DIRECTORY
      @property
      def OutputDirectory(self):
          if self._OutputDirectory is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._OutputDirectory is None:
                  self._OutputDirectory = os.path.join("Build", self._PlatformName)
          return self._OutputDirectory
  
      ## Retrieve SUPPORTED_ARCHITECTURES
      @property
      def SupArchList(self):
          if self._SupArchList is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._SupArchList is None:
                  EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)
          return self._SupArchList
  
      ## Retrieve BUILD_TARGETS
      @property
      def BuildTargets(self):
          if self._BuildTargets is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._BuildTargets is None:
                  EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)
          return self._BuildTargets
  
      @property
      def PcdInfoFlag(self):
          if self._PcdInfoFlag is None or self._PcdInfoFlag.upper() == 'FALSE':
              return False
          elif self._PcdInfoFlag.upper() == 'TRUE':
              return True
          else:
              return False
  
      @property
      def VarCheckFlag(self):
          if self._VarCheckFlag is None or self._VarCheckFlag.upper() == 'FALSE':
              return False
          elif self._VarCheckFlag.upper() == 'TRUE':
              return True
          else:
              return False
  
      # # Retrieve SKUID_IDENTIFIER
      @property
      def SkuName(self):
          if self._SkuName is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._SkuName is None:
                  self._SkuName = TAB_DEFAULT
          return self._SkuName
  
      ## Override SKUID_IDENTIFIER
      @SkuName.setter
      def SkuName(self, Value):
          self._SkuName = Value
  
      @property
      def FlashDefinition(self):
          if self._FlashDefinition is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._FlashDefinition is None:
                  self._FlashDefinition = ''
          return self._FlashDefinition
  
      @property
      def Prebuild(self):
          if self._Prebuild is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._Prebuild is None:
                  self._Prebuild = ''
          return self._Prebuild
  
      @property
      def Postbuild(self):
          if self._Postbuild is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._Postbuild is None:
                  self._Postbuild = ''
          return self._Postbuild
  
      ## Retrieve FLASH_DEFINITION
      @property
      def BuildNumber(self):
          if self._BuildNumber is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._BuildNumber is None:
                  self._BuildNumber = ''
          return self._BuildNumber
  
      ## Retrieve MAKEFILE_NAME
      @property
      def MakefileName(self):
          if self._MakefileName is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._MakefileName is None:
                  self._MakefileName = ''
          return self._MakefileName
  
      ## Retrieve BsBaseAddress
      @property
      def BsBaseAddress(self):
          if self._BsBaseAddress is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._BsBaseAddress is None:
                  self._BsBaseAddress = ''
          return self._BsBaseAddress
  
      ## Retrieve RtBaseAddress
      @property
      def RtBaseAddress(self):
          if self._RtBaseAddress is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._RtBaseAddress is None:
                  self._RtBaseAddress = ''
          return self._RtBaseAddress
  
      ## Retrieve the top address for the load fix address
      @property
      def LoadFixAddress(self):
          if self._LoadFixAddress is None:
              if self._Header is None:
                  self._GetHeaderInfo()
  
              if self._LoadFixAddress is None:
                  self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')
  
              try:
                  self._LoadFixAddress = int (self._LoadFixAddress, 0)
              except:
                  EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))
  
          #
          # If command line defined, should override the value in DSC file.
          #
          if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines:
              try:
                  self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
              except:
                  EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))
  
          if self._LoadFixAddress < 0:
              EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))
          if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:
              EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))
  
          return self._LoadFixAddress
  
      ## Retrieve RFCLanguage filter
      @property
      def RFCLanguages(self):
          if self._RFCLanguages is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._RFCLanguages is None:
                  self._RFCLanguages = []
          return self._RFCLanguages
  
      ## Retrieve ISOLanguage filter
      @property
      def ISOLanguages(self):
          if self._ISOLanguages is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._ISOLanguages is None:
                  self._ISOLanguages = []
          return self._ISOLanguages
  
      ## Retrieve the GUID string for VPD tool
      @property
      def VpdToolGuid(self):
          if self._VpdToolGuid is None:
              if self._Header is None:
                  self._GetHeaderInfo()
              if self._VpdToolGuid is None:
                  self._VpdToolGuid = ''
          return self._VpdToolGuid
  
      ## Retrieve [SkuIds] section information
      @property
      def SkuIds(self):
          if self._SkuIds is None:
              self._SkuIds = OrderedDict()
              RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]
              for Record in RecordList:
                  if not Record[0]:
                      EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',
                                      File=self.MetaFile, Line=Record[-1])
                  if not Record[1]:
                      EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',
                                      File=self.MetaFile, Line=Record[-1])
                  if not Pattern.match(Record[0]) and not HexPattern.match(Record[0]):
                      EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID number is invalid. It only support Integer and HexNumber",
                                      File=self.MetaFile, Line=Record[-1])
                  if not SkuIdPattern.match(Record[1]) or (Record[2] and not SkuIdPattern.match(Record[2])):
                      EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID name is invalid. The correct format is '(a-zA-Z_)(a-zA-Z0-9_)*'",
                                      File=self.MetaFile, Line=Record[-1])
                  self._SkuIds[Record[1].upper()] = (str(DscBuildData.ToInt(Record[0])), Record[1].upper(), Record[2].upper())
              if TAB_DEFAULT not in self._SkuIds:
                  self._SkuIds[TAB_DEFAULT] = ("0", TAB_DEFAULT, TAB_DEFAULT)
              if TAB_COMMON not in self._SkuIds:
                  self._SkuIds[TAB_COMMON] = ("0", TAB_DEFAULT, TAB_DEFAULT)
          return self._SkuIds
  
      @staticmethod
      def ToInt(intstr):
          return int(intstr, 16) if intstr.upper().startswith("0X") else int(intstr)
  
      def _GetDefaultStores(self):
          if self.DefaultStores is None:
              self.DefaultStores = OrderedDict()
              RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch]
              for Record in RecordList:
                  if not Record[0]:
                      EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number',
                                      File=self.MetaFile, Line=Record[-1])
                  if not Record[1]:
                      EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name',
                                      File=self.MetaFile, Line=Record[-1])
                  if not Pattern.match(Record[0]) and not HexPattern.match(Record[0]):
                      EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber",
                                      File=self.MetaFile, Line=Record[-1])
                  if not IsValidWord(Record[1]):
                      EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",
                                      File=self.MetaFile, Line=Record[-1])
                  self.DefaultStores[Record[1].upper()] = (DscBuildData.ToInt(Record[0]), Record[1].upper())
              if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores:
                  self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0, TAB_DEFAULT_STORES_DEFAULT)
              GlobalData.gDefaultStores = sorted(self.DefaultStores.keys())
          return self.DefaultStores
  
      def OverrideDuplicateModule(self):
          RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
          Macros = self._Macros
          Components = {}
          for Record in RecordList:
              ModuleId = Record[6]
              file_guid = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
              file_guid_str = file_guid[0][2] if file_guid else "NULL"
              ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
              if self._Arch != TAB_ARCH_COMMON and (file_guid_str,str(ModuleFile)) in Components:
                  self._RawData.DisableOverrideComponent(Components[(file_guid_str,str(ModuleFile))])
              Components[(file_guid_str,str(ModuleFile))] = ModuleId
          self._RawData._PostProcessed = False
      ## Retrieve [Components] section information
      @property
      def Modules(self):
          if self._Modules is not None:
              return self._Modules
          self.OverrideDuplicateModule()
          self._Modules = OrderedDict()
          RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
          Macros = self._Macros
          for Record in RecordList:
              ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
              ModuleId = Record[6]
              LineNo = Record[7]
  
              # check the file validation
              ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
              if ErrorCode != 0:
                  EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
                                  ExtraData=ErrorInfo)
  
              Module = ModuleBuildClassObject()
              Module.MetaFile = ModuleFile
  
              # get module private library instance
              RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]
              for Record in RecordList:
                  LibraryClass = Record[0]
                  LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)
                  LineNo = Record[-1]
  
                  # check the file validation
                  ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')
                  if ErrorCode != 0:
                      EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
                                      ExtraData=ErrorInfo)
  
                  if LibraryClass == '' or LibraryClass == 'NULL':
                      self._NullLibraryNumber += 1
                      LibraryClass = 'NULL%d' % self._NullLibraryNumber
                      EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
                  Module.LibraryClasses[LibraryClass] = LibraryPath
                  if LibraryPath not in self.LibraryInstances:
                      self.LibraryInstances.append(LibraryPath)
  
              # get module private PCD setting
              for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \
                           MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:
                  RecordList = self._RawData[Type, self._Arch, None, ModuleId]
                  for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
                      TokenList = GetSplitValueList(Setting)
                      DefaultValue = TokenList[0]
                      # the format is PcdName| Value | VOID* | MaxDatumSize
                      if len(TokenList) > 2:
                          MaxDatumSize = TokenList[2]
                      else:
                          MaxDatumSize = ''
                      TypeString = self._PCD_TYPE_STRING_[Type]
                      Pcd = PcdClassObject(
                              PcdCName,
                              TokenSpaceGuid,
                              TypeString,
                              '',
                              DefaultValue,
                              '',
                              MaxDatumSize,
                              {},
                              False,
                              None
                              )
                      Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd
  
              # get module private build options
              RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]
              for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
                  if (ToolChainFamily, ToolChain) not in Module.BuildOptions:
                      Module.BuildOptions[ToolChainFamily, ToolChain] = Option
                  else:
                      OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]
                      Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
  
              RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
              if RecordList:
                  if len(RecordList) != 1:
                      EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',
                                      File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
                  ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)
                  ModuleFile.Arch = self._Arch
  
              self._Modules[ModuleFile] = Module
          return self._Modules
  
      ## Retrieve all possible library instances used in this platform
      @property
      def LibraryInstances(self):
          if self._LibraryInstances is None:
              self.LibraryClasses
          return self._LibraryInstances
  
      ## Retrieve [LibraryClasses] information
      @property
      def LibraryClasses(self):
          if self._LibraryClasses is None:
              self._LibraryInstances = []
              #
              # tdict is a special dict kind of type, used for selecting correct
              # library instance for given library class and module type
              #
              LibraryClassDict = tdict(True, 3)
              # track all library class names
              LibraryClassSet = set()
              RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]
              Macros = self._Macros
              for Record in RecordList:
                  LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, Dummy, LineNo = Record
                  if LibraryClass == '' or LibraryClass == 'NULL':
                      self._NullLibraryNumber += 1
                      LibraryClass = 'NULL%d' % self._NullLibraryNumber
                      EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))
                  LibraryClassSet.add(LibraryClass)
                  LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)
                  # check the file validation
                  ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')
                  if ErrorCode != 0:
                      EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
                                      ExtraData=ErrorInfo)
  
                  if ModuleType != TAB_COMMON and ModuleType not in SUP_MODULE_LIST:
                      EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,
                                      File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)
                  LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance
                  if LibraryInstance not in self._LibraryInstances:
                      self._LibraryInstances.append(LibraryInstance)
  
              # resolve the specific library instance for each class and each module type
              self._LibraryClasses = tdict(True)
              for LibraryClass in LibraryClassSet:
                  # try all possible module types
                  for ModuleType in SUP_MODULE_LIST:
                      LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]
                      if LibraryInstance is None:
                          continue
                      self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance
  
              RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]
              for Record in RecordList:
                  File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
                  LineNo = Record[-1]
                  # check the file validation
                  ErrorCode, ErrorInfo = File.Validate('.inf')
                  if ErrorCode != 0:
                      EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
                                      ExtraData=ErrorInfo)
                  if File not in self._LibraryInstances:
                      self._LibraryInstances.append(File)
                  #
                  # we need the module name as the library class name, so we have
                  # to parse it here. (self._Bdb[] will trigger a file parse if it
                  # hasn't been parsed)
                  #
                  Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
                  self._LibraryClasses[Library.BaseName, ':dummy:'] = Library
          return self._LibraryClasses
  
      def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):
          if not self._DecPcds:
  
              FdfInfList = []
              if GlobalData.gFdfParser:
                  FdfInfList = GlobalData.gFdfParser.Profile.InfList
  
              PkgSet = set()
              for Inf in FdfInfList:
                  ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
                  if ModuleFile in self._Modules:
                      continue
                  ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
                  PkgSet.update(ModuleData.Packages)
  
              self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
              self._GuidDict.update(GlobalData.gPlatformPcds)
  
          if (PcdCName, TokenSpaceGuid) not in self._DecPcds:
              EdkLogger.error('build', PARSER_ERROR,
                              "Pcd (%s.%s) defined in DSC is not declared in DEC files referenced in INF files in FDF. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),
                              File=self.MetaFile, Line=LineNo)
          ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)
          if not IsValid:
              if PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
                  EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
                                  ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
              else:
                  if ValueList[2] == '-1':
                      EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
                                  ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
          if ValueList[Index]:
              DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType
              if "{CODE(" not in ValueList[Index]:
                  try:
                      ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)
                  except BadExpression as Value:
                      EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,
                                      ExtraData="PCD [%s.%s] Value \"%s\" " % (
                                      TokenSpaceGuid, PcdCName, ValueList[Index]))
                  except EvaluationException as Excpt:
                      if hasattr(Excpt, 'Pcd'):
                          if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
                              EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
                                              " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
                                              " of the DSC file" % Excpt.Pcd,
                                              File=self.MetaFile, Line=LineNo)
                          else:
                              EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
                                              File=self.MetaFile, Line=LineNo)
                      else:
                          EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
                                          File=self.MetaFile, Line=LineNo)
  
          if ValueList[Index]:
              Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
              if not Valid:
                  EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,
                                  ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))
              if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT, MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE):
                  if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():
                      DecPcd = self._DecPcds[PcdCName, TokenSpaceGuid]
                      EdkLogger.error('build', FORMAT_INVALID,
                                      "Pcd datumtype used in DSC file is not the same as its declaration. DatumType:%s"%DecPcd.DatumType,
                                      File=self.MetaFile, Line=LineNo,
                                      ExtraData="Dsc:%s.%s|%s\n    Dec:%s.%s|%s|%s|%s" % (TokenSpaceGuid, PcdCName, Setting, TokenSpaceGuid, \
                                      PcdCName, DecPcd.DefaultValue, DecPcd.DatumType, DecPcd.TokenValue))
          if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds:
              if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]:
                  GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]
          return ValueList
  
      def _FilterPcdBySkuUsage(self, Pcds):
          available_sku = self.SkuIdMgr.AvailableSkuIdSet
          sku_usage = self.SkuIdMgr.SkuUsageType
          if sku_usage == SkuClass.SINGLE:
              for pcdname in Pcds:
                  pcd = Pcds[pcdname]
                  Pcds[pcdname].SkuInfoList = {TAB_DEFAULT:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
                  if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
                      Pcds[pcdname].SkuOverrideValues = {TAB_DEFAULT:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
          else:
              for pcdname in Pcds:
                  pcd = Pcds[pcdname]
                  Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
                  if isinstance(pcd, StructurePcd) and pcd.SkuOverrideValues:
                      Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
          return Pcds
  
      def CompleteHiiPcdsDefaultStores(self, Pcds):
          HiiPcd = [Pcds[pcd] for pcd in Pcds if Pcds[pcd].Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]]
          DefaultStoreMgr = DefaultStore(self.DefaultStores)
          for pcd in HiiPcd:
              for skuid in pcd.SkuInfoList:
                  skuobj = pcd.SkuInfoList.get(skuid)
                  if TAB_DEFAULT_STORES_DEFAULT not in skuobj.DefaultStoreDict:
                      PcdDefaultStoreSet = set(defaultstorename  for defaultstorename in skuobj.DefaultStoreDict)
                      mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
                      skuobj.DefaultStoreDict[TAB_DEFAULT_STORES_DEFAULT] = skuobj.DefaultStoreDict[mindefaultstorename]
          return Pcds
  
      def RecoverCommandLinePcd(self):
          def UpdateCommandLineValue(pcd):
              if pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
                                          self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
                  pcd.PcdValueFromComm = pcd.DefaultValue
              elif pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
                  pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).HiiDefaultValue
              else:
                  pcd.PcdValueFromComm = pcd.SkuInfoList.get(TAB_DEFAULT).DefaultValue
          for pcd in self._Pcds:
              if isinstance(self._Pcds[pcd], StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm):
                  UpdateCommandLineValue(self._Pcds[pcd])
  
      def __ParsePcdFromCommandLine(self):
          if GlobalData.BuildOptionPcd:
              for i, pcd in enumerate(GlobalData.BuildOptionPcd):
                  if isinstance(pcd, tuple):
                      continue
                  (pcdname, pcdvalue) = pcd.split('=')
                  if not pcdvalue:
                      EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))
                  if '.' in pcdname:
                      (Name1, Name2) = pcdname.split('.', 1)
                      if "." in Name2:
                          (Name3, FieldName) = Name2.split(".", 1)
                          if ((Name3, Name1)) in self.DecPcds:
                              HasTokenSpace = True
                              TokenCName = Name3
                              TokenSpaceGuidCName = Name1
                          else:
                              FieldName = Name2
                              TokenCName = Name1
                              TokenSpaceGuidCName = ''
                              HasTokenSpace = False
                      else:
                          if ((Name2, Name1)) in self.DecPcds:
                              HasTokenSpace = True
                              TokenCName = Name2
                              TokenSpaceGuidCName = Name1
                              FieldName =""
                          else:
                              FieldName = Name2
                              TokenCName = Name1
                              TokenSpaceGuidCName = ''
                              HasTokenSpace = False
                  else:
                      FieldName = ""
                      TokenCName = pcdname
                      TokenSpaceGuidCName = ''
                      HasTokenSpace = False
                  TokenSpaceGuidCNameList = []
                  FoundFlag = False
                  PcdDatumType = ''
                  DisplayName = TokenCName
                  if FieldName:
                      DisplayName = TokenCName + '.' + FieldName
                  if not HasTokenSpace:
                      for key in self.DecPcds:
                          PcdItem = self.DecPcds[key]
                          if TokenCName == PcdItem.TokenCName:
                              if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
                                  if len (TokenSpaceGuidCNameList) < 1:
                                      TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
                                      TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
                                      PcdDatumType = PcdItem.DatumType
                                      FoundFlag = True
                                  else:
                                      EdkLogger.error(
                                              'build',
                                               AUTOGEN_ERROR,
                                              "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
                                              )
                  else:
                      if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:
                          PcdDatumType = self.DecPcds[(TokenCName, TokenSpaceGuidCName)].DatumType
                          FoundFlag = True
                  if not FoundFlag:
                      if HasTokenSpace:
                          EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, DisplayName))
                      else:
                          EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (DisplayName))
                  pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")
                  if FieldName:
                      pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict, FieldName)
                  else:
                      pcdvalue = DscBuildData.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict)
                      IsValid, Cause = CheckPcdDatum(PcdDatumType, pcdvalue)
                      if not IsValid:
                          EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
                  GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, ("build command options", 1))
  
          if GlobalData.BuildOptionPcd:
              inf_objs = [item for item in self._Bdb._CACHE_.values() if item.Arch == self.Arch and item.MetaFile.Ext.lower() == '.inf']
              for pcd in GlobalData.BuildOptionPcd:
                  (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, _) = pcd
                  for BuildData in inf_objs:
                      for key in BuildData.Pcds:
                          PcdItem = BuildData.Pcds[key]
                          if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":
                              PcdItem.DefaultValue = pcdvalue
                              PcdItem.PcdValueFromComm = pcdvalue
          #In command line, the latter full assign value in commandLine should override the former field assign value.
          #For example, --pcd Token.pcd.field="" --pcd Token.pcd=H"{}"
          delete_assign = []
          field_assign = {}
          if GlobalData.BuildOptionPcd:
              for pcdTuple in GlobalData.BuildOptionPcd:
                  TokenSpaceGuid, Token, Field = pcdTuple[0], pcdTuple[1], pcdTuple[2]
                  if Field:
                      if (TokenSpaceGuid, Token) not in field_assign:
                          field_assign[TokenSpaceGuid, Token] = []
                      field_assign[TokenSpaceGuid, Token].append(pcdTuple)
                  else:
                      if (TokenSpaceGuid, Token) in field_assign:
                          delete_assign.extend(field_assign[TokenSpaceGuid, Token])
                          field_assign[TokenSpaceGuid, Token] = []
              for item in delete_assign:
                  GlobalData.BuildOptionPcd.remove(item)
  
      @staticmethod
      def HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''):
          if FieldName:
              IsArray = False
              TokenCName += '.' + FieldName
          if PcdValue.startswith('H'):
              if FieldName and _IsFieldValueAnArray(PcdValue[1:]):
                  PcdDatumType = TAB_VOID
                  IsArray = True
              if FieldName and not IsArray:
                  return PcdValue
              try:
                  PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True)
              except BadExpression as Value:
                  EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %
                                  (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
          elif PcdValue.startswith("L'") or PcdValue.startswith("'"):
              if FieldName and _IsFieldValueAnArray(PcdValue):
                  PcdDatumType = TAB_VOID
                  IsArray = True
              if FieldName and not IsArray:
                  return PcdValue
              try:
                  PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
              except BadExpression as Value:
                  EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %
                                  (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
          elif PcdValue.startswith('L'):
              PcdValue = 'L"' + PcdValue[1:] + '"'
              if FieldName and _IsFieldValueAnArray(PcdValue):
                  PcdDatumType = TAB_VOID
                  IsArray = True
              if FieldName and not IsArray:
                  return PcdValue
              try:
                  PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
              except BadExpression as Value:
                  EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %
                                  (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
          else:
              if PcdValue.upper() == 'FALSE':
                  PcdValue = str(0)
              if PcdValue.upper() == 'TRUE':
                  PcdValue = str(1)
              if not FieldName:
                  if PcdDatumType not in TAB_PCD_NUMERIC_TYPES:
                      PcdValue = '"' + PcdValue + '"'
                  elif not PcdValue.isdigit() and not PcdValue.upper().startswith('0X'):
                      PcdValue = '"' + PcdValue + '"'
              else:
                  IsArray = False
                  Base = 10
                  if PcdValue.upper().startswith('0X'):
                      Base = 16
                  try:
                      Num = int(PcdValue, Base)
                  except:
                      PcdValue = '"' + PcdValue + '"'
                  if _IsFieldValueAnArray(PcdValue):
                      PcdDatumType = TAB_VOID
                      IsArray = True
                  if not IsArray:
                      return PcdValue
              try:
                  PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
              except BadExpression as Value:
                  EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %
                                  (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
          return PcdValue
  
      ## Retrieve all PCD settings in platform
      @property
      def Pcds(self):
          if self._Pcds is None:
              self._Pcds = OrderedDict()
              self.__ParsePcdFromCommandLine()
              self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
              self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
              self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
              self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))
              self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))
              self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))
              self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
              self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
              self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
  
              self._Pcds = self.CompletePcdValues(self._Pcds)
              self._Pcds = self.OverrideByFdfOverAll(self._Pcds)
              self._Pcds = self.OverrideByCommOverAll(self._Pcds)
              self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
              self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
              self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
  
              self.RecoverCommandLinePcd()
          return self._Pcds
  
      ## Retrieve [BuildOptions]
      @property
      def BuildOptions(self):
          if self._BuildOptions is None:
              self._BuildOptions = OrderedDict()
              #
              # Retrieve build option for EDKII and EDK style module
              #
              for CodeBase in (EDKII_NAME, EDK_NAME):
                  RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
                  for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
                      if Dummy3.upper() != TAB_COMMON:
                          continue
                      CurKey = (ToolChainFamily, ToolChain, CodeBase)
                      #
                      # Only flags can be appended
                      #
                      if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
                          self._BuildOptions[CurKey] = Option
                      else:
                          if ' ' + Option not in self._BuildOptions[CurKey]:
                              self._BuildOptions[CurKey] += ' ' + Option
          return self._BuildOptions
      def GetBuildOptionsByPkg(self, Module, ModuleType):
  
          local_pkg = os.path.split(Module.LocalPkg())[0]
          if self._ModuleTypeOptions is None:
              self._ModuleTypeOptions = OrderedDict()
          if ModuleType not in self._ModuleTypeOptions:
              options = OrderedDict()
              self._ModuleTypeOptions[ ModuleType] = options
              RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
              for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
                  if Dummy2 not in (TAB_COMMON,local_pkg.upper(),"EDKII"):
                      continue
                  Type = Dummy3
                  if Type.upper() == ModuleType.upper():
                      Key = (ToolChainFamily, ToolChain)
                      if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
                          options[Key] = Option
                      else:
                          if ' ' + Option not in options[Key]:
                              options[Key] += ' ' + Option
          return self._ModuleTypeOptions[ModuleType]
      def GetBuildOptionsByModuleType(self, Edk, ModuleType):
          if self._ModuleTypeOptions is None:
              self._ModuleTypeOptions = OrderedDict()
          if (Edk, ModuleType) not in self._ModuleTypeOptions:
              options = OrderedDict()
              self._ModuleTypeOptions[Edk, ModuleType] = options
              DriverType = '%s.%s' % (Edk, ModuleType)
              CommonDriverType = '%s.%s' % (TAB_COMMON, ModuleType)
              RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
              for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4, Dummy5 in RecordList:
                  Type = Dummy2 + '.' + Dummy3
                  if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():
                      Key = (ToolChainFamily, ToolChain, Edk)
                      if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
                          options[Key] = Option
                      else:
                          if ' ' + Option not in options[Key]:
                              options[Key] += ' ' + Option
          return self._ModuleTypeOptions[Edk, ModuleType]
  
      @staticmethod
      def GetStructurePcdInfo(PcdSet):
          structure_pcd_data = defaultdict(list)
          for item in PcdSet:
              structure_pcd_data[(item[0], item[1])].append(item)
  
          return structure_pcd_data
  
      @staticmethod
      def OverrideByFdf(StruPcds,workspace):
          if GlobalData.gFdfParser is None:
              return StruPcds
          StructurePcdInFdf = OrderedDict()
          fdfpcd = GlobalData.gFdfParser.Profile.PcdDict
          fdfpcdlocation = GlobalData.gFdfParser.Profile.PcdLocalDict
          for item in fdfpcd :
              if len(item[2]) and (item[0],item[1]) in StruPcds:
                  StructurePcdInFdf[(item[1],item[0],item[2] )] = fdfpcd[item]
          GlobalPcds = {(item[0],item[1]) for item in StructurePcdInFdf}
          for Pcd in StruPcds.values():
              if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:
                  continue
              FieldValues = OrderedDict()
              for item in StructurePcdInFdf:
                  if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]:
                      FieldValues[item[2]] = StructurePcdInFdf[item]
              for field in FieldValues:
                  if field not in Pcd.PcdFieldValueFromFdf:
                      Pcd.PcdFieldValueFromFdf[field] = ["","",""]
                  Pcd.PcdFieldValueFromFdf[field][0] = FieldValues[field]
                  Pcd.PcdFieldValueFromFdf[field][1] = os.path.relpath(fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][0],workspace)
                  Pcd.PcdFieldValueFromFdf[field][2] = fdfpcdlocation[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName,field)][1]
  
          return StruPcds
  
      @staticmethod
      def OverrideByComm(StruPcds):
          StructurePcdInCom = OrderedDict()
          for item in GlobalData.BuildOptionPcd:
              if len(item) == 5 and (item[1], item[0]) in StruPcds:
                  StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])
          GlobalPcds = {(item[0], item[1]) for item in StructurePcdInCom}
          for Pcd in StruPcds.values():
              if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) not in GlobalPcds:
                  continue
              FieldValues = OrderedDict()
              for item in StructurePcdInCom:
                  if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (item[0], item[1]) and item[2]:
                      FieldValues[item[2]] = StructurePcdInCom[item]
              for field in FieldValues:
                  if field not in Pcd.PcdFieldValueFromComm:
                      Pcd.PcdFieldValueFromComm[field] = ["", "", ""]
                  Pcd.PcdFieldValueFromComm[field][0] = FieldValues[field][0]
                  Pcd.PcdFieldValueFromComm[field][1] = FieldValues[field][1][0]
                  Pcd.PcdFieldValueFromComm[field][2] = FieldValues[field][1][1]
          return StruPcds
  
      def OverrideByCommOverAll(self,AllPcds):
          def CheckStructureInComm(commpcds):
              if not commpcds:
                  return False
              if len(commpcds[0]) == 5:
                  return True
              return False
          NoFiledValues = OrderedDict()
          if CheckStructureInComm(GlobalData.BuildOptionPcd):
              StructurePcdInCom = OrderedDict()
              for item in GlobalData.BuildOptionPcd:
                  StructurePcdInCom[(item[0], item[1], item[2] )] = (item[3], item[4])
              for item in StructurePcdInCom:
                  if not item[2]:
                      NoFiledValues[(item[0], item[1])] = StructurePcdInCom[item]
          else:
              for item in GlobalData.BuildOptionPcd:
                  NoFiledValues[(item[0], item[1])] = [item[2]]
          for Guid, Name in NoFiledValues:
              if (Name, Guid) in AllPcds:
                  Pcd = AllPcds.get((Name, Guid))
                  if isinstance(self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), None), StructurePcd):
                      self._DecPcds.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName)).PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
                  else:
                      Pcd.PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
                      Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
                      for sku in Pcd.SkuInfoList:
                          SkuInfo = Pcd.SkuInfoList[sku]
                          if SkuInfo.DefaultValue:
                              SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
                          else:
                              SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
                              for defaultstore in SkuInfo.DefaultStoreDict:
                                  SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)][0]
                      if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
                          if Pcd.DatumType == TAB_VOID:
                              if not Pcd.MaxDatumSize:
                                  Pcd.MaxDatumSize = '0'
                              CurrentSize = int(Pcd.MaxDatumSize, 16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
                              OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
                              MaxSize = max(CurrentSize, OptionSize)
                              Pcd.MaxDatumSize = str(MaxSize)
              else:
                  PcdInDec = self.DecPcds.get((Name, Guid))
                  if PcdInDec:
                      PcdInDec.PcdValueFromComm = NoFiledValues[(Guid, Name)][0]
                      if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
                                          self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
                                          self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG],
                                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
                                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
                          self._Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
                          self._Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid, Name)][0]
                      if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC],
                                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX]]:
                          self._Pcds[Name, Guid].SkuInfoList = {TAB_DEFAULT:SkuInfoClass(TAB_DEFAULT, self.SkuIds[TAB_DEFAULT][0], '', '', '', '', '', NoFiledValues[( Guid, Name)][0])}
          return AllPcds
  
      def OverrideByFdfOverAll(self,AllPcds):
  
          if GlobalData.gFdfParser is None:
              return AllPcds
          NoFiledValues = GlobalData.gFdfParser.Profile.PcdDict
          for Name,Guid,Field in NoFiledValues:
              if len(Field):
                  continue
              Value = NoFiledValues[(Name,Guid,Field)]
              if (Name,Guid) in AllPcds:
                  Pcd = AllPcds.get((Name,Guid))
                  if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd):
                      self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = Value
                  else:
                      Pcd.PcdValueFromComm = Value
                      Pcd.DefaultValue = Value
                      for sku in Pcd.SkuInfoList:
                          SkuInfo = Pcd.SkuInfoList[sku]
                          if SkuInfo.DefaultValue:
                              SkuInfo.DefaultValue = Value
                          else:
                              SkuInfo.HiiDefaultValue = Value
                              for defaultstore in SkuInfo.DefaultStoreDict:
                                  SkuInfo.DefaultStoreDict[defaultstore] = Value
                      if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
                          if Pcd.DatumType == TAB_VOID:
                              if not Pcd.MaxDatumSize:
                                  Pcd.MaxDatumSize = '0'
                              CurrentSize = int(Pcd.MaxDatumSize,16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
                              OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
                              MaxSize = max(CurrentSize, OptionSize)
                              Pcd.MaxDatumSize = str(MaxSize)
              else:
                  PcdInDec = self.DecPcds.get((Name,Guid))
                  if PcdInDec:
                      PcdInDec.PcdValueFromFdf = Value
                      if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
                                          self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
                                          self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:
                          self._Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
                          self._Pcds[Name, Guid].DefaultValue = Value
          return AllPcds
  
      def ParsePcdNameStruct(self,NamePart1,NamePart2):
          TokenSpaceCName = PcdCName = DimensionAttr = Field = ""
          if "." in NamePart1:
              TokenSpaceCName, TempPcdCName = NamePart1.split(".")
              if "[" in TempPcdCName:
                  PcdCName = TempPcdCName[:TempPcdCName.index("[")]
                  DimensionAttr = TempPcdCName[TempPcdCName.index("["):]
              else:
                  PcdCName = TempPcdCName
              Field = NamePart2
          else:
              TokenSpaceCName = NamePart1
              if "[" in NamePart2:
                  PcdCName = NamePart2[:NamePart2.index("[")]
                  DimensionAttr = NamePart2[NamePart2.index("["):]
              else:
                  PcdCName = NamePart2
  
          return TokenSpaceCName,PcdCName,DimensionAttr,Field
  
      def UpdateStructuredPcds(self, TypeList, AllPcds):
  
          DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]
  
          Pcds = AllPcds
          DefaultStoreMgr = DefaultStore(self.DefaultStores)
          SkuIds = self.SkuIds
          self.SkuIdMgr.AvailableSkuIdSet.update({TAB_DEFAULT:0})
          DefaultStores = {storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict}
          DefaultStores.add(TAB_DEFAULT_STORES_DEFAULT)
  
          S_PcdSet = []
          # Find out all possible PCD candidates for self._Arch
          RecordList = []
  
          for Type in TypeList:
              RecordList.extend(self._RawData[Type, self._Arch])
  
          for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4, Dummy5 in RecordList:
              SkuName = SkuName.upper()
              default_store = default_store.upper()
              SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
              if SkuName not in SkuIds:
                  continue
              TCName,PCName,DimensionAttr,Field = self.ParsePcdNameStruct(TokenSpaceGuid, PcdCName)
              pcd_in_dec = self._DecPcds.get((PCName,TCName), None)
              if pcd_in_dec is None:
                  EdkLogger.error('build', PARSER_ERROR,
                              "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
                              File=self.MetaFile, Line = Dummy5)
              if SkuName in SkuIds and ("." in TokenSpaceGuid or "[" in PcdCName):
                  if not isinstance (pcd_in_dec, StructurePcd):
                      EdkLogger.error('build', PARSER_ERROR,
                                  "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (TCName, PCName, self._Arch),
                                  File=self.MetaFile, Line = Dummy5)
  
                  S_PcdSet.append([ TCName,PCName,DimensionAttr,Field, SkuName, default_store, Dummy5, AnalyzePcdExpression(Setting)[0]])
  
          # handle pcd value override
          StrPcdSet = DscBuildData.GetStructurePcdInfo(S_PcdSet)
          S_pcd_set = OrderedDict()
          for str_pcd in StrPcdSet:
              str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
              str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
              str_pcd_obj_str = StructurePcd()
              str_pcd_obj_str.copy(str_pcd_dec)
              if str_pcd_obj:
                  str_pcd_obj_str.copy(str_pcd_obj)
                  if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
                      str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
                  else:
                      str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
              for str_pcd_data in StrPcdSet[str_pcd]:
                  if str_pcd_data[4] in SkuIds:
                      str_pcd_obj_str.AddOverrideValue(str_pcd_data[3], str(str_pcd_data[7]), TAB_DEFAULT if str_pcd_data[4] == TAB_COMMON else str_pcd_data[4], TAB_DEFAULT_STORES_DEFAULT if str_pcd_data[5] == TAB_COMMON else str_pcd_data[5], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:], LineNo=str_pcd_data[6],DimensionAttr = str_pcd_data[2])
              S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
  
          # Add the Structure PCD that only defined in DEC, don't have override in DSC file
          for Pcd in self.DecPcds:
              if isinstance(self._DecPcds[Pcd], StructurePcd):
                  if Pcd not in S_pcd_set:
                      str_pcd_obj_str = StructurePcd()
                      str_pcd_obj_str.copy(self._DecPcds[Pcd])
                      str_pcd_obj = Pcds.get(Pcd, None)
                      if str_pcd_obj:
                          str_pcd_obj_str.copy(str_pcd_obj)
                          if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
                              str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
                          else:
                              str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
                      S_pcd_set[Pcd] = str_pcd_obj_str
          if S_pcd_set:
              GlobalData.gStructurePcd[self.Arch] = S_pcd_set.copy()
          self.FilterStrcturePcd(S_pcd_set)
          for stru_pcd in S_pcd_set.values():
              for skuid in SkuIds:
                  if skuid in stru_pcd.SkuOverrideValues:
                      continue
                  nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)
                  NoDefault = False
                  if skuid not in stru_pcd.SkuOverrideValues:
                      while nextskuid not in stru_pcd.SkuOverrideValues:
                          if nextskuid == TAB_DEFAULT:
                              NoDefault = True
                              break
                          nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
                      stru_pcd.SkuOverrideValues[skuid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid]) if not NoDefault else copy.deepcopy({defaultstorename: stru_pcd.DefaultValues for defaultstorename in DefaultStores} if DefaultStores else {}) #{TAB_DEFAULT_STORES_DEFAULT:stru_pcd.DefaultValues})
                      if not NoDefault:
                          stru_pcd.ValueChain.add((skuid, ''))
                  if 'DEFAULT' in stru_pcd.SkuOverrideValues and not GlobalData.gPcdSkuOverrides.get((stru_pcd.TokenCName, stru_pcd.TokenSpaceGuidCName)):
                      GlobalData.gPcdSkuOverrides.update(
                          {(stru_pcd.TokenCName, stru_pcd.TokenSpaceGuidCName): {'DEFAULT':stru_pcd.SkuOverrideValues['DEFAULT']}})
              if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
                  for skuid in SkuIds:
                      nextskuid = skuid
                      NoDefault = False
                      if skuid not in stru_pcd.SkuOverrideValues:
                          while nextskuid not in stru_pcd.SkuOverrideValues:
                              if nextskuid == TAB_DEFAULT:
                                  NoDefault = True
                                  break
                              nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
                      if NoDefault:
                          continue
                      PcdDefaultStoreSet = set(defaultstorename  for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid])
                      mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
  
                      for defaultstoreid in DefaultStores:
                          if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
                              stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = CopyDict(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
                              stru_pcd.ValueChain.add((skuid, defaultstoreid))
          S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
          S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
          Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
          if Str_Pcd_Values:
              for (skuname, StoreName, PcdGuid, PcdName, PcdValue) in Str_Pcd_Values:
                  str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
                  if str_pcd_obj is None:
                      print(PcdName, PcdGuid)
                      raise
                  if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
                                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
                      if skuname not in str_pcd_obj.SkuInfoList:
                          str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})
                      else:
                          str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue
                          str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
                  elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
                                          self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
                      if skuname in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
                          str_pcd_obj.DefaultValue = PcdValue
                  else:
                      if skuname not in str_pcd_obj.SkuInfoList:
                          nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
                          NoDefault = False
                          while nextskuid not in str_pcd_obj.SkuInfoList:
                              if nextskuid == TAB_DEFAULT:
                                  NoDefault = True
                                  break
                              nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
                          str_pcd_obj.SkuInfoList[skuname] = copy.deepcopy(str_pcd_obj.SkuInfoList[nextskuid]) if not NoDefault else SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], DefaultValue=PcdValue)
                          str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]
                          str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname
                      else:
                          str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue
              for str_pcd_obj in S_pcd_set.values():
                  if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
                                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
                      continue
                  PcdDefaultStoreSet = set(defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict)
                  DefaultStoreObj = DefaultStore(self._GetDefaultStores())
                  mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)
                  str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]
  
              for str_pcd_obj in S_pcd_set.values():
  
                  str_pcd_obj.MaxDatumSize = DscBuildData.GetStructurePcdMaxSize(str_pcd_obj)
                  Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
                  Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName].CustomAttribute['IsStru']=True
  
              for pcdkey in Pcds:
                  pcd = Pcds[pcdkey]
                  if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
                      pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
                      del pcd.SkuInfoList[TAB_COMMON]
                  elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
                      del pcd.SkuInfoList[TAB_COMMON]
  
          list(map(self.FilterSkuSettings, [Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType]))
          return Pcds
      @cached_property
      def PlatformUsedPcds(self):
          FdfInfList = []
          if GlobalData.gFdfParser:
              FdfInfList = GlobalData.gFdfParser.Profile.InfList
          FdfModuleList = [PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch) for Inf in FdfInfList]
          AllModulePcds = set()
          ModuleSet = set(list(self._Modules.keys()) + FdfModuleList)
          for ModuleFile in ModuleSet:
              ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
              AllModulePcds = AllModulePcds | ModuleData.PcdsName
          for ModuleFile in self.LibraryInstances:
              ModuleData = self._Bdb.CreateBuildObject(ModuleFile, self._Arch, self._Target, self._Toolchain)
              AllModulePcds = AllModulePcds | ModuleData.PcdsName
          return AllModulePcds
  
      #Filter the StrucutrePcd that is not used by any module in dsc file and fdf file.
      def FilterStrcturePcd(self, S_pcd_set):
          UnusedStruPcds = set(S_pcd_set.keys()) - self.PlatformUsedPcds
          for (Token, TokenSpaceGuid) in UnusedStruPcds:
              del S_pcd_set[(Token, TokenSpaceGuid)]
  
      ## Retrieve non-dynamic PCD settings
      #
      #   @param  Type    PCD type
      #
      #   @retval a dict object contains settings of given PCD type
      #
      def _GetPcd(self, Type):
          Pcds = OrderedDict()
          #
          # tdict is a special dict kind of type, used for selecting correct
          # PCD settings for certain ARCH
          #
          AvailableSkuIdSet = copy.copy(self.SkuIds)
  
          PcdDict = tdict(True, 4)
          PcdList = []
          # Find out all possible PCD candidates for self._Arch
          RecordList = self._RawData[Type, self._Arch]
          PcdValueDict = OrderedDict()
          for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
              SkuName = SkuName.upper()
              SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
              if SkuName not in AvailableSkuIdSet:
                  EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
                                              File=self.MetaFile, Line=Dummy5)
              if SkuName in (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT, TAB_COMMON):
                  if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, Dummy5) not in PcdList:
                      PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
                  PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
  
          for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
              Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
              if Setting is None:
                  continue
              PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
              if MaxDatumSize:
                  if int(MaxDatumSize, 0) > 0xFFFF:
                      EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
                                      File=self.MetaFile, Line=Dummy4)
                  if int(MaxDatumSize, 0) < 0:
                      EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
                                      File=self.MetaFile, Line=Dummy4)
              if (PcdCName, TokenSpaceGuid) in PcdValueDict:
                  PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize,Dummy4)
              else:
                  PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize,Dummy4)}
  
          for ((PcdCName, TokenSpaceGuid), PcdSetting) in PcdValueDict.items():
              if self.SkuIdMgr.SystemSkuId in PcdSetting:
                  PcdValue, DatumType, MaxDatumSize,_ = PcdSetting[self.SkuIdMgr.SystemSkuId]
              elif TAB_DEFAULT in PcdSetting:
                  PcdValue, DatumType, MaxDatumSize,_  = PcdSetting[TAB_DEFAULT]
              elif TAB_COMMON in PcdSetting:
                  PcdValue, DatumType, MaxDatumSize,_  = PcdSetting[TAB_COMMON]
              else:
                  PcdValue = None
                  DatumType = None
                  MaxDatumSize = None
  
              Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
                                                  PcdCName,
                                                  TokenSpaceGuid,
                                                  self._PCD_TYPE_STRING_[Type],
                                                  DatumType,
                                                  PcdValue,
                                                  '',
                                                  MaxDatumSize,
                                                  {},
                                                  False,
                                                  None,
                                                  IsDsc=True)
              for SkuName in PcdValueDict[PcdCName, TokenSpaceGuid]:
                  Settings = PcdValueDict[PcdCName, TokenSpaceGuid][SkuName]
                  if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
                      Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
                      Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
                  Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = Settings[0]
                  Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Settings[3])
          return Pcds
  
      @staticmethod
      def GetStructurePcdMaxSize(str_pcd):
          pcd_default_value = str_pcd.DefaultValue
          sku_values = [skuobj.HiiDefaultValue if str_pcd.Type in [DscBuildData._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], DscBuildData._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]] else skuobj.DefaultValue for skuobj in str_pcd.SkuInfoList.values()]
          sku_values.append(pcd_default_value)
  
          def get_length(value):
              Value = value.strip()
              if len(value) > 1:
                  if Value.startswith(TAB_GUID) and Value.endswith(')'):
                      return 16
                  if Value.startswith('L"') and Value.endswith('"'):
                      return len(Value[2:-1])
                  if Value[0] == '"' and Value[-1] == '"':
                      return len(Value) - 2
                  if Value.strip().startswith("{CODE("):
                      tmpValue = RemoveCComments(Value)
                      return len(tmpValue.split(","))
                  if (Value[0] == '{' and Value[-1] == '}'):
                      return len(Value.split(","))
                  if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
                      return  len(list(Value[2:-1]))
                  if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
                      return len(Value) - 2
              return len(Value)
  
          return str(max(get_length(item) for item in sku_values))
  
      @staticmethod
      def ExecuteCommand (Command):
          try:
              Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
          except:
              EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)
          Result = Process.communicate()
          return Process.returncode, Result[0].decode(), Result[1].decode()
  
      @staticmethod
      def IntToCString(Value, ValueSize):
          Result = '"'
          if not isinstance (Value, str):
              for Index in range(0, ValueSize):
                  Result = Result + '\\x%02x' % (Value & 0xff)
                  Value = Value >> 8
          Result = Result + '"'
          return Result
  
      def GenerateSizeFunction(self, Pcd):
          CApp = "// Default Value in Dec \n"
          CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
  
          if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
              CApp += "  *Size = (sizeof (%s) > *Size ? sizeof (%s) : *Size);\n" % (Pcd.DatumType,Pcd.DatumType)
          else:
              if "{CODE(" in Pcd.DefaultValueFromDec:
                  CApp += "  *Size = (sizeof (%s_%s_INIT_Value) > *Size ? sizeof (%s_%s_INIT_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Pcd.TokenSpaceGuidCName,Pcd.TokenCName)
              if Pcd.Type in PCD_DYNAMIC_TYPE_SET | PCD_DYNAMIC_EX_TYPE_SET:
                  for skuname in Pcd.SkuInfoList:
                      skuobj = Pcd.SkuInfoList[skuname]
                      if skuobj.VariableName:
                          for defaultstore in skuobj.DefaultStoreDict:
                              pcddef = self.GetPcdDscRawDefaultValue(Pcd,skuname,defaultstore)
                              if pcddef:
                                  if "{CODE(" in pcddef:
                                      CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore)
                                  else:
                                      CApp += "  *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
                      else:
                          pcddef = self.GetPcdDscRawDefaultValue(Pcd,skuname,TAB_DEFAULT_STORES_DEFAULT)
                          if pcddef:
                              if  "{CODE(" in pcddef:
                                  CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT)
                              else:
                                  CApp += "  *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
              else:
                  pcddef = self.GetPcdDscRawDefaultValue(Pcd,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
                  if pcddef:
                      if "{CODE(" in pcddef:
                          CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
                      else:
                          CApp += "  *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
          ActualCap = []
          for index in Pcd.DefaultValues:
              if index:
                  ActualCap.append(index)
              FieldList = Pcd.DefaultValues[index]
              if not FieldList:
                  continue
              for FieldName in FieldList:
                  FieldName = "." + FieldName
                  IsArray = _IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
                  if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
                      try:
                          Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
                      except BadExpression:
                          EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
                                          (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
                      Value, ValueSize = ParseFieldValue(Value)
                      if not Pcd.IsArray():
                          CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0));  // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
                  else:
                      NewFieldName = ''
                      FieldName_ori = FieldName.strip('.')
                      while '[' in  FieldName:
                          NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
                          Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
                          FieldName = FieldName.split(']', 1)[1]
                      FieldName = NewFieldName + FieldName
                      while '[' in FieldName and not Pcd.IsArray():
                          FieldName = FieldName.rsplit('[', 1)[0]
                          CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
          for skuname in Pcd.SkuOverrideValues:
              if skuname == TAB_COMMON:
                  continue
              for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
                  CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
                  for index in Pcd.SkuOverrideValues[skuname][defaultstorenameitem]:
                      if index:
                          ActualCap.append(index)
                      for FieldList in [Pcd.SkuOverrideValues[skuname][defaultstorenameitem][index]]:
                          if not FieldList:
                              continue
                          for FieldName in FieldList:
                              FieldName = "." + FieldName
                              IsArray = _IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
                              if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
                                  try:
                                      Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
                                  except BadExpression:
                                      EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
                                                      (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
                                  Value, ValueSize = ParseFieldValue(Value)
                                  if not Pcd.IsArray():
                                      CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
                              else:
                                  NewFieldName = ''
                                  FieldName_ori = FieldName.strip('.')
                                  while '[' in  FieldName:
                                      NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
                                      Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
                                      FieldName = FieldName.split(']', 1)[1]
                                  FieldName = NewFieldName + FieldName
                                  while '[' in FieldName and not Pcd.IsArray():
                                      FieldName = FieldName.rsplit('[', 1)[0]
                                      CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
          if Pcd.PcdFieldValueFromFdf:
              CApp = CApp + "// From fdf \n"
          for FieldName in Pcd.PcdFieldValueFromFdf:
              FieldName = "." + FieldName
              IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0])
              if IsArray and not (Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0].endswith('}')):
                  try:
                      Value = ValueExpressionEx(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
                  except BadExpression:
                      EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
                                      (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2]))
                  Value, ValueSize = ParseFieldValue(Value)
                  if not Pcd.IsArray():
                      CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][1], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][2], Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0]);
              else:
                  NewFieldName = ''
                  FieldName_ori = FieldName.strip('.')
                  while '[' in  FieldName:
                      NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
                      Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
                      FieldName = FieldName.split(']', 1)[1]
                  FieldName = NewFieldName + FieldName
                  while '[' in FieldName:
                      FieldName = FieldName.rsplit('[', 1)[0]
                      CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %s Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromFdf[FieldName_ori][1], Pcd.PcdFieldValueFromFdf[FieldName_ori][2], Pcd.PcdFieldValueFromFdf[FieldName_ori][0])
          if Pcd.PcdFieldValueFromComm:
              CApp = CApp + "// From Command Line \n"
          for FieldName in Pcd.PcdFieldValueFromComm:
              FieldName = "." + FieldName
              IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
              if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):
                  try:
                      Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], TAB_VOID, self._GuidDict)(True)
                  except BadExpression:
                      EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
                                      (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2]))
                  Value, ValueSize = ParseFieldValue(Value)
                  if not Pcd.IsArray():
                      CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0]);
              else:
                  NewFieldName = ''
                  FieldName_ori = FieldName.strip('.')
                  while '[' in  FieldName:
                      NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
                      Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
                      FieldName = FieldName.split(']', 1)[1]
                  FieldName = NewFieldName + FieldName
                  while '[' in FieldName and not Pcd.IsArray():
                      FieldName = FieldName.rsplit('[', 1)[0]
                      CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0])
          if Pcd.GetPcdMaxSize():
              CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())
          ArraySizeByAssign = self.CalculateActualCap(ActualCap)
          if ArraySizeByAssign > 1:
              CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); \n" % (ArraySizeByAssign, ArraySizeByAssign)
          CApp = CApp + "}\n"
          return CApp
      def CalculateActualCap(self,ActualCap):
          if not ActualCap:
              return 1
          maxsize = 1
          for item in ActualCap:
              index_elements = ArrayIndex.findall(item)
              rt = 1
              for index_e in index_elements:
                  index_num = index_e.lstrip("[").rstrip("]").strip()
                  if not index_num:
                      # Not support flexiable pcd array assignment
                      return 1
                  index_num = int(index_num,16) if index_num.startswith(("0x","0X")) else int(index_num)
                  rt = rt * (index_num+1)
              if rt  >maxsize:
                  maxsize = rt
  
          return maxsize
  
      @staticmethod
      def GenerateSizeStatments(Pcd,skuname,defaultstorename):
          if Pcd.IsArray():
              r_datatype = [Pcd.BaseDatumType]
              lastoneisEmpty = False
              for dem in Pcd.Capacity:
                  if lastoneisEmpty:
                      EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s.  " %
                                          (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName))))
                  if dem == '0' or dem == "-1":
                      r_datatype.append("[1]")
                      lastoneisEmpty = True
                  else:
                      r_datatype.append("[" + dem + "]")
  
              if Pcd.Type in [MODEL_PCD_DYNAMIC_EX_HII, MODEL_PCD_DYNAMIC_HII]:
                  PcdDefValue = Pcd.SkuInfoList.get(skuname).DefaultStoreDict.get(defaultstorename)
              elif Pcd.Type in [MODEL_PCD_DYNAMIC_EX_DEFAULT,MODEL_PCD_DYNAMIC_VPD,MODEL_PCD_DYNAMIC_DEFAULT,MODEL_PCD_DYNAMIC_EX_VPD]:
                  PcdDefValue = Pcd.SkuInfoList.get(skuname).DefaultValue
              else:
                  PcdDefValue = Pcd.DefaultValue
              if lastoneisEmpty:
                  if "{CODE(" not in PcdDefValue:
                      sizebasevalue_plus = "(%s / sizeof(%s) + 1)" % ((DscBuildData.GetStructurePcdMaxSize(Pcd), Pcd.BaseDatumType))
                      sizebasevalue = "(%s / sizeof(%s))" % ((DscBuildData.GetStructurePcdMaxSize(Pcd), Pcd.BaseDatumType))
                      sizeof = "sizeof(%s)" % Pcd.BaseDatumType
                      CApp = '  int ArraySize = %s %% %s ? %s : %s ;\n' % ( (DscBuildData.GetStructurePcdMaxSize(Pcd), sizeof, sizebasevalue_plus, sizebasevalue))
                      CApp += '  Size = ArraySize * sizeof(%s); \n' % Pcd.BaseDatumType
                  else:
                      CApp = "  Size = 0;\n"
              else:
                  CApp = '  Size = sizeof(%s);\n' % ("".join(r_datatype) )
          else:
              CApp = '  Size = sizeof(%s);\n' % (Pcd.DatumType)
          CApp = CApp + '  Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
          return CApp
  
      def GetIndicator(self,index,FieldName,Pcd):
          def cleanupindex(indexstr):
              return indexstr.strip("[").strip("]").strip()
          index_elements = ArrayIndex.findall(index)
          pcd_capacity = Pcd.Capacity
          if index:
              indicator = "(Pcd"
              if len(pcd_capacity)>2:
                  for i in range(0,len(index_elements)):
                      index_ele = index_elements[i]
                      index_num = index_ele.strip("[").strip("]").strip()
                      if i == len(index_elements) -2:
                          indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[i+1])),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1]), cleanupindex(index_elements[i]))
                          break
                      else:
                          indicator += " + %d*%s*Size/sizeof(%s)/%d" %(int(cleanupindex(index_elements[i])),reduce(lambda x,y: int(x)*int(y),pcd_capacity[i+1:-1]),Pcd.BaseDatumType,reduce(lambda x,y: int(x)*int(y),pcd_capacity[:-1]))
              elif len(pcd_capacity) == 2:
                  indicator += "+ %d*Size/sizeof(%s)/%d + %s)" %(int(cleanupindex(index_elements[0])),Pcd.BaseDatumType,int(pcd_capacity[0]), index_elements[1].strip("[").strip("]").strip())
              elif len(pcd_capacity) == 1:
                  index_ele = index_elements[0]
                  index_num = index_ele.strip("[").strip("]").strip()
                  indicator += " + %s)" % (index_num)
          else:
              indicator = "Pcd"
          if FieldName:
              indicator += "->" + FieldName
          return indicator
  
      def GetStarNum(self,Pcd):
          if not Pcd.IsArray():
              return 1
          elif Pcd.IsSimpleTypeArray():
              return len(Pcd.Capacity)
          else:
              return len(Pcd.Capacity) + 1
      def GenerateDefaultValueAssignFunction(self, Pcd):
          CApp = "// Default value in Dec \n"
          CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType)
          CApp = CApp + '  UINT32  FieldSize;\n'
          CApp = CApp + '  CHAR8   *Value;\n'
          CApp = CApp + ' UINT32 PcdArraySize;\n'
          DefaultValueFromDec = Pcd.DefaultValueFromDec
          IsArray = _IsFieldValueAnArray(Pcd.DefaultValueFromDec)
          if IsArray:
              try:
                  DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, TAB_VOID)(True)
              except BadExpression:
                  EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %
                                  (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))
          DefaultValueFromDec = StringToArray(DefaultValueFromDec)
          Value, ValueSize = ParseFieldValue (DefaultValueFromDec)
          if IsArray:
              #
              # Use memcpy() to copy value into field
              #
              if Pcd.IsArray():
                  pcdarraysize = Pcd.PcdArraySize()
                  if "{CODE(" in Pcd.DefaultValueFromDec:
                      if Pcd.Capacity[-1] != "-1":
                          CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_INIT_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From  %s Line %s \n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1])
                      CApp = CApp + ' PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
                      CApp = CApp + '  memcpy (Pcd, %s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
                  else:
                      if Pcd.Capacity[-1] != "-1":
                          CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1])
                      CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
                      CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
                      CApp = CApp + '  memcpy (Pcd, Value, PcdArraySize);\n'
              else:
                  if "{CODE(" in Pcd.DefaultValueFromDec:
                      CApp = CApp + '  PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
                      CApp = CApp + '  memcpy (Pcd, &%s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
                  else:
                      CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
                      CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
          elif isinstance(Value, str):
              CApp = CApp + '  Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)
          for index in Pcd.DefaultValues:
              FieldList = Pcd.DefaultValues[index]
              if not FieldList:
                  continue
              for FieldName in FieldList:
                  IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
                  if IsArray:
                      try:
                          FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
                      except BadExpression:
                          EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
                                          (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
  
                  try:
                      Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
                  except Exception:
                      EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
  
                  indicator = self.GetIndicator(index, FieldName,Pcd)
                  if IsArray:
                      #
                      # Use memcpy() to copy value into field
                      #
                      CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
                      CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                      CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                      CApp = CApp + '  memcpy (&%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize)
                  elif isinstance(Value, str):
                      CApp = CApp + '  %s = %s; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                  else:
                      if '[' in FieldName and ']' in FieldName:
                          Index = int(FieldName.split('[')[1].split(']')[0])
                          CApp = CApp + '  __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
                      if ValueSize > 4:
                          CApp = CApp + '  %s = %dULL; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                      else:
                          CApp = CApp + '  %s = %d; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
          CApp = CApp + "}\n"
          return CApp
  
      @staticmethod
      def GenerateDefaultValueAssignStatement(Pcd):
          CApp = '  Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
          return CApp
  
      def GetPcdDscRawDefaultValue(self,Pcd, SkuName,DefaultStoreName):
          if Pcd.Type in PCD_DYNAMIC_TYPE_SET or Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
              if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
                  pcddefaultvalue = Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT) if Pcd.DefaultFromDSC else None
              else:
                  pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)
          else:
              pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(TAB_DEFAULT_STORES_DEFAULT)
  
          return pcddefaultvalue
      def GetPcdDscRawValueInfo(self,Pcd, SkuName,DefaultStoreName):
          DscValueInfo = Pcd.DscRawValueInfo.get(SkuName, {}).get(DefaultStoreName)
          if DscValueInfo:
              dscfilepath,lineno = DscValueInfo
          else:
              dscfilepath = self.MetaFile.File
              lineno = ""
          return dscfilepath,lineno
  
      def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):
          CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName)
          CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.BaseDatumType)
          CApp = CApp + '  UINT32  FieldSize;\n'
          CApp = CApp + '  CHAR8   *Value;\n'
          CApp = CApp + ' UINT32 PcdArraySize;\n'
  
          CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
          inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]
          dscfilepath,lineno = self.GetPcdDscRawValueInfo(Pcd, SkuName, DefaultStoreName)
          if lineno:
              valuefrom = "%s Line %s" % (dscfilepath,str(lineno))
          else:
              valuefrom = dscfilepath
  
          pcddefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, SkuName, DefaultStoreName)
          if pcddefaultvalue:
              FieldList = pcddefaultvalue
              IsArray = _IsFieldValueAnArray(FieldList)
              if IsArray:
                  if "{CODE(" not in FieldList:
                      try:
                          FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
                      except BadExpression:
                          EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
                                          (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
              Value, ValueSize = ParseFieldValue (FieldList)
  
              if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
                  if isinstance(Value, str):
                      if "{CODE(" in Value:
                          if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
                              pcdarraysize = Pcd.PcdArraySize()
                              CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType, valuefrom)
                          CApp = CApp+ ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                          CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                      else:
                          CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
                  elif IsArray:
                      #
                      # Use memcpy() to copy value into field
                      #
                      if Pcd.IsArray():
                          pcdarraysize = Pcd.PcdArraySize()
                          if "{CODE(" in pcddefaultvalue:
                              if Pcd.Capacity[-1] != "-1":
                                  CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From  %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
                              CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                              CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                          else:
                              if Pcd.Capacity[-1] != "-1":
                                  CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From  %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
                              CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
                              CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
                              CApp = CApp + '  memcpy (Pcd, Value, PcdArraySize);\n'
                      else:
                          if "{CODE(" in pcddefaultvalue:
                              CApp = CApp + '  PcdArraySize = %d < sizeof(%s) * %d ? %d: sizeof(%s) * %d;\n ' % (ValueSize,Pcd.BaseDatumType,pcdarraysize,ValueSize,Pcd.BaseDatumType,pcdarraysize)
                              CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                          else:
                              CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
                              CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
              else:
                  if isinstance(Value, str):
                      if "{CODE(" in Value:
                          if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
                              pcdarraysize = Pcd.PcdArraySize()
                              CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
                          CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n '% (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                          CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                      else:
                          CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
                  elif IsArray:
                      #
                      # Use memcpy() to copy value into field
                      #
                      if Pcd.IsArray():
                          pcdarraysize = Pcd.PcdArraySize()
                          if "{CODE(" in pcddefaultvalue:
                              if Pcd.Capacity[-1] != "-1":
                                  CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From  %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
                              CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                              CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                          else:
                              if Pcd.Capacity[-1] != "-1":
                                  CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From  %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
                              CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
                              CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
                              CApp = CApp + '  memcpy (Pcd, Value, PcdArraySize);\n'
                      else:
                          if "{CODE(" in pcddefaultvalue:
                              CApp = CApp + '  PcdArraySize = %d < sizeof(%s) * %d ? %d: sizeof(%s) * %d;\n ' % (ValueSize,Pcd.BaseDatumType,pcdarraysize,ValueSize,Pcd.BaseDatumType,pcdarraysize)
                              CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                          else:
                              CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
                              CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
  
          inheritvalue = inherit_OverrideValues.get(DefaultStoreName)
          if not inheritvalue:
              inheritvalue = []
          for index in inheritvalue:
              FieldList = inheritvalue[index]
              if not FieldList:
                  continue
              if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT) or (( (SkuName, '') not in Pcd.ValueChain) and ( (SkuName, DefaultStoreName) not in Pcd.ValueChain )):
                  for FieldName in FieldList:
                      indicator = self.GetIndicator(index, FieldName,Pcd)
                      IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
                      if IsArray:
                          try:
                              FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
                          except BadExpression:
                              EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
                                              (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
                      try:
                          Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
                      except Exception:
                          EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
                      if isinstance(Value, str):
                          CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                      elif IsArray:
                      #
                      # Use memcpy() to copy value into field
                      #
                          CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
                          CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                          CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                          CApp = CApp + '  memcpy (&%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (indicator, ValueSize, ValueSize)
                      else:
                          if '[' in FieldName and ']' in FieldName:
                              Index = int(FieldName.split('[')[1].split(']')[0])
                              CApp = CApp + '  __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
                          if ValueSize > 4:
                              CApp = CApp + '  %s = %dULL; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                          else:
                              CApp = CApp + '  %s = %d; // From %s Line %d Value %s\n' % (indicator, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
          CApp = CApp + "}\n"
          return CApp
  
      @staticmethod
      def GenerateInitValueStatement(Pcd, SkuName, DefaultStoreName):
          CApp = '  Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName)
          return CApp
  
      def GenerateCommandLineValue(self, Pcd):
          CApp = "// Value in CommandLine\n"
          CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType)
          CApp = CApp + '  UINT32  FieldSize;\n'
          CApp = CApp + '  CHAR8   *Value;\n'
  
          pcddefaultvalue = Pcd.PcdValueFromComm
          for FieldList in [pcddefaultvalue, Pcd.PcdFieldValueFromComm]:
              if not FieldList:
                  continue
              if pcddefaultvalue and FieldList == pcddefaultvalue:
                  IsArray = _IsFieldValueAnArray(FieldList)
                  if IsArray:
                      try:
                          FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
                      except BadExpression:
                          EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %
                                          (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
                  Value, ValueSize = ParseFieldValue (FieldList)
  
                  if isinstance(Value, str):
                      CApp = CApp + '  Pcd = %s; // From Command Line \n' % (Value)
                  elif IsArray:
                  #
                  # Use memcpy() to copy value into field
                  #
                      CApp = CApp + '  Value     = %s; // From Command Line.\n' % (DscBuildData.IntToCString(Value, ValueSize))
                      CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
                  continue
              for FieldName in FieldList:
                  IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
                  if IsArray:
                      try:
                          FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
                      except BadExpression:
                          EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
                                          (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
                      except:
                          print("error")
                  try:
                      Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
                  except Exception:
                      EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
                  if isinstance(Value, str):
                      CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                  elif IsArray:
                  #
                  # Use memcpy() to copy value into field
                  #
                      CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
                      CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                      CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                      CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
                  else:
                      if '[' in FieldName and ']' in FieldName:
                          Index = int(FieldName.split('[')[1].split(']')[0])
                          CApp = CApp + '  __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
                      if ValueSize > 4:
                          CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                      else:
                          CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
          CApp = CApp + "}\n"
          return CApp
  
      @staticmethod
      def GenerateCommandLineValueStatement(Pcd):
          CApp = '  Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
          return CApp
      def GenerateFdfValue(self,Pcd):
          CApp = "// Value in Fdf\n"
          CApp = CApp + "void Assign_%s_%s_Fdf_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.BaseDatumType)
          CApp = CApp + '  UINT32  FieldSize;\n'
          CApp = CApp + '  CHAR8   *Value;\n'
  
          pcddefaultvalue = Pcd.PcdValueFromFdf
          for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromFdf]:
              if not FieldList:
                  continue
              if pcddefaultvalue and FieldList == pcddefaultvalue:
                  IsArray = _IsFieldValueAnArray(FieldList)
                  if IsArray:
                      try:
                          FieldList = ValueExpressionEx(FieldList, TAB_VOID)(True)
                      except BadExpression:
                          EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Fdf: %s" %
                                          (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
                  Value, ValueSize = ParseFieldValue (FieldList)
  
                  if isinstance(Value, str):
                      CApp = CApp + '  Pcd = %s; // From Fdf \n' % (Value)
                  elif IsArray:
                  #
                  # Use memcpy() to copy value into field
                  #
                      CApp = CApp + '  Value     = %s; // From Fdf .\n' % (DscBuildData.IntToCString(Value, ValueSize))
                      CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
                  continue
              for FieldName in FieldList:
                  IsArray = _IsFieldValueAnArray(FieldList[FieldName][0])
                  if IsArray:
                      try:
                          FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], TAB_VOID, self._GuidDict)(True)
                      except BadExpression:
                          EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
                                          (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
                      except:
                          print("error")
                  try:
                      Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
                  except Exception:
                      EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))
                  if isinstance(Value, str):
                      CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                  elif IsArray:
                  #
                  # Use memcpy() to copy value into field
                  #
                      CApp = CApp + '  FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.BaseDatumType, FieldName)
                      CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                      CApp = CApp + '  __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.BaseDatumType, FieldName, ValueSize, Pcd.BaseDatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                      CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
                  else:
                      if '[' in FieldName and ']' in FieldName:
                          Index = int(FieldName.split('[')[1].split(']')[0])
                          CApp = CApp + '  __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName)
                      if ValueSize > 4:
                          CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
                      else:
                          CApp = CApp + '  Pcd->%s = %d; // From %s Line %s Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
          CApp = CApp + "}\n"
          return CApp
  
      @staticmethod
      def GenerateFdfValueStatement(Pcd):
          CApp = '  Assign_%s_%s_Fdf_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
          return CApp
  
      def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
          OverrideValues = {DefaultStore:{}}
          if Pcd.SkuOverrideValues:
              OverrideValues = Pcd.SkuOverrideValues[SkuName]
          if not OverrideValues:
              OverrideValues = {TAB_DEFAULT_STORES_DEFAULT:Pcd.DefaultValues}
          for DefaultStoreName in OverrideValues:
              CApp = CApp + 'void\n'
              CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
              CApp = CApp + '  void\n'
              CApp = CApp + '  )\n'
              CApp = CApp + '{\n'
              CApp = CApp + '  UINT32  Size;\n'
              CApp = CApp + '  UINT32  FieldSize;\n'
              CApp = CApp + '  CHAR8   *Value;\n'
              CApp = CApp + '  UINT32  OriginalSize;\n'
              CApp = CApp + '  VOID    *OriginalPcd;\n'
  
              CApp = CApp + '  %s      *Pcd;  // From %s Line %d \n' % (Pcd.BaseDatumType,Pcd.PkgPath, Pcd.PcdDefineLineNo)
  
              CApp = CApp + '\n'
  
              PcdDefaultValue = StringToArray(Pcd.DefaultValueFromDec.strip())
  
              InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
  
              #
              # Get current PCD value and size
              #
              CApp = CApp + '  OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
  
              #
              # Determine the size of the PCD.  For simple structures, sizeof(TYPE) provides
              # the correct value.  For structures with a flexible array member, the flexible
              # array member is detected, and the size is based on the highest index used with
              # the flexible array member.  The flexible array member must be the last field
              # in a structure.  The size formula for this case is:
              # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
              #
              CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd,SkuName,DefaultStoreName)
              if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
                  CApp = CApp + '  OriginalSize = OriginalSize < sizeof(%s) * %d? OriginalSize:sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize(),Pcd.BaseDatumType,Pcd.PcdArraySize())
                  CApp = CApp + '  Size = sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize())
  
              #
              # Allocate and zero buffer for the PCD
              # Must handle cases where current value is smaller, larger, or same size
              # Always keep that larger one as the current size
              #
              CApp = CApp + '  Size = (OriginalSize > Size ? OriginalSize : Size);\n'
              CApp = CApp + '  Pcd     = (%s *)malloc (Size);\n' % (Pcd.BaseDatumType,)
              CApp = CApp + '  memset (Pcd, 0, Size);\n'
  
              #
              # Copy current PCD value into allocated buffer.
              #
              CApp = CApp + '  memcpy (Pcd, OriginalPcd, OriginalSize);\n'
  
              #
              # Assign field values in PCD
              #
              CApp = CApp + DscBuildData.GenerateDefaultValueAssignStatement(Pcd)
              if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
                          self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
                  for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
                      storeset = [DefaultStoreName] if DefaultStoreName == TAB_DEFAULT_STORES_DEFAULT else [TAB_DEFAULT_STORES_DEFAULT, DefaultStoreName]
                      for defaultstorenameitem in storeset:
                          CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
                          CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, skuname, defaultstorenameitem)
                      if skuname == SkuName:
                          break
              else:
                  CApp = CApp + "// SkuName: %s,  DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
                  CApp = CApp + DscBuildData.GenerateInitValueStatement(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
              CApp = CApp + DscBuildData.GenerateFdfValueStatement(Pcd)
              CApp = CApp + DscBuildData.GenerateCommandLineValueStatement(Pcd)
              #
              # Set new PCD value and size
              #
              CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (void *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
  
              #
              # Free PCD
              #
              CApp = CApp + '  free (Pcd);\n'
              CApp = CApp + '}\n'
              CApp = CApp + '\n'
          return InitByteValue, CApp
  
      def GenerateArrayAssignment(self, Pcd):
          CApp = ""
          if not Pcd:
              return CApp
          Demesion = ""
          for d in Pcd.Capacity:
              Demesion += "[]"
  
          Value = Pcd.DefaultValueFromDec
          if "{CODE(" in Pcd.DefaultValueFromDec:
              realvalue = Pcd.DefaultValueFromDec.strip()[6:-2] # "{CODE(").rstrip(")}"
              CApp += "static %s %s_%s_INIT_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Demesion,realvalue)
  
          if Pcd.Type in PCD_DYNAMIC_TYPE_SET | PCD_DYNAMIC_EX_TYPE_SET:
              for skuname in Pcd.SkuInfoList:
                  skuinfo = Pcd.SkuInfoList[skuname]
                  if skuinfo.VariableName:
                      for defaultstore in skuinfo.DefaultStoreDict:
                          pcddscrawdefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, skuname, defaultstore)
                          if pcddscrawdefaultvalue:
                              Value = skuinfo.DefaultStoreDict[defaultstore]
                              if "{CODE(" in Value:
                                  realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}"
                                  CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Demesion,realvalue)
                  else:
                      pcddscrawdefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, skuname, TAB_DEFAULT_STORES_DEFAULT)
                      if pcddscrawdefaultvalue:
                          Value = skuinfo.DefaultValue
                          if "{CODE(" in Value:
                              realvalue = Value.strip()[6:-2] # "{CODE(").rstrip(")}"
                              CApp += "static %s %s_%s_%s_%s_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Demesion,realvalue)
          else:
              pcddscrawdefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
              if pcddscrawdefaultvalue:
                  if "{CODE(" in Pcd.DefaultValue:
                      realvalue = Pcd.DefaultValue.strip()[6:-2] # "{CODE(").rstrip(")}"
                      CApp += "static %s %s_%s_DEFAULT_STANDARD_Value%s = %s;\n" % (Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Demesion,realvalue)
  
          return CApp
  
      def SkuOverrideValuesEmpty(self,OverrideValues):
          if not OverrideValues:
              return True
          for key in OverrideValues:
              if OverrideValues[key]:
                  return False
          return True
  
      def ParseCCFlags(self, ccflag):
          ccflags = set()
          ccflaglist = ccflag.split(" ")
          i = 0
          while i < len(ccflaglist):
              item = ccflaglist[i].strip()
              if item in (r"/D", r"/U","-D","-U"):
                  ccflags.add(" ".join((ccflaglist[i],ccflaglist[i+1])))
                  i = i+1
              elif item.startswith((r"/D", r"/U","-D","-U")):
                  ccflags.add(item)
              i +=1
          return ccflags
      def GenerateByteArrayValue (self, StructuredPcds):
          #
          # Generate/Compile/Run C application to determine if there are any flexible array members
          #
          if not StructuredPcds:
              return
  
          InitByteValue = ""
          CApp = PcdMainCHeader
  
          IncludeFiles = set()
          for PcdName in StructuredPcds:
              Pcd = StructuredPcds[PcdName]
              for IncludeFile in Pcd.StructuredPcdIncludeFile:
                  if IncludeFile not in IncludeFiles:
                      IncludeFiles.add(IncludeFile)
                      CApp = CApp + '#include <%s>\n' % (IncludeFile)
          CApp = CApp + '\n'
          for Pcd in StructuredPcds.values():
              CApp = CApp + self.GenerateArrayAssignment(Pcd)
          for PcdName in StructuredPcds:
              Pcd = StructuredPcds[PcdName]
              CApp = CApp + self.GenerateSizeFunction(Pcd)
              CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
              CApp = CApp + self.GenerateFdfValue(Pcd)
              CApp = CApp + self.GenerateCommandLineValue(Pcd)
              if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
                          self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
                  CApp = CApp + self.GenerateInitValueFunction(Pcd, self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT)
              else:
                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
                      if SkuName not in Pcd.SkuOverrideValues:
                          continue
                      for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
                          CApp = CApp + self.GenerateInitValueFunction(Pcd, SkuName, DefaultStoreName)
              if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
                          self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
                  InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd, InitByteValue, CApp)
              else:
                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
                      if SkuName not in Pcd.SkuOverrideValues:
                          continue
                      for DefaultStoreName in Pcd.DefaultStoreName:
                          Pcd = StructuredPcds[PcdName]
                          InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
  
          CApp = CApp + 'VOID\n'
          CApp = CApp + 'PcdEntryPoint(\n'
          CApp = CApp + '  VOID\n'
          CApp = CApp + '  )\n'
          CApp = CApp + '{\n'
          for Pcd in StructuredPcds.values():
              if self.SkuOverrideValuesEmpty(Pcd.SkuOverrideValues) or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
                  CApp = CApp + '  Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, TAB_DEFAULT_STORES_DEFAULT, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
              else:
                  for SkuName in self.SkuIdMgr.SkuOverrideOrder():
                      if SkuName not in self.SkuIdMgr.AvailableSkuIdSet:
                          continue
                      for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
                          CApp = CApp + '  Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
          CApp = CApp + '}\n'
  
          CApp = CApp + PcdMainCEntry + '\n'
  
          if not os.path.exists(self.OutputPath):
              os.makedirs(self.OutputPath)
          CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
          SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
  
          MakeApp = PcdMakefileHeader
          if sys.platform == "win32":
              MakeApp = MakeApp + 'APPFILE = %s\%s.exe\n' % (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
          else:
              MakeApp = MakeApp + PcdGccMakefile
              MakeApp = MakeApp + 'APPFILE = %s/%s\n' % (self.OutputPath, PcdValueInitName) + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \
                        'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +='
  
          IncSearchList = []
          PlatformInc = OrderedDict()
          for Cache in self._Bdb._CACHE_.values():
              if Cache.MetaFile.Ext.lower() != '.dec':
                  continue
              if Cache.Includes:
                  if str(Cache.MetaFile.Path) not in PlatformInc:
                      PlatformInc[str(Cache.MetaFile.Path)] = []
                      PlatformInc[str(Cache.MetaFile.Path)].append (os.path.dirname(Cache.MetaFile.Path))
                      PlatformInc[str(Cache.MetaFile.Path)].extend (Cache.CommonIncludes)
  
          PcdDependDEC = []
          for Pcd in StructuredPcds.values():
              for PackageDec in Pcd.PackageDecs:
                  Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
                  if not os.path.exists(Package):
                      EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
                  if Package not in PcdDependDEC:
                      PcdDependDEC.append(Package)
  
          if PlatformInc and PcdDependDEC:
              for pkg in PcdDependDEC:
                  if pkg in PlatformInc:
                      for inc in PlatformInc[pkg]:
                          MakeApp += '-I'  + str(inc) + ' '
                          IncSearchList.append(inc)
          MakeApp = MakeApp + '\n'
  
          CC_FLAGS = LinuxCFLAGS
          if sys.platform == "win32":
              CC_FLAGS = WindowsCFLAGS
          BuildOptions = OrderedDict()
          for Options in self.BuildOptions:
              if Options[2] != EDKII_NAME:
                  continue
              Family = Options[0]
              if Family and Family != self.ToolChainFamily:
                  continue
              Target, Tag, Arch, Tool, Attr = Options[1].split("_")
              if Tool != 'CC':
                  continue
              if Attr != "FLAGS":
                  continue
              if Target == TAB_STAR or Target == self._Target:
                  if Tag == TAB_STAR or Tag == self._Toolchain:
                      if 'COMMON' not in BuildOptions:
                          BuildOptions['COMMON'] = set()
                      if Arch == TAB_STAR:
                          BuildOptions['COMMON']|= self.ParseCCFlags(self.BuildOptions[Options])
                      if Arch in self.SupArchList:
                          if Arch not in BuildOptions:
                              BuildOptions[Arch] = set()
                          BuildOptions[Arch] |= self.ParseCCFlags(self.BuildOptions[Options])
  
          if BuildOptions:
              ArchBuildOptions = {arch:flags for arch,flags in BuildOptions.items() if arch != 'COMMON'}
              if len(ArchBuildOptions.keys()) == 1:
                  BuildOptions['COMMON'] |= (list(ArchBuildOptions.values())[0])
              elif len(ArchBuildOptions.keys()) > 1:
                  CommonBuildOptions = reduce(lambda x,y: x&y, ArchBuildOptions.values())
                  BuildOptions['COMMON'] |= CommonBuildOptions
              ValueList = [item for item in BuildOptions['COMMON'] if item.startswith((r"/U","-U"))]
              ValueList.extend([item for item in BuildOptions['COMMON'] if item.startswith((r"/D", "-D"))])
              CC_FLAGS += " ".join(ValueList)
          MakeApp += CC_FLAGS
  
          if sys.platform == "win32":
              MakeApp = MakeApp + PcdMakefileEnd
              MakeApp = MakeApp + AppTarget % ("""\tcopy $(APPLICATION) $(APPFILE) /y """)
          else:
              MakeApp = MakeApp + AppTarget % ("""\tcp $(APPLICATION) $(APPFILE) """)
          MakeApp = MakeApp + '\n'
          IncludeFileFullPaths = []
          for includefile in IncludeFiles:
              for includepath in IncSearchList:
                  includefullpath = os.path.join(str(includepath), includefile)
                  if os.path.exists(includefullpath):
                      IncludeFileFullPaths.append(os.path.normpath(includefullpath))
                      break
          SearchPathList = []
          SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include")))
          SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common")))
          SearchPathList.extend(str(item) for item in IncSearchList)
          IncFileList = GetDependencyList(IncludeFileFullPaths, SearchPathList)
          for include_file in IncFileList:
              MakeApp += "$(OBJECTS) : %s\n" % include_file
          MakeFileName = os.path.join(self.OutputPath, 'Makefile')
          MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
          SaveFileOnChange(MakeFileName, MakeApp, False)
  
          InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
          OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
          SaveFileOnChange(InputValueFile, InitByteValue, False)
  
          Dest_PcdValueInitExe = PcdValueInitName
          if not sys.platform == "win32":
              Dest_PcdValueInitExe = os.path.join(self.OutputPath, PcdValueInitName)
          else:
              Dest_PcdValueInitExe = os.path.join(self.OutputPath, PcdValueInitName) +".exe"
          Messages = ''
          if sys.platform == "win32":
              MakeCommand = 'nmake -f %s' % (MakeFileName)
              returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
              Messages = StdOut
          else:
              MakeCommand = 'make -f %s' % (MakeFileName)
              returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (MakeCommand)
              Messages = StdErr
  
          Messages = Messages.split('\n')
          MessageGroup = []
          if returncode != 0:
              CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
              File = open (CAppBaseFileName + '.c', 'r')
              FileData = File.readlines()
              File.close()
              for Message in Messages:
                  if " error" in Message or "warning" in Message:
                      FileInfo = Message.strip().split('(')
                      if len (FileInfo) > 1:
                          FileName = FileInfo [0]
                          FileLine = FileInfo [1].split (')')[0]
                      else:
                          FileInfo = Message.strip().split(':')
                          if len(FileInfo) < 2:
                              continue
                          FileName = FileInfo [0]
                          FileLine = FileInfo [1]
                      if FileLine.isdigit():
                          error_line = FileData[int (FileLine) - 1]
                          if r"//" in error_line:
                              c_line, dsc_line = error_line.split(r"//")
                          else:
                              dsc_line = error_line
                          message_itmes = Message.split(":")
                          Index = 0
                          if "PcdValueInit.c" not in Message:
                              if not MessageGroup:
                                  MessageGroup.append(Message)
                              break
                          else:
                              for item in message_itmes:
                                  if "PcdValueInit.c" in item:
                                      Index = message_itmes.index(item)
                                      message_itmes[Index] = dsc_line.strip()
                                      break
                              MessageGroup.append(":".join(message_itmes[Index:]).strip())
                              continue
                      else:
                          MessageGroup.append(Message)
              if MessageGroup:
                  EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
              else:
                  EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
  
          if DscBuildData.NeedUpdateOutput(OutputValueFile, Dest_PcdValueInitExe, InputValueFile):
              Command = Dest_PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
              returncode, StdOut, StdErr = DscBuildData.ExecuteCommand (Command)
              if returncode != 0:
                  EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
  
          File = open (OutputValueFile, 'r')
          FileBuffer = File.readlines()
          File.close()
  
          StructurePcdSet = []
          for Pcd in FileBuffer:
              PcdValue = Pcd.split ('|')
              PcdInfo = PcdValue[0].split ('.')
              StructurePcdSet.append((PcdInfo[0], PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
          return StructurePcdSet
  
      @staticmethod
      def NeedUpdateOutput(OutputFile, ValueCFile, StructureInput):
          if not os.path.exists(OutputFile):
              return True
          if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
              return True
          if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:
              return True
          return False
  
      ## Retrieve dynamic PCD settings
      #
      #   @param  Type    PCD type
      #
      #   @retval a dict object contains settings of given PCD type
      #
      def _GetDynamicPcd(self, Type):
  
  
          Pcds = OrderedDict()
          #
          # tdict is a special dict kind of type, used for selecting correct
          # PCD settings for certain ARCH and SKU
          #
          PcdDict = tdict(True, 4)
          PcdList = []
          # Find out all possible PCD candidates for self._Arch
          RecordList = self._RawData[Type, self._Arch]
          AvailableSkuIdSet = copy.copy(self.SkuIds)
  
  
          for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
              SkuName = SkuName.upper()
              SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
              if SkuName not in AvailableSkuIdSet:
                  EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
                                              File=self.MetaFile, Line=Dummy5)
              if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, Dummy5) not in PcdList:
                  PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
              PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
  
          # Remove redundant PCD candidates, per the ARCH and SKU
          for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
  
              Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
              if Setting is None:
                  continue
  
              PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
              if MaxDatumSize:
                  if int(MaxDatumSize, 0) > 0xFFFF:
                      EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
                                      File=self.MetaFile, Line=Dummy4)
                  if int(MaxDatumSize, 0) < 0:
                      EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
                                      File=self.MetaFile, Line=Dummy4)
              SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
              if (PcdCName, TokenSpaceGuid) in Pcds:
                  pcdObject = Pcds[PcdCName, TokenSpaceGuid]
                  pcdObject.SkuInfoList[SkuName] = SkuInfo
                  if MaxDatumSize.strip():
                      CurrentMaxSize = int(MaxDatumSize.strip(), 0)
                  else:
                      CurrentMaxSize = 0
                  if pcdObject.MaxDatumSize:
                      PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
                  else:
                      PcdMaxSize = 0
                  if CurrentMaxSize > PcdMaxSize:
                      pcdObject.MaxDatumSize = str(CurrentMaxSize)
              else:
                  Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
                                                      PcdCName,
                                                      TokenSpaceGuid,
                                                      self._PCD_TYPE_STRING_[Type],
                                                      DatumType,
                                                      PcdValue,
                                                      '',
                                                      MaxDatumSize,
                                                      OrderedDict({SkuName : SkuInfo}),
                                                      False,
                                                      None,
                                                      IsDsc=True)
  
              if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
                  Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
                  Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
              Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
              Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Dummy4)
  
          for pcd in Pcds.values():
              pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
              # Only fix the value while no value provided in DSC file.
              for sku in pcd.SkuInfoList.values():
                  if not sku.DefaultValue:
                      sku.DefaultValue = pcdDecObject.DefaultValue
              if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
                  valuefromDec = pcdDecObject.DefaultValue
                  SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', '', valuefromDec)
                  pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
              elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
                  pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
                  del pcd.SkuInfoList[TAB_COMMON]
              elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
                  del pcd.SkuInfoList[TAB_COMMON]
  
          list(map(self.FilterSkuSettings, Pcds.values()))
  
          return Pcds
  
      def FilterSkuSettings(self, PcdObj):
  
          if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
              if TAB_DEFAULT in PcdObj.SkuInfoList and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList:
                  PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList[TAB_DEFAULT]
              PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
              PcdObj.SkuInfoList[TAB_DEFAULT].SkuIdName = TAB_DEFAULT
              PcdObj.SkuInfoList[TAB_DEFAULT].SkuId = '0'
  
          elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
              PcdObj.SkuInfoList = {TAB_DEFAULT:PcdObj.SkuInfoList[TAB_DEFAULT]}
  
          return PcdObj
  
      @staticmethod
      def CompareVarAttr(Attr1, Attr2):
          if not Attr1 or not Attr2:  # for empty string
              return True
          Attr1s = [attr.strip() for attr in Attr1.split(",")]
          Attr1Set = set(Attr1s)
          Attr2s = [attr.strip() for attr in Attr2.split(",")]
          Attr2Set = set(Attr2s)
          if Attr2Set == Attr1Set:
              return True
          else:
              return False
  
      def CompletePcdValues(self, PcdSet):
          Pcds = OrderedDict()
          DefaultStoreObj = DefaultStore(self._GetDefaultStores())
          SkuIds = {skuname:skuid for skuname, skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname != TAB_COMMON}
          DefaultStores = set(storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict)
          for PcdCName, TokenSpaceGuid in PcdSet:
              PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
  
              if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
                          self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
                  Pcds[PcdCName, TokenSpaceGuid]= PcdObj
                  continue
              PcdType = PcdObj.Type
              if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
                  for skuid in PcdObj.SkuInfoList:
                      skuobj = PcdObj.SkuInfoList[skuid]
                      mindefaultstorename = DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict))
                      for defaultstorename in DefaultStores:
                          if defaultstorename not in skuobj.DefaultStoreDict:
                              skuobj.DefaultStoreDict[defaultstorename] = skuobj.DefaultStoreDict[mindefaultstorename]
                      skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
              for skuname, skuid in SkuIds.items():
                  if skuname not in PcdObj.SkuInfoList:
                      nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
                      while nextskuid not in PcdObj.SkuInfoList:
                          nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
                      PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
                      PcdObj.SkuInfoList[skuname].SkuId = skuid
                      PcdObj.SkuInfoList[skuname].SkuIdName = skuname
              if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
                  PcdObj.DefaultValue = list(PcdObj.SkuInfoList.values())[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList[TAB_DEFAULT].HiiDefaultValue
              Pcds[PcdCName, TokenSpaceGuid]= PcdObj
          return Pcds
      ## Retrieve dynamic HII PCD settings
      #
      #   @param  Type    PCD type
      #
      #   @retval a dict object contains settings of given PCD type
      #
      def _GetDynamicHiiPcd(self, Type):
  
          VariableAttrs = {}
  
          Pcds = OrderedDict()
          UserDefinedDefaultStores = []
          #
          # tdict is a special dict kind of type, used for selecting correct
          # PCD settings for certain ARCH and SKU
          #
          PcdDict = tdict(True, 5)
          PcdList = []
          RecordList = self._RawData[Type, self._Arch]
          # Find out all possible PCD candidates for self._Arch
          AvailableSkuIdSet = copy.copy(self.SkuIds)
          DefaultStoresDefine = self._GetDefaultStores()
  
          for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4, Dummy5 in RecordList:
              SkuName = SkuName.upper()
              SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
              DefaultStore = DefaultStore.upper()
              if DefaultStore == TAB_COMMON:
                  DefaultStore = TAB_DEFAULT_STORES_DEFAULT
              else:
                  #The end user define [DefaultStores] and [SKUID_IDENTIFIER.Menufacturing] in DSC
                  UserDefinedDefaultStores.append((PcdCName, TokenSpaceGuid))
              if SkuName not in AvailableSkuIdSet:
                  EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
                                              File=self.MetaFile, Line=Dummy5)
              if DefaultStore not in DefaultStoresDefine:
                  EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
                                              File=self.MetaFile, Line=Dummy5)
              if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5) not in PcdList:
                  PcdList.append((PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy5))
              PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore] = Setting
  
  
          # Remove redundant PCD candidates, per the ARCH and SKU
          for PcdCName, TokenSpaceGuid, SkuName, DefaultStore, Dummy4 in PcdList:
  
              Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid, DefaultStore]
              if Setting is None:
                  continue
              VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
  
              rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
              if not rt:
                  EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
                          ExtraData="[%s]" % VarAttribute)
              ExceedMax = False
              FormatCorrect = True
              if VariableOffset.isdigit():
                  if int(VariableOffset, 10) > 0xFFFF:
                      ExceedMax = True
              elif variablePattern.match(VariableOffset):
                  if int(VariableOffset, 16) > 0xFFFF:
                      ExceedMax = True
              # For Offset written in "A.B"
              elif VariableOffset.find('.') > -1:
                  VariableOffsetList = VariableOffset.split(".")
                  if not (len(VariableOffsetList) == 2
                          and IsValidWord(VariableOffsetList[0])
                          and IsValidWord(VariableOffsetList[1])):
                      FormatCorrect = False
              else:
                  FormatCorrect = False
              if not FormatCorrect:
                  EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
  
              if ExceedMax:
                  EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
              if (VariableName, VariableGuid) not in VariableAttrs:
                  VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
              else:
                  if not DscBuildData.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
                      EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))
  
              pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
              if (PcdCName, TokenSpaceGuid) in Pcds:
                  pcdObject = Pcds[PcdCName, TokenSpaceGuid]
                  if SkuName in pcdObject.SkuInfoList:
                      Skuitem = pcdObject.SkuInfoList[SkuName]
                      Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
                  else:
                      SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
                      pcdObject.SkuInfoList[SkuName] = SkuInfo
              else:
                  SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute, DefaultStore={DefaultStore:DefaultValue})
                  PcdClassObj = PcdClassObject(
                                                  PcdCName,
                                                  TokenSpaceGuid,
                                                  self._PCD_TYPE_STRING_[Type],
                                                  '',
                                                  DefaultValue,
                                                  '',
                                                  '',
                                                  OrderedDict({SkuName : SkuInfo}),
                                                  False,
                                                  None,
                                                  pcdDecObject.validateranges,
                                                  pcdDecObject.validlists,
                                                  pcdDecObject.expressions,
                                                  IsDsc=True)
                  if (PcdCName, TokenSpaceGuid) in UserDefinedDefaultStores:
                      PcdClassObj.UserDefinedDefaultStoresFlag = True
                  Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj
  
                  Pcds[PcdCName, TokenSpaceGuid].CustomAttribute['DscPosition'] = int(Dummy4)
              if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
                  Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
                  Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
              Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue
              Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][DefaultStore] = (self.MetaFile.File,Dummy4)
          for pcd in Pcds.values():
              pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
              pcd.DatumType = pcdDecObject.DatumType
              # Only fix the value while no value provided in DSC file.
              for sku in pcd.SkuInfoList.values():
                  if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue is None):
                      sku.HiiDefaultValue = pcdDecObject.DefaultValue
                      for default_store in sku.DefaultStoreDict:
                          sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue
                      pcd.DefaultValue = pcdDecObject.DefaultValue
              if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
                  SkuInfoObj = list(pcd.SkuInfoList.values())[0]
                  valuefromDec = pcdDecObject.DefaultValue
                  SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec, VariableAttribute=SkuInfoObj.VariableAttribute, DefaultStore={DefaultStore:valuefromDec})
                  pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
              elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
                  pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
                  del pcd.SkuInfoList[TAB_COMMON]
              elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
                  del pcd.SkuInfoList[TAB_COMMON]
  
              if pcd.MaxDatumSize.strip():
                  MaxSize = int(pcd.MaxDatumSize, 0)
              else:
                  MaxSize = 0
              if pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
                  for (_, skuobj) in pcd.SkuInfoList.items():
                      datalen = 0
                      skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
                      datalen = len(skuobj.HiiDefaultValue.split(","))
                      if datalen > MaxSize:
                          MaxSize = datalen
                      for defaultst in skuobj.DefaultStoreDict:
                          skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
                  pcd.DefaultValue = StringToArray(pcd.DefaultValue)
                  pcd.MaxDatumSize = str(MaxSize)
          rt, invalidhii = DscBuildData.CheckVariableNameAssignment(Pcds)
          if not rt:
              invalidpcd = ",".join(invalidhii)
              EdkLogger.error('build', PCD_VARIABLE_INFO_ERROR, Message='The same HII PCD must map to the same EFI variable for all SKUs', File=self.MetaFile, ExtraData=invalidpcd)
  
          list(map(self.FilterSkuSettings, Pcds.values()))
  
          return Pcds
  
      @staticmethod
      def CheckVariableNameAssignment(Pcds):
          invalidhii = []
          for pcdname in Pcds:
              pcd = Pcds[pcdname]
              varnameset = set(sku.VariableName for (skuid, sku) in pcd.SkuInfoList.items())
              if len(varnameset) > 1:
                  invalidhii.append(".".join((pcdname[1], pcdname[0])))
          if len(invalidhii):
              return False, invalidhii
          else:
              return True, []
      ## Retrieve dynamic VPD PCD settings
      #
      #   @param  Type    PCD type
      #
      #   @retval a dict object contains settings of given PCD type
      #
      def _GetDynamicVpdPcd(self, Type):
  
  
          Pcds = OrderedDict()
          #
          # tdict is a special dict kind of type, used for selecting correct
          # PCD settings for certain ARCH and SKU
          #
          PcdDict = tdict(True, 4)
          PcdList = []
  
          # Find out all possible PCD candidates for self._Arch
          RecordList = self._RawData[Type, self._Arch]
          AvailableSkuIdSet = copy.copy(self.SkuIds)
  
          for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4, Dummy5 in RecordList:
              SkuName = SkuName.upper()
              SkuName = TAB_DEFAULT if SkuName == TAB_COMMON else SkuName
              if SkuName not in AvailableSkuIdSet:
                  EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
                                              File=self.MetaFile, Line=Dummy5)
              if "." not in TokenSpaceGuid and "[" not in PcdCName and (PcdCName, TokenSpaceGuid, SkuName, Dummy5) not in PcdList:
                  PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
              PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
  
          # Remove redundant PCD candidates, per the ARCH and SKU
          for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
              Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
              if Setting is None:
                  continue
              #
              # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
              # For the Integer & Boolean type, the optional data can only be InitialValue.
              # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
              # until the DEC parser has been called.
              #
              VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
              if MaxDatumSize:
                  if int(MaxDatumSize, 0) > 0xFFFF:
                      EdkLogger.error('build', FORMAT_INVALID, "The size value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)),
                                      File=self.MetaFile, Line=Dummy4)
                  if int(MaxDatumSize, 0) < 0:
                      EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
                                      File=self.MetaFile, Line=Dummy4)
              SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
              if (PcdCName, TokenSpaceGuid) in Pcds:
                  pcdObject = Pcds[PcdCName, TokenSpaceGuid]
                  pcdObject.SkuInfoList[SkuName] = SkuInfo
                  if MaxDatumSize.strip():
                      CurrentMaxSize = int(MaxDatumSize.strip(), 0)
                  else:
                      CurrentMaxSize = 0
                  if pcdObject.MaxDatumSize:
                      PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
                  else:
                      PcdMaxSize = 0
                  if CurrentMaxSize > PcdMaxSize:
                      pcdObject.MaxDatumSize = str(CurrentMaxSize)
              else:
                  Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
                                                  PcdCName,
                                                  TokenSpaceGuid,
                                                  self._PCD_TYPE_STRING_[Type],
                                                  '',
                                                  InitialValue,
                                                  '',
                                                  MaxDatumSize,
                                                  OrderedDict({SkuName : SkuInfo}),
                                                  False,
                                                  None,
                                                  IsDsc=True)
  
              if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
                  Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
                  Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
              Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = InitialValue
              Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Dummy4)
          for pcd in Pcds.values():
              pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
              pcd.DatumType = pcdDecObject.DatumType
              # Only fix the value while no value provided in DSC file.
              for sku in pcd.SkuInfoList.values():
                  if not sku.DefaultValue:
                      sku.DefaultValue = pcdDecObject.DefaultValue
              if TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON not in pcd.SkuInfoList:
                  SkuInfoObj = list(pcd.SkuInfoList.values())[0]
                  valuefromDec = pcdDecObject.DefaultValue
                  SkuInfo = SkuInfoClass(TAB_DEFAULT, '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
                  pcd.SkuInfoList[TAB_DEFAULT] = SkuInfo
              elif TAB_DEFAULT not in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
                  pcd.SkuInfoList[TAB_DEFAULT] = pcd.SkuInfoList[TAB_COMMON]
                  del pcd.SkuInfoList[TAB_COMMON]
              elif TAB_DEFAULT in pcd.SkuInfoList and TAB_COMMON in pcd.SkuInfoList:
                  del pcd.SkuInfoList[TAB_COMMON]
  
          #For the same one VOID* pcd, if the default value type of one SKU is "Unicode string",
          #the other SKUs are "OtherVOID*"(ASCII string or byte array),Then convert "Unicode string" to "byte array".
          for pcd in Pcds.values():
              PcdValueTypeSet = set()
              for sku in pcd.SkuInfoList.values():
                  PcdValueTypeSet.add("UnicodeString" if sku.DefaultValue.startswith(('L"',"L'")) else "OtherVOID*")
              if len(PcdValueTypeSet) > 1:
                  for sku in pcd.SkuInfoList.values():
                      sku.DefaultValue = StringToArray(sku.DefaultValue) if sku.DefaultValue.startswith(('L"',"L'")) else sku.DefaultValue
  
          list(map(self.FilterSkuSettings, Pcds.values()))
          return Pcds
  
      ## Add external modules
      #
      #   The external modules are mostly those listed in FDF file, which don't
      # need "build".
      #
      #   @param  FilePath    The path of module description file
      #
      def AddModule(self, FilePath):
          FilePath = NormPath(FilePath)
          if FilePath not in self.Modules:
              Module = ModuleBuildClassObject()
              Module.MetaFile = FilePath
              self.Modules.append(Module)
  
      @property
      def ToolChainFamily(self):
          self._ToolChainFamily = TAB_COMPILER_MSFT
          BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))
          if os.path.isfile(BuildConfigurationFile) == True:
              ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
              if ToolDefinitionFile == '':
                  ToolDefinitionFile = "tools_def.txt"
                  ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
              if os.path.isfile(ToolDefinitionFile) == True:
                  ToolDefinition = ToolDef.ToolsDefTxtDatabase
                  if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
                     or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
                     or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
                      self._ToolChainFamily = TAB_COMPILER_MSFT
                  else:
                      self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
          return self._ToolChainFamily
  
      ## Add external PCDs
      #
      #   The external PCDs are mostly those listed in FDF file to specify address
      # or offset information.
      #
      #   @param  Name    Name of the PCD
      #   @param  Guid    Token space guid of the PCD
      #   @param  Value   Value of the PCD
      #
      def AddPcd(self, Name, Guid, Value):
          if (Name, Guid) not in self.Pcds:
              self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
          self.Pcds[Name, Guid].DefaultValue = Value
  
      @property
      def DecPcds(self):
          if self._DecPcds is None:
              FdfInfList = []
              if GlobalData.gFdfParser:
                  FdfInfList = GlobalData.gFdfParser.Profile.InfList
              PkgSet = set()
              for Inf in FdfInfList:
                  ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
                  if ModuleFile in self._Modules:
                      continue
                  ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
                  PkgSet.update(ModuleData.Packages)
              self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain, PkgSet)
              self._GuidDict.update(GlobalData.gPlatformPcds)
          return self._DecPcds
  