]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Java/Source/PcdTools/org/tianocore/pcd/action/PlatformPcdPreprocessAction.java
Restructuring for better separation of Tool packages.
[mirror_edk2.git] / Tools / Java / Source / PcdTools / org / tianocore / pcd / action / PlatformPcdPreprocessAction.java
diff --git a/Tools/Java/Source/PcdTools/org/tianocore/pcd/action/PlatformPcdPreprocessAction.java b/Tools/Java/Source/PcdTools/org/tianocore/pcd/action/PlatformPcdPreprocessAction.java
new file mode 100644 (file)
index 0000000..ee91f2a
--- /dev/null
@@ -0,0 +1,992 @@
+/** @file\r
+   PlatformPcdPreprocessAction class.\r
+\r
+   The abstract parent class PlatformPcdPreprocessAction, This class is to collect platform's\r
+   pcd build information from fpd file.\r
+   This class will be extended by building tools and wizard tools.\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+package org.tianocore.pcd.action;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.UUID;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;\r
+import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;\r
+import org.tianocore.pcd.entity.*;\r
+import org.tianocore.pcd.entity.Token;\r
+import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
+import org.tianocore.pcd.exception.PlatformPcdPreprocessException;\r
+\r
+/**\r
+   The abstract parent class PlatformPcdPreprocessAction, This class is to collect platform's\r
+   pcd build information from fpd file.\r
+   This class will be extended by building tools and wizard tools.\r
+\r
+**/\r
+public abstract class PlatformPcdPreprocessAction {\r
+    ///\r
+    /// PCD memory database\r
+    ///\r
+    private MemoryDatabaseManager pcdDbManager;\r
+\r
+    ///\r
+    /// Errors string when perform preprocess \r
+    /// \r
+    private String                errorString;\r
+\r
+    ///\r
+    /// the count of errors when perform preprocess\r
+    /// \r
+    private int                   errorCount;\r
+\r
+    /**\r
+       Default contructor function  \r
+    **/\r
+    public PlatformPcdPreprocessAction() {\r
+        pcdDbManager = null;\r
+        errorString  = null;\r
+       errorCount   = 0;\r
+    }\r
+\r
+    /**\r
+       Set parameter pcdDbManager\r
+\r
+       @param pcdDbManager\r
+    **/\r
+    public void setPcdDbManager(MemoryDatabaseManager pcdDbManager) {\r
+        this.pcdDbManager = pcdDbManager;\r
+    }\r
+\r
+    /**\r
+       Get parameter pcdDbManager\r
+\r
+       @return MemoryDatabaseManager\r
+    **/\r
+    public MemoryDatabaseManager getPcdDbManager() {\r
+        return pcdDbManager;\r
+    }\r
+\r
+    /**\r
+       Abstract function: retrieve module information from FPD file.\r
+\r
+       In building environement, this function will be implementated by FpdParserTask.\r
+\r
+       @return List<ModulePcdInfoFromFpd>        the component array.\r
+       @throws PlatformPcdPreprocessException    get all modules in <ModuleSA> in FPD file.\r
+\r
+    **/\r
+    public abstract List<ModulePcdInfoFromFpd> getComponentsFromFpd()\r
+                                               throws PlatformPcdPreprocessException;\r
+\r
+    /**\r
+       Abstract function to get GUID string from SPD file.\r
+\r
+       In building evnironment, this function will be implementated by GlobaData.\r
+\r
+       @param guidCName the CName of GUID\r
+\r
+       @return String        Guid information from SPD file.\r
+       @throws PlatformPcdPreprocessException\r
+                            Fail to get Guid information from SPD file.\r
+    **/\r
+    public abstract String getGuidInfoFromSpd(String guidCName) throws PlatformPcdPreprocessException;\r
+\r
+    /**\r
+       Abstract function: Verification the PCD data.\r
+\r
+       In different environment, such as building environment and wizard environment,\r
+       it has different implementation according to optimization.\r
+\r
+       @param cName         The token name\r
+       @param moduleName    The module who use this PCD token\r
+       @param datum         The PCD's datum\r
+       @param datumType     The PCD's datum type\r
+       @param maxDatumSize  The max size for PCD's Datum.\r
+\r
+       @return String       exception strings.\r
+\r
+    **/\r
+    public abstract String verifyDatum(String cName, String moduleName, String datum,\r
+                                       Token.DATUM_TYPE  datumType, int maxDatumSize);\r
+\r
+    /**\r
+       Abstract function: Get dynamic information for a token\r
+\r
+       @param token\r
+       @param moduleName\r
+\r
+       @return DynamicPcdBuildDefinitions.PcdBuildData\r
+    **/\r
+    public abstract DynamicPcdBuildDefinitions.PcdBuildData\r
+                                            getDynamicInfoFromFpd(Token     token,\r
+                                                                  String    moduleName)\r
+                                            throws PlatformPcdPreprocessException;\r
+\r
+    /**\r
+       Abstract function: Get all dynamic PCD information from FPD file.\r
+\r
+       @return List<DynamicPcdBuildDefinitions.PcdBuildData>    All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.\r
+       @throws PlatformPcdPreprocessBuildException              Failure to get dynamic information list.\r
+\r
+    **/\r
+    public abstract List<DynamicPcdBuildDefinitions.PcdBuildData>\r
+                                            getAllDynamicPcdInfoFromFpd()\r
+                                            throws PlatformPcdPreprocessException;\r
+\r
+    /**\r
+       Return the error string after preprocess \r
+\r
+       @return String error string\r
+    **/\r
+    public String getErrorString() {\r
+        return errorString;\r
+    }\r
+\r
+    public void putError(String error) {\r
+        if (errorString == null) {\r
+            errorString = "### ERROR[" + errorCount + "] ###\r\n" + error + "\r\n";\r
+        } else {\r
+            errorString += "### ERROR[" + errorCount + "] ###\r\n" + error + "\r\n";\r
+        }\r
+\r
+        errorCount++;\r
+    }\r
+\r
+    /**\r
+      Collect all PCD information from FPD file into PCD memory database.\r
+\r
+    **/\r
+    public void initPcdMemoryDbWithPlatformInfo()\r
+        throws PlatformPcdPreprocessException {\r
+        int                                 index;\r
+        int                                 pcdIndex;\r
+        List<PcdBuildDefinition.PcdData>    pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();\r
+        PcdBuildDefinition.PcdData          pcdBuildData;\r
+        Token                               token             = null;\r
+        List<ModulePcdInfoFromFpd>          modules;\r
+        String                              primaryKey;\r
+        String                              exceptionString;\r
+        UsageInstance                       usageInstance;\r
+        Token.PCD_TYPE                      pcdType           = Token.PCD_TYPE.UNKNOWN;\r
+        Token.DATUM_TYPE                    datumType         = Token.DATUM_TYPE.UNKNOWN;\r
+        long                                tokenNumber;\r
+        String                              moduleName;\r
+        String                              datum;\r
+        int                                 maxDatumSize;\r
+        String                              tokenSpaceStrRet;\r
+        ModulePcdInfoFromFpd                curModule;\r
+\r
+        //\r
+        // ----------------------------------------------\r
+        // 1), Get all <ModuleSA> from FPD file.\r
+        // ----------------------------------------------\r
+        //\r
+        modules = getComponentsFromFpd();\r
+\r
+        if (modules == null) {\r
+            throw new PlatformPcdPreprocessException(\r
+                "No modules found in the FPD file.\nPlease check whether there are elements in <FrameworkModules> in the FPD file!");\r
+        }\r
+\r
+        //\r
+        // -------------------------------------------------------------------\r
+        // 2), Loop all modules to process <PcdBuildDeclarations> for each module.\r
+        // -------------------------------------------------------------------\r
+        //\r
+        for (index = 0; index < modules.size(); index++) {\r
+            curModule = modules.get(index);\r
+\r
+            //\r
+           // It is legal for a module does not contains ANY pcd build definitions.\r
+           //\r
+           if (curModule.pcdBuildDefinition == null) {\r
+                continue;\r
+           }\r
+\r
+            pcdBuildDataArray = curModule.pcdBuildDefinition.getPcdDataList();\r
+            moduleName        = curModule.usageId.moduleName;\r
+\r
+            //\r
+            // ----------------------------------------------------------------------\r
+            // 2.1), Loop all Pcd entry for a module and add it into memory database.\r
+            // ----------------------------------------------------------------------\r
+            //\r
+            for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex++) {\r
+                pcdBuildData = pcdBuildDataArray.get(pcdIndex);\r
+\r
+                tokenSpaceStrRet = getGuidInfoFromSpd(pcdBuildData.getTokenSpaceGuidCName());\r
+\r
+                if (tokenSpaceStrRet == null) {\r
+                    putError("Failed to get Token Space Guid for token " + pcdBuildData.getCName() +\r
+                             " from any SPD file. You must have an <GuidDeclaration> for this Token Space Guid!");\r
+                    //\r
+                    // Do not break preprocess, continues to analysis.\r
+                    // All errors will be summary to be shown.\r
+                    // \r
+                    continue;\r
+                }\r
+\r
+                primaryKey   = Token.getPrimaryKeyString(pcdBuildData.getCName(), tokenSpaceStrRet);\r
+                pcdType      = Token.getPcdTypeFromString(pcdBuildData.getItemType().toString());\r
+                datumType    = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
+                tokenNumber  = Long.decode(pcdBuildData.getToken().toString());\r
+                if (pcdBuildData.getValue() != null) {\r
+                    datum = pcdBuildData.getValue().toString();\r
+                } else {\r
+                    datum = null;\r
+                }\r
+                maxDatumSize = pcdBuildData.getMaxDatumSize();\r
+\r
+                if ((pcdType    == Token.PCD_TYPE.FEATURE_FLAG) &&\r
+                    (datumType  != Token.DATUM_TYPE.BOOLEAN)){\r
+                    exceptionString = String.format("In FPD file, for PCD %s in module %s, the PCD type is FEATURE_FLAG but "+\r
+                                                    "datum type for this PCD entry is not BOOLEAN!",\r
+                                                    pcdBuildData.getCName(),\r
+                                                    moduleName);\r
+                    putError(exceptionString);\r
+                    //\r
+                    // Do not break preprocess, continues to analysis.\r
+                    // All errors will be summary to be shown.\r
+                    // \r
+                    continue;\r
+                }\r
+\r
+                //\r
+                // -------------------------------------------------------------------------------------------\r
+                // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule\r
+                // -------------------------------------------------------------------------------------------\r
+                //\r
+                if (!Token.isDynamic(pcdType)) {\r
+                     //\r
+                     // Value is required.\r
+                     //\r
+                     if (datum == null) {\r
+                         exceptionString = String.format("In the FPD file, there is no value for PCD entry %s in module %s!",\r
+                                                         pcdBuildData.getCName(),\r
+                                                         moduleName);\r
+                         putError(exceptionString);\r
+                         //\r
+                         // Do not break preprocess, continues to analysis.\r
+                         // All errors will be summary to be shown.\r
+                         // \r
+                         continue;\r
+                     }\r
+\r
+                     //\r
+                     // Check whether the datum size is matched datum type.\r
+                     //\r
+                     if ((exceptionString = verifyDatum(pcdBuildData.getCName(),\r
+                                                        moduleName,\r
+                                                        datum,\r
+                                                        datumType,\r
+                                                        maxDatumSize)) != null) {\r
+                         putError(exceptionString);\r
+                         //\r
+                         // Do not break preprocess, continues to analysis.\r
+                         // All errors will be summary to be shown.\r
+                         // \r
+                         continue;\r
+                     }\r
+                }\r
+\r
+                //\r
+                // ---------------------------------------------------------------------------------\r
+                // 2.1.2), Create token or update token information for current anaylized PCD data.\r
+                // ---------------------------------------------------------------------------------\r
+                //\r
+                if (pcdDbManager.isTokenInDatabase(primaryKey)) {\r
+                    //\r
+                    // If the token is already exist in database, do some necessary checking\r
+                    // and add a usage instance into this token in database\r
+                    //\r
+                    token = pcdDbManager.getTokenByKey(primaryKey);\r
+\r
+                    //\r
+                    // checking for DatumType, DatumType should be unique for one PCD used in different\r
+                    // modules.\r
+                    //\r
+                    if (token.datumType != datumType) {\r
+                        exceptionString = String.format("In the FPD file, the datum type of the PCD entry %s is %s, which is different from %s which was previously defined!",\r
+                                                        pcdBuildData.getCName(),\r
+                                                        pcdBuildData.getDatumType().toString(),\r
+                                                        Token.getStringOfdatumType(token.datumType));\r
+                        putError(exceptionString);\r
+                        //\r
+                        // Do not break preprocess, continues to analysis.\r
+                        // All errors will be summary to be shown.\r
+                        // \r
+                        continue;\r
+                    }\r
+\r
+                    //\r
+                    // Check token number is valid\r
+                    //\r
+                    if (tokenNumber != token.tokenNumber) {\r
+                        exceptionString = String.format("In the FPD file, the token number of PCD entry %s in module %s is different from the same PCD entry in other modules!",\r
+                                                        pcdBuildData.getCName(),\r
+                                                        moduleName);\r
+                        putError(exceptionString);\r
+                        //\r
+                        // Do not break preprocess, continues to analysis.\r
+                        // All errors will be summary to be shown.\r
+                        // \r
+                        continue;\r
+                    }\r
+\r
+                    //\r
+                    // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.\r
+                    //\r
+                    if (token.isDynamicPCD != Token.isDynamic(pcdType)) {\r
+                        exceptionString = String.format("In the FPD file, for PCD entry %s in module %s, you defined dynamic or non-dynamic PCD type which"+\r
+                                                        " is different from other module's definition.",\r
+                                                        token.cName,\r
+                                                        moduleName);\r
+                        putError(exceptionString);\r
+                        //\r
+                        // Do not break preprocess, continues to analysis.\r
+                        // All errors will be summary to be shown.\r
+                        // \r
+                        continue;\r
+                    }\r
+\r
+                    if (token.isDynamicPCD) {\r
+                        if ((maxDatumSize != 0) &&\r
+                            (maxDatumSize != token.datumSize)){\r
+                            exceptionString = String.format("In the FPD file, for dynamic PCD %s in module %s, the max datum size is %d which "+\r
+                                                            "is different than <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",\r
+                                                            token.cName,\r
+                                                            moduleName,\r
+                                                            maxDatumSize,\r
+                                                            token.datumSize);\r
+                            putError(exceptionString);\r
+                            //\r
+                            // Do not break preprocess, continues to analysis.\r
+                            // All errors will be summary to be shown.\r
+                            // \r
+                            continue;\r
+                        }\r
+                    }\r
+\r
+                } else {\r
+                    //\r
+                    // If the token is not in database, create a new token instance and add\r
+                    // a usage instance into this token in database.\r
+                    //\r
+                    tokenSpaceStrRet = getGuidInfoFromSpd(pcdBuildData.getTokenSpaceGuidCName());\r
+\r
+                    if (tokenSpaceStrRet == null) {\r
+                        putError("Failed to get the Token Space Guid for token" + token.cName +\r
+                                 " from any SPD file. You must have a <GuidDeclaration> for this Token Space Guid!");\r
+                        //\r
+                        // Do not break preprocess, continues to analysis.\r
+                        // All errors will be summary to be shown.\r
+                        // \r
+                        continue;\r
+                    }\r
+\r
+                    token = new Token(pcdBuildData.getCName(), tokenSpaceStrRet);\r
+\r
+                    token.datumType     = datumType;\r
+                    token.tokenNumber   = tokenNumber;\r
+                    token.isDynamicPCD  = Token.isDynamic(pcdType);\r
+                    token.datumSize     = maxDatumSize;\r
+\r
+                    if (token.isDynamicPCD) {\r
+                        //\r
+                        // For Dynamic and Dynamic Ex type, need find the dynamic information\r
+                        // in <DynamicPcdBuildDefinition> section in FPD file.\r
+                        //\r
+                        if (null == updateDynamicInformation(moduleName,\r
+                                                             token,\r
+                                                             datum,\r
+                                                             maxDatumSize)) {\r
+                            continue;\r
+                        }\r
+                    }\r
+\r
+                    pcdDbManager.addTokenToDatabase(primaryKey, token);\r
+                }\r
+\r
+                //\r
+                // -----------------------------------------------------------------------------------\r
+                // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.\r
+                // -----------------------------------------------------------------------------------\r
+                //\r
+                token.updateSupportPcdType(pcdType);\r
+\r
+                //\r
+                // ------------------------------------------------\r
+                // 2.1.4), Create an usage instance for this token.\r
+                // ------------------------------------------------\r
+                //\r
+                usageInstance = new UsageInstance(token,\r
+                                                  curModule.usageId,\r
+                                                  pcdType,\r
+                                                  datum,\r
+                                                  maxDatumSize);\r
+                if (!token.addUsageInstance(usageInstance)) {\r
+                    putError(String.format("PCD %s for module %s(%s) already exists in the database.\nPlease check all PCD build entries "+\r
+                                           "in the %s module's <ModuleSA> section to make sure there are no duplicated definitions in the FPD file!",\r
+                                           token.cName,\r
+                                           curModule.usageId.moduleGuid,\r
+                                           moduleName,\r
+                                           moduleName));\r
+                    continue;\r
+                }\r
+            }\r
+        }\r
+\r
+        //\r
+        // ------------------------------------------------\r
+        // 3), Add unreference dynamic_Ex pcd token into Pcd database.\r
+        // ------------------------------------------------\r
+        //\r
+        List<Token> tokenArray = getUnreferencedDynamicPcd();\r
+        if (tokenArray != null) {\r
+            for (index = 0; index < tokenArray.size(); index++) {\r
+                pcdDbManager.addTokenToDatabase(tokenArray.get(index).getPrimaryKeyString(),\r
+                                             tokenArray.get(index));\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+       Update dynamic information for PCD entry.\r
+\r
+       Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in\r
+       FPD file.\r
+\r
+       @param moduleName        The name of the module who use this PCD\r
+       @param token             The token instance\r
+       @param datum             The <datum> in module's PCD information\r
+       @param maxDatumSize      The <maxDatumSize> in module's PCD information\r
+\r
+       @return Token\r
+     */\r
+    private Token updateDynamicInformation(String   moduleName,\r
+                                           Token    token,\r
+                                           String   datum,\r
+                                           int      maxDatumSize)\r
+        throws PlatformPcdPreprocessException {\r
+        int                 index           = 0;\r
+        int                 offset;\r
+        String              exceptionString = null;\r
+        SkuInstance         skuInstance     = null;\r
+        String              temp;\r
+        boolean             hasSkuId0       = false;\r
+        long                tokenNumber     = 0;\r
+        String              hiiDefaultValue = null;\r
+        String              variableGuidString = null;\r
+\r
+        List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo>   skuInfoList = null;\r
+        DynamicPcdBuildDefinitions.PcdBuildData                 dynamicInfo = null;\r
+\r
+        dynamicInfo = getDynamicInfoFromFpd(token, moduleName);\r
+        if (dynamicInfo == null) {\r
+            exceptionString = String.format("In the FPD file, the Dynamic PCD %s is used by module %s.\n" +\r
+                                            "However, there is no dynamic information in the <DynamicPcdBuildDefinitions> " +\r
+                                            "section of the FPD file.  This section is required!",\r
+                                            token.cName,\r
+                                            moduleName);\r
+            putError(exceptionString);\r
+            return null;\r
+        }\r
+\r
+        token.datumSize = dynamicInfo.getMaxDatumSize();\r
+\r
+        exceptionString = verifyDatum(token.cName,\r
+                                      moduleName,\r
+                                      null,\r
+                                      token.datumType,\r
+                                      token.datumSize);\r
+        if (exceptionString != null) {\r
+            throw new PlatformPcdPreprocessException(exceptionString);\r
+        }\r
+\r
+        if ((maxDatumSize != 0) &&\r
+            (maxDatumSize != token.datumSize)) {\r
+            exceptionString = String.format("In the FPD file, for dynamic PCD %s, the datum size in module %s is %d, but "+\r
+                                            "the datum size in <DynamicPcdBuildDefinitions> is %d, they do not match!",\r
+                                            token.cName,\r
+                                            moduleName,\r
+                                            maxDatumSize,\r
+                                            dynamicInfo.getMaxDatumSize());\r
+            putError(exceptionString);\r
+            return null;\r
+        }\r
+        tokenNumber = Long.decode(dynamicInfo.getToken().toString());\r
+        if (tokenNumber != token.tokenNumber) {\r
+            exceptionString = String.format("In the FPD file, for dynamic PCD %s, the token number in module %s is 0x%x, but "+\r
+                                            "in the <DynamicPcdBuildDefinictions> section, the token number is 0x%x, they do not match!",\r
+                                            token.cName,\r
+                                            moduleName,\r
+                                            token.tokenNumber,\r
+                                            tokenNumber);\r
+            putError(exceptionString);\r
+            return null;\r
+        }\r
+\r
+        token.dynamicExTokenNumber = tokenNumber;\r
+\r
+        skuInfoList = dynamicInfo.getSkuInfoList();\r
+\r
+        //\r
+        // Loop all sku data\r
+        //\r
+        for (index = 0; index < skuInfoList.size(); index++) {\r
+            skuInstance = new SkuInstance();\r
+            //\r
+            // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
+            //\r
+            temp = skuInfoList.get(index).getSkuId().toString();\r
+            skuInstance.id = Integer.decode(temp);\r
+            if (skuInstance.id == 0) {\r
+                hasSkuId0 = true;\r
+            }\r
+            //\r
+            // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
+            //\r
+            if (skuInfoList.get(index).getValue() != null) {\r
+                skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
+                if ((exceptionString = verifyDatum(token.cName,\r
+                                                   null,\r
+                                                   skuInfoList.get(index).getValue().toString(),\r
+                                                   token.datumType,\r
+                                                   token.datumSize)) != null) {\r
+                    putError(exceptionString);\r
+                    return null;\r
+                }\r
+\r
+                token.skuData.add(skuInstance);\r
+\r
+                continue;\r
+            }\r
+\r
+            //\r
+            // Judge whether is HII group case.\r
+            //\r
+            if (skuInfoList.get(index).getVariableName() != null) {\r
+                exceptionString = null;\r
+                if (skuInfoList.get(index).getVariableGuid() == null) {\r
+                    exceptionString = String.format("In the FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
+                                                    "file, use of HII was defined, but there is no <VariableGuid> defined for SKU %d data!",\r
+                                                    token.cName,\r
+                                                    index);\r
+                    putError(exceptionString);\r
+                    return null;\r
+                }\r
+\r
+                if (skuInfoList.get(index).getVariableOffset() == null) {\r
+                    exceptionString = String.format("In the FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
+                                                    "file, use of HII was defined, but there is no <VariableOffset> defined for SKU %d data!",\r
+                                                    token.cName,\r
+                                                    index);\r
+                    putError(exceptionString);\r
+                    return null;\r
+                }\r
+\r
+                if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
+                    exceptionString = String.format("In the FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
+                                                    "file, use of HII was defined, but there is no <HiiDefaultValue> defined for SKU %d data!",\r
+                                                    token.cName,\r
+                                                    index);\r
+                    putError(exceptionString);\r
+                    return null;\r
+                }\r
+\r
+                if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
+                    hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
+                } else {\r
+                    hiiDefaultValue = null;\r
+                }\r
+\r
+                if ((exceptionString = verifyDatum(token.cName,\r
+                                                   null,\r
+                                                   hiiDefaultValue,\r
+                                                   token.datumType,\r
+                                                   token.datumSize)) != null) {\r
+                    throw new PlatformPcdPreprocessException(exceptionString);\r
+                }\r
+\r
+                offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
+                if (offset > 0xFFFF) {\r
+                    putError(String.format("In the FPD file, for dynamic PCD %s, the variable offset defined in SKU %d data "+\r
+                                           "exceeds 64K, which is not allowed!",\r
+                                           token.cName,\r
+                                           index));\r
+                    return null;\r
+                }\r
+\r
+                //\r
+                // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
+                //\r
+                variableGuidString = getGuidInfoFromSpd(skuInfoList.get(index).getVariableGuid().toString());\r
+                if (variableGuidString == null) {\r
+                    putError(String.format("In the FPD file, for dynamic PCD %s, the variable guid: %s cannot be found in any SPD file!",\r
+                                           token.cName,\r
+                                           skuInfoList.get(index).getVariableGuid().toString()));\r
+                    return null;\r
+                }\r
+                String variableStr = skuInfoList.get(index).getVariableName();\r
+                Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
+                Matcher matcher = pattern.matcher(variableStr);\r
+                List<String> varNameList = new ArrayList<String>();\r
+                while (matcher.find()){\r
+                    String str = variableStr.substring(matcher.start(),matcher.end());\r
+                    varNameList.add(str);\r
+                }\r
+\r
+                skuInstance.value.setHiiData(varNameList,\r
+                                             translateSchemaStringToUUID(variableGuidString),\r
+                                             skuInfoList.get(index).getVariableOffset(),\r
+                                             skuInfoList.get(index).getHiiDefaultValue().toString());\r
+                token.skuData.add(skuInstance);\r
+                continue;\r
+            }\r
+\r
+            if (skuInfoList.get(index).getVpdOffset() != null) {\r
+                skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
+                token.skuData.add(skuInstance);\r
+                continue;\r
+            }\r
+\r
+            exceptionString = String.format("In the FPD file, for dynamic PCD %s, the dynamic info must "+\r
+                                            "be one of: 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
+                                            token.cName);\r
+            putError(exceptionString);\r
+            return null;\r
+        }\r
+\r
+        if (!hasSkuId0) {\r
+            exceptionString = String.format("In the FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions>, there is "+\r
+                                            "no SKU ID = 0 data, which is required for every dynamic PCD",\r
+                                            token.cName);\r
+            putError(exceptionString);\r
+            return null;\r
+        }\r
+\r
+        return token;\r
+    }\r
+\r
+    /**\r
+       Get all dynamic PCD defined in <DynamicPcdBuildDefinitions> which unreferenced by\r
+       any <ModuleSA> in FPD file.\r
+\r
+       @return List<Token>  Return PCD token\r
+    **/\r
+    private List<Token> getUnreferencedDynamicPcd () throws PlatformPcdPreprocessException {\r
+        List<Token>                                   tokenArray                 = new ArrayList<Token>();\r
+        Token                                         token                      = null;\r
+        List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray   = null;\r
+        DynamicPcdBuildDefinitions.PcdBuildData       pcdBuildData               = null;\r
+        List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo>   skuInfoList      = null;\r
+        Token.PCD_TYPE                                pcdType;\r
+        SkuInstance                                   skuInstance                = null;\r
+        String  primaryKey = null;\r
+        boolean hasSkuId0  = false;\r
+        int     index, offset, index2;\r
+        String  temp;\r
+        String  exceptionString;\r
+        String  hiiDefaultValue;\r
+        String  tokenSpaceStrRet;\r
+        String  variableGuidString;\r
+\r
+        dynamicPcdBuildDataArray = getAllDynamicPcdInfoFromFpd();\r
+        if (dynamicPcdBuildDataArray == null) {\r
+            return null;\r
+        }\r
+\r
+        for (index2 = 0; index2 < dynamicPcdBuildDataArray.size(); index2++) {\r
+            pcdBuildData = dynamicPcdBuildDataArray.get(index2);\r
+            tokenSpaceStrRet = getGuidInfoFromSpd(pcdBuildData.getTokenSpaceGuidCName());\r
+\r
+            if (tokenSpaceStrRet == null) {\r
+                putError("Failed to get the Token Space Guid for token" + pcdBuildData.getCName());\r
+                continue;\r
+            }\r
+\r
+            primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),\r
+                                                   tokenSpaceStrRet);\r
+\r
+            if (pcdDbManager.isTokenInDatabase(primaryKey)) {\r
+                continue;\r
+            }\r
+\r
+            pcdType = Token.getPcdTypeFromString(pcdBuildData.getItemType().toString());\r
+            if (pcdType != Token.PCD_TYPE.DYNAMIC_EX) {\r
+                putError(String.format("In the FPD file, it not allowed to define DYNAMIC PCD %s that is not used by any module",\r
+                                       pcdBuildData.getCName()));\r
+                continue;\r
+            }\r
+\r
+            //\r
+            // Create new token for unreference dynamic PCD token\r
+            //\r
+            token           = new Token(pcdBuildData.getCName(), tokenSpaceStrRet);\r
+            token.datumSize = pcdBuildData.getMaxDatumSize();\r
+\r
+\r
+            token.datumType     = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
+            token.tokenNumber   = Long.decode(pcdBuildData.getToken().toString());\r
+            token.dynamicExTokenNumber = token.tokenNumber;\r
+            token.isDynamicPCD  = true;\r
+            token.updateSupportPcdType(pcdType);\r
+\r
+            exceptionString = verifyDatum(token.cName,\r
+                                          null,\r
+                                          null,\r
+                                          token.datumType,\r
+                                          token.datumSize);\r
+            if (exceptionString != null) {\r
+                putError(exceptionString);\r
+                continue;\r
+            }\r
+\r
+            skuInfoList = pcdBuildData.getSkuInfoList();\r
+\r
+            //\r
+            // Loop all sku data\r
+            //\r
+            for (index = 0; index < skuInfoList.size(); index++) {\r
+                skuInstance = new SkuInstance();\r
+                //\r
+                // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
+                //\r
+                temp = skuInfoList.get(index).getSkuId().toString();\r
+                skuInstance.id = Integer.decode(temp);\r
+                if (skuInstance.id == 0) {\r
+                    hasSkuId0 = true;\r
+                }\r
+                //\r
+                // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
+                //\r
+                if (skuInfoList.get(index).getValue() != null) {\r
+                    skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
+                    if ((exceptionString = verifyDatum(token.cName,\r
+                                                       null,\r
+                                                       skuInfoList.get(index).getValue().toString(),\r
+                                                       token.datumType,\r
+                                                       token.datumSize)) != null) {\r
+                        putError(exceptionString);\r
+                        continue;\r
+                    }\r
+\r
+                    token.skuData.add(skuInstance);\r
+\r
+                    continue;\r
+                }\r
+\r
+                //\r
+                // Judge whether is HII group case.\r
+                //\r
+                if (skuInfoList.get(index).getVariableName() != null) {\r
+                    exceptionString = null;\r
+                    if (skuInfoList.get(index).getVariableGuid() == null) {\r
+                        exceptionString = String.format("In the FPD file, for dynamic PCD %s in the <DynamicPcdBuildDefinitions> section of the FPD "+\r
+                                                        "file, use of HII is defined, but there is no <VariableGuid> defined for SKU %d data!",\r
+                                                        token.cName,\r
+                                                        index);\r
+                        putError(exceptionString);\r
+                        continue;\r
+                    }\r
+\r
+                    if (skuInfoList.get(index).getVariableOffset() == null) {\r
+                        exceptionString = String.format("In the FPD file, for dynamic PCD %s in the <DynamicPcdBuildDefinitions> section of the FPD "+\r
+                                                        "file, use of HII is defined, but there is no <VariableOffset> defined for SKU %d data!",\r
+                                                        token.cName,\r
+                                                        index);\r
+                        putError(exceptionString);\r
+                        continue;\r
+                    }\r
+\r
+                    if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
+                        exceptionString = String.format("In the FPD file, for dynamic PCD %s in the <DynamicPcdBuildDefinitions> section of the FPD "+\r
+                                                        "file, use of HII is defined, but there is no <HiiDefaultValue> defined for SKU %d data!",\r
+                                                        token.cName,\r
+                                                        index);\r
+                        putError(exceptionString);\r
+                        continue;\r
+                    }\r
+\r
+                    if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
+                        hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
+                    } else {\r
+                        hiiDefaultValue = null;\r
+                    }\r
+\r
+                    if ((exceptionString = verifyDatum(token.cName,\r
+                                                       null,\r
+                                                       hiiDefaultValue,\r
+                                                       token.datumType,\r
+                                                       token.datumSize)) != null) {\r
+                        putError(exceptionString);\r
+                        continue;\r
+                    }\r
+\r
+                    offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
+                    if (offset > 0xFFFF) {\r
+                        exceptionString = String.format("In the FPD file, for dynamic PCD %s, the variable offset defined in SKU %d data "+\r
+                                          "exceeds 64K, which is not allowed!",\r
+                                          token.cName,\r
+                                          index);\r
+                        putError(exceptionString);\r
+                        continue;\r
+                    }\r
+\r
+                    //\r
+                    // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
+                    //\r
+                    variableGuidString = getGuidInfoFromSpd(skuInfoList.get(index).getVariableGuid().toString());\r
+                    if (variableGuidString == null) {\r
+                        exceptionString = String.format("In the FPD file, for dynamic PCD %s, the variable guid %s cannot be found in any SPD file!",\r
+                                                        token.cName,\r
+                                                        skuInfoList.get(index).getVariableGuid().toString());\r
+                        putError(exceptionString);\r
+                        continue;\r
+                    }\r
+                    String variableStr = skuInfoList.get(index).getVariableName();\r
+                    Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
+                    Matcher matcher = pattern.matcher(variableStr);\r
+                    List<String> varNameList = new ArrayList<String>();\r
+                    while (matcher.find()){\r
+                        String str = variableStr.substring(matcher.start(),matcher.end());\r
+                        varNameList.add(str);\r
+                    }\r
+\r
+                    skuInstance.value.setHiiData(varNameList,\r
+                                                 translateSchemaStringToUUID(variableGuidString),\r
+                                                 skuInfoList.get(index).getVariableOffset(),\r
+                                                 skuInfoList.get(index).getHiiDefaultValue().toString());\r
+                    token.skuData.add(skuInstance);\r
+                    continue;\r
+                }\r
+\r
+                if (skuInfoList.get(index).getVpdOffset() != null) {\r
+                    skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
+                    token.skuData.add(skuInstance);\r
+                    continue;\r
+                }\r
+\r
+                exceptionString = String.format("In the FPD file, for dynamic PCD %s, the dynamic info must "+\r
+                                                "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
+                                                token.cName);\r
+                putError(exceptionString);\r
+            }\r
+\r
+            if (!hasSkuId0) {\r
+                exceptionString = String.format("In the FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions>, there is "+\r
+                                                "no SKU ID = 0 data, which is required for every dynamic PCD",\r
+                                                token.cName);\r
+                putError(exceptionString);\r
+                continue;\r
+            }\r
+\r
+            tokenArray.add(token);\r
+        }\r
+\r
+        return tokenArray;\r
+    }\r
+\r
+    /**\r
+       Translate the schema string to UUID instance.\r
+\r
+       In schema, the string of UUID is defined as following two types string:\r
+        1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(\r
+        )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?\r
+\r
+        2) GuidNamingConvention: pattern =\r
+        [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\r
+\r
+       This function will convert string and create uuid instance.\r
+\r
+       @param uuidString    UUID string in XML file\r
+\r
+       @return UUID         UUID instance\r
+    **/\r
+    private UUID translateSchemaStringToUUID(String uuidString)\r
+        throws PlatformPcdPreprocessException {\r
+        String      temp;\r
+        String[]    splitStringArray;\r
+        int         index;\r
+        int         chIndex;\r
+        int         chLen;\r
+\r
+        if (uuidString == null) {\r
+            return null;\r
+        }\r
+\r
+        if (uuidString.length() == 0) {\r
+            return null;\r
+        }\r
+\r
+        if (uuidString.equals("0") ||\r
+            uuidString.equalsIgnoreCase("0x0")) {\r
+            return new UUID(0, 0);\r
+        }\r
+\r
+        uuidString = uuidString.replaceAll("\\{", "");\r
+        uuidString = uuidString.replaceAll("\\}", "");\r
+\r
+        //\r
+        // If the UUID schema string is GuidArrayType type then need translate\r
+        // to GuidNamingConvention type at first.\r
+        //\r
+        if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {\r
+            splitStringArray = uuidString.split("," );\r
+            if (splitStringArray.length != 11) {\r
+                throw new PlatformPcdPreprocessException ("Wrong format for GUID string: " + uuidString);\r
+            }\r
+\r
+            //\r
+            // Remove blank space from these string and remove header string "0x"\r
+            //\r
+            for (index = 0; index < 11; index++) {\r
+                splitStringArray[index] = splitStringArray[index].trim();\r
+                splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());\r
+            }\r
+\r
+            //\r
+            // Add heading '0' to normalize the string length\r
+            //\r
+            for (index = 3; index < 11; index++) {\r
+                chLen = splitStringArray[index].length();\r
+                for (chIndex = 0; chIndex < 2 - chLen; chIndex++) {\r
+                    splitStringArray[index] = "0" + splitStringArray[index];\r
+                }\r
+            }\r
+\r
+            //\r
+            // construct the final GuidNamingConvention string\r
+            //\r
+            temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",\r
+                                 splitStringArray[0],\r
+                                 splitStringArray[1],\r
+                                 splitStringArray[2],\r
+                                 splitStringArray[3],\r
+                                 splitStringArray[4],\r
+                                 splitStringArray[5],\r
+                                 splitStringArray[6],\r
+                                 splitStringArray[7],\r
+                                 splitStringArray[8],\r
+                                 splitStringArray[9],\r
+                                 splitStringArray[10]);\r
+            uuidString = temp;\r
+        }\r
+\r
+        return UUID.fromString(uuidString);\r
+    }\r
+}\r
+\r