]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py
BaseTools: Add PackageDocumentTools into Scripts folder
[mirror_edk2.git] / BaseTools / Scripts / PackageDocumentTools / plugins / EdkPlugins / edk2 / model / baseobject.py
diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/edk2/model/baseobject.py
new file mode 100644 (file)
index 0000000..05fa252
--- /dev/null
@@ -0,0 +1,934 @@
+## @file\r
+#\r
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials are licensed and made available\r
+# under the terms and conditions of the BSD License which accompanies this\r
+# 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
+import plugins.EdkPlugins.basemodel.ini as ini\r
+import plugins.EdkPlugins.edk2.model.dsc as dsc\r
+import plugins.EdkPlugins.edk2.model.inf as inf\r
+import plugins.EdkPlugins.edk2.model.dec as dec\r
+import os\r
+from plugins.EdkPlugins.basemodel.message import *\r
+\r
+class SurfaceObject(object):\r
+    _objs = {}\r
+\r
+    def __new__(cls, *args, **kwargs):\r
+        """Maintain only a single instance of this object\r
+        @return: instance of this class\r
+\r
+        """\r
+        obj = object.__new__(cls, *args, **kwargs)\r
+        if not cls._objs.has_key("None"):\r
+            cls._objs["None"] = []\r
+        cls._objs["None"].append(obj)\r
+\r
+        return obj\r
+\r
+    def __init__(self, parent, workspace):\r
+        self._parent    = parent\r
+        self._fileObj   = None\r
+        self._workspace = workspace\r
+        self._isModify  = False\r
+        self._modifiedObjs = []\r
+\r
+    def __del__(self):\r
+        pass\r
+\r
+    def Destroy(self):\r
+        key = self.GetRelativeFilename()\r
+        self.GetFileObj().Destroy(self)\r
+        del self._fileObj\r
+        # dereference self from _objs arrary\r
+        assert self._objs.has_key(key), "when destory, object is not in obj list"\r
+        assert self in self._objs[key], "when destory, object is not in obj list"\r
+        self._objs[key].remove(self)\r
+        if len(self._objs[key]) == 0:\r
+            del self._objs[key]\r
+\r
+    def GetParent(self):\r
+        return self._parent\r
+\r
+    def GetWorkspace(self):\r
+        return self._workspace\r
+\r
+    def GetFileObjectClass(self):\r
+        return ini.BaseINIFile\r
+\r
+    def GetFilename(self):\r
+        return self.GetFileObj().GetFilename()\r
+\r
+    def GetFileObj(self):\r
+        return self._fileObj\r
+\r
+    def GetRelativeFilename(self):\r
+        fullPath = self.GetFilename()\r
+        return fullPath[len(self._workspace) + 1:]\r
+\r
+    def Load(self, relativePath):\r
+        # if has been loaded, directly return\r
+        if self._fileObj != None: return True\r
+\r
+        relativePath = os.path.normpath(relativePath)\r
+        fullPath = os.path.join(self._workspace, relativePath)\r
+        fullPath = os.path.normpath(fullPath)\r
+\r
+        if not os.path.exists(fullPath):\r
+            ErrorMsg("file does not exist!", fullPath)\r
+            return False\r
+\r
+        self._fileObj = self.GetFileObjectClass()(fullPath, self)\r
+\r
+        if not self._fileObj.Parse():\r
+            ErrorMsg("Fail to parse file!", fullPath)\r
+            return False\r
+\r
+        # remove self from None list to list with filename as key\r
+        cls = self.__class__\r
+        if self not in cls._objs["None"]:\r
+            ErrorMsg("Sufrace object does not be create into None list")\r
+        cls._objs["None"].remove(self)\r
+        if not cls._objs.has_key(relativePath):\r
+            cls._objs[relativePath] = []\r
+        cls._objs[relativePath].append(self)\r
+\r
+        return True\r
+\r
+    def Reload(self, force=False):\r
+        ret = True\r
+        # whether require must be update\r
+        if force:\r
+            ret = self.GetFileObj().Reload(True)\r
+        else:\r
+            if self.IsModified():\r
+                if self.GetFileObj().IsModified():\r
+                    ret = self.GetFileObj().Reload()\r
+        return ret\r
+\r
+    def Modify(self, modify=True, modifiedObj=None):\r
+        if modify:\r
+            #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))\r
+            if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:\r
+                return\r
+            self._isModify = modify\r
+            self.GetParent().Modify(modify, self)\r
+        else:\r
+            self._isModify = modify\r
+\r
+    def IsModified(self):\r
+        return self._isModify\r
+\r
+    def GetModifiedObjs(self):\r
+        return self._modifiedObjs\r
+\r
+    def FilterObjsByArch(self, objs, arch):\r
+        arr = []\r
+        for obj in objs:\r
+            if obj.GetArch().lower() == 'common':\r
+                arr.append(obj)\r
+                continue\r
+            if obj.GetArch().lower() == arch.lower():\r
+                arr.append(obj)\r
+                continue\r
+        return arr\r
+\r
+class Platform(SurfaceObject):\r
+    def __init__(self, parent, workspace):\r
+        SurfaceObject.__init__(self, parent, workspace)\r
+        self._modules    = []\r
+        self._packages   = []\r
+\r
+    def Destroy(self):\r
+        for module in self._modules:\r
+            module.Destroy()\r
+        del self._modules[:]\r
+\r
+        del self._packages[:]\r
+        SurfaceObject.Destroy(self)\r
+\r
+    def GetName(self):\r
+        return self.GetFileObj().GetDefine("PLATFORM_NAME")\r
+\r
+    def GetFileObjectClass(self):\r
+        return dsc.DSCFile\r
+\r
+    def GetModuleCount(self):\r
+        if self.GetFileObj() == None:\r
+            ErrorMsg("Fail to get module count because DSC file has not been load!")\r
+\r
+        return len(self.GetFileObj().GetComponents())\r
+\r
+    def GetSupportArchs(self):\r
+        return self.GetFileObj().GetDefine("SUPPORTED_ARCHITECTURES").strip().split('#')[0].split('|')\r
+\r
+    def LoadModules(self, precallback=None, postcallback=None):\r
+        for obj in self.GetFileObj().GetComponents():\r
+            mFilename = obj.GetFilename()\r
+            if precallback != None:\r
+                precallback(self, mFilename)\r
+            arch = obj.GetArch()\r
+            if arch.lower() == 'common':\r
+                archarr = self.GetSupportArchs()\r
+            else:\r
+                archarr = [arch]\r
+            for arch in archarr:\r
+                module = Module(self, self.GetWorkspace())\r
+                if module.Load(mFilename, arch, obj.GetOveridePcds(), obj.GetOverideLibs()):\r
+                    self._modules.append(module)\r
+                    if postcallback != None:\r
+                        postcallback(self, module)\r
+                else:\r
+                    del module\r
+                    ErrorMsg("Fail to load module %s" % mFilename)\r
+\r
+    def GetModules(self):\r
+        return self._modules\r
+\r
+    def GetLibraryPath(self, classname, arch, type):\r
+        objs = self.GetFileObj().GetSectionObjectsByName("libraryclasses")\r
+\r
+        for obj in objs:\r
+            if classname.lower() != obj.GetClass().lower():\r
+                continue\r
+            if obj.GetArch().lower() != 'common' and \\r
+               obj.GetArch().lower() != arch.lower():\r
+                continue\r
+\r
+            if obj.GetModuleType().lower() != 'common' and \\r
+               obj.GetModuleType().lower() != type.lower():\r
+                continue\r
+\r
+            return obj.GetInstance()\r
+\r
+        ErrorMsg("Fail to get library class %s [%s][%s] from platform %s" % (classname, arch, type, self.GetFilename()))\r
+        return None\r
+\r
+    def GetPackage(self, path):\r
+        package = self.GetParent().GetPackage(path)\r
+        if package not in self._packages:\r
+            self._packages.append(package)\r
+        return package\r
+\r
+    def GetPcdBuildObjs(self, name, arch=None):\r
+        arr = []\r
+        objs = self.GetFileObj().GetSectionObjectsByName('pcds')\r
+        for obj in objs:\r
+            if obj.GetPcdName().lower() == name.lower():\r
+                arr.append(obj)\r
+        if arch != None:\r
+            arr = self.FilterObjsByArch(arr, arch)\r
+        return arr\r
+\r
+    def Reload(self, callback=None):\r
+        # do not care force paramter for platform object\r
+        isFileChanged = self.GetFileObj().IsModified()\r
+        ret = SurfaceObject.Reload(self, False)\r
+        if not ret: return False\r
+        if isFileChanged:\r
+            # destroy all modules and reload them again\r
+            for obj in self._modules:\r
+                obj.Destroy()\r
+            del self._modules[:]\r
+            del self._packages[:]\r
+            self.LoadModules(callback)\r
+        else:\r
+            for obj in self._modules:\r
+                callback(self, obj.GetFilename())\r
+                obj.Reload()\r
+\r
+        self.Modify(False)\r
+        return True\r
+\r
+    def Modify(self, modify=True, modifiedObj=None):\r
+        if modify:\r
+            #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))\r
+            if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:\r
+                return\r
+            self._isModify = modify\r
+            self.GetParent().Modify(modify, self)\r
+        else:\r
+            if self.GetFileObj().IsModified():\r
+                return\r
+            for obj in self._modules:\r
+                if obj.IsModified():\r
+                    return\r
+\r
+            self._isModify = modify\r
+            self.GetParent().Modify(modify, self)\r
+\r
+    def GetModuleObject(self, relativePath, arch):\r
+        path = os.path.normpath(relativePath)\r
+        for obj in self._modules:\r
+            if obj.GetRelativeFilename() == path:\r
+                if arch.lower() == 'common':\r
+                    return obj\r
+                if obj.GetArch() == arch:\r
+                    return obj\r
+        return None\r
+\r
+    def GenerateFullReferenceDsc(self):\r
+        oldDsc = self.GetFileObj()\r
+        newDsc = dsc.DSCFile()\r
+        newDsc.CopySectionsByName(oldDsc, 'defines')\r
+        newDsc.CopySectionsByName(oldDsc, 'SkuIds')\r
+\r
+        #\r
+        # Dynamic common section should also be copied\r
+        #\r
+        newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicDefault')\r
+        newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicHii')\r
+        newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicVpd')\r
+        newDsc.CopySectionsByName(oldDsc, 'PcdsDynamicEx')\r
+\r
+        sects = oldDsc.GetSectionByName('Components')\r
+        for oldSect in sects:\r
+            newSect = newDsc.AddNewSection(oldSect.GetName())\r
+            for oldComObj in oldSect.GetObjects():\r
+                module = self.GetModuleObject(oldComObj.GetFilename(), oldSect.GetArch())\r
+                if module == None: continue\r
+\r
+                newComObj = dsc.DSCComponentObject(newSect)\r
+                newComObj.SetFilename(oldComObj.GetFilename())\r
+\r
+                # add all library instance for override section\r
+                libdict = module.GetLibraries()\r
+                for libclass in libdict.keys():\r
+                    if libdict[libclass] != None:\r
+                        newComObj.AddOverideLib(libclass, libdict[libclass].GetRelativeFilename().replace('\\', '/'))\r
+\r
+                # add all pcds for override section\r
+                pcddict = module.GetPcds()\r
+                for pcd in pcddict.values():\r
+                    buildPcd   = pcd.GetBuildObj()\r
+                    buildType  = buildPcd.GetPcdType()\r
+                    buildValue = None\r
+                    if buildType.lower() == 'pcdsdynamichii' or \\r
+                       buildType.lower() == 'pcdsdynamicvpd' or \\r
+                       buildType.lower() == 'pcdsdynamicdefault':\r
+                        buildType = 'PcdsDynamic'\r
+                    if buildType != 'PcdsDynamic':\r
+                        buildValue = buildPcd.GetPcdValue()\r
+                    newComObj.AddOveridePcd(buildPcd.GetPcdName(),\r
+                                            buildType,\r
+                                            buildValue)\r
+                newSect.AddObject(newComObj)\r
+        return newDsc\r
+\r
+class Module(SurfaceObject):\r
+    def __init__(self, parent, workspace):\r
+        SurfaceObject.__init__(self, parent, workspace)\r
+        self._arch        = 'common'\r
+        self._parent      = parent\r
+        self._overidePcds = {}\r
+        self._overideLibs = {}\r
+        self._libs        = {}\r
+        self._pcds        = {}\r
+        self._ppis        = []\r
+        self._protocols   = []\r
+        self._depexs      = []\r
+        self._guids       = []\r
+        self._packages    = []\r
+\r
+    def Destroy(self):\r
+        for lib in self._libs.values():\r
+            if lib != None:\r
+                lib.Destroy()\r
+        self._libs.clear()\r
+\r
+        for pcd in self._pcds.values():\r
+            pcd.Destroy()\r
+        self._pcds.clear()\r
+\r
+        for ppi in self._ppis:\r
+            ppi.DeRef(self)\r
+        del self._ppis[:]\r
+\r
+        for protocol in self._protocols:\r
+            if protocol != None:\r
+                protocol.DeRef(self)\r
+        del self._protocols[:]\r
+\r
+        for guid in self._guids:\r
+            if guid != None:\r
+                guid.DeRef(self)\r
+        del self._guids[:]\r
+\r
+        del self._packages[:]\r
+        del self._depexs[:]\r
+        SurfaceObject.Destroy(self)\r
+\r
+    def GetFileObjectClass(self):\r
+        return inf.INFFile\r
+\r
+    def GetLibraries(self):\r
+        return self._libs\r
+\r
+    def Load(self, filename, arch='common', overidePcds=None, overideLibs=None):\r
+        if not SurfaceObject.Load(self, filename):\r
+            return False\r
+\r
+        self._arch = arch\r
+        if overidePcds != None:\r
+            self._overideLibs = overideLibs\r
+        if overideLibs != None:\r
+            self._overidePcds = overidePcds\r
+\r
+        self._SearchLibraries()\r
+        self._SearchPackage()\r
+        self._SearchSurfaceItems()\r
+        return True\r
+\r
+    def GetArch(self):\r
+        return self._arch\r
+\r
+    def GetModuleName(self):\r
+        return self.GetFileObj().GetDefine("BASE_NAME")\r
+\r
+    def GetModuleType(self):\r
+        return self.GetFileObj().GetDefine("MODULE_TYPE")\r
+\r
+    def GetPlatform(self):\r
+        return self.GetParent()\r
+\r
+    def GetModuleObj(self):\r
+        return self\r
+\r
+    def GetPcds(self):\r
+        pcds = self._pcds.copy()\r
+        for lib in self._libs.values():\r
+            if lib == None: continue\r
+            for name in lib._pcds.keys():\r
+                pcds[name] = lib._pcds[name]\r
+        return pcds\r
+\r
+    def GetPpis(self):\r
+        ppis = []\r
+        ppis += self._ppis\r
+        for lib in self._libs.values():\r
+            if lib == None: continue\r
+            ppis += lib._ppis\r
+        return ppis\r
+\r
+    def GetProtocols(self):\r
+        pros = []\r
+        pros = self._protocols\r
+        for lib in self._libs.values():\r
+            if lib == None: continue\r
+            pros += lib._protocols\r
+        return pros\r
+\r
+    def GetGuids(self):\r
+        guids = []\r
+        guids += self._guids\r
+        for lib in self._libs.values():\r
+            if lib == None: continue\r
+            guids += lib._guids\r
+        return guids\r
+\r
+    def GetDepexs(self):\r
+        deps = []\r
+        deps += self._depexs\r
+        for lib in self._libs.values():\r
+            if lib == None: continue\r
+            deps += lib._depexs\r
+        return deps\r
+\r
+    def IsLibrary(self):\r
+        return self.GetFileObj().GetDefine("LIBRARY_CLASS") != None\r
+\r
+    def GetLibraryInstance(self, classname, arch, type):\r
+        if classname not in self._libs.keys():\r
+            # find in overide lib firstly\r
+            if classname in self._overideLibs.keys():\r
+                self._libs[classname] = Library(self, self.GetWorkspace())\r
+                self._libs[classname].Load(self._overideLibs[classname])\r
+                return self._libs[classname]\r
+\r
+            parent = self.GetParent()\r
+            if issubclass(parent.__class__, Platform):\r
+                path = parent.GetLibraryPath(classname, arch, type)\r
+                if path == None:\r
+                    ErrorMsg('Fail to get library instance for %s' % classname, self.GetFilename())\r
+                    return None\r
+                self._libs[classname] = Library(self, self.GetWorkspace())\r
+                if not self._libs[classname].Load(path, self.GetArch()):\r
+                    self._libs[classname] = None\r
+            else:\r
+                self._libs[classname] = parent.GetLibraryInstance(classname, arch, type)\r
+        return self._libs[classname]\r
+\r
+    def GetSourceObjs(self):\r
+        return self.GetFileObj().GetSectionObjectsByName('source')\r
+\r
+    def _SearchLibraries(self):\r
+        objs = self.GetFileObj().GetSectionObjectsByName('libraryclasses')\r
+        arch = self.GetArch()\r
+        type = self.GetModuleType()\r
+        for obj in objs:\r
+            if obj.GetArch().lower() != 'common' and \\r
+               obj.GetArch().lower() not in self.GetPlatform().GetSupportArchs():\r
+                continue\r
+            classname = obj.GetClass()\r
+            instance = self.GetLibraryInstance(classname, arch, type)\r
+            if not self.IsLibrary() and instance != None:\r
+                instance._isInherit = False\r
+\r
+            if classname not in self._libs.keys():\r
+                self._libs[classname] = instance\r
+\r
+    def _SearchSurfaceItems(self):\r
+        # get surface item from self's inf\r
+        pcds  = []\r
+        ppis  = []\r
+        pros  = []\r
+        deps  = []\r
+        guids = []\r
+        if self.GetFileObj() != None:\r
+            pcds = self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('pcd'),\r
+                                          self.GetArch())\r
+            for pcd in pcds:\r
+                if pcd.GetPcdName() not in self._pcds.keys():\r
+                    pcdItem = PcdItem(pcd.GetPcdName(), self, pcd)\r
+                    self._pcds[pcd.GetPcdName()] = ModulePcd(self,\r
+                                                             pcd.GetPcdName(),\r
+                                                             pcd,\r
+                                                             pcdItem)\r
+\r
+            ppis += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('ppis'),\r
+                                          self.GetArch())\r
+\r
+            for ppi in ppis:\r
+                item = PpiItem(ppi.GetName(), self, ppi)\r
+                if item not in self._ppis:\r
+                    self._ppis.append(item)\r
+\r
+            pros += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('protocols'),\r
+                                          self.GetArch())\r
+\r
+            for pro in pros:\r
+                item = ProtocolItem(pro.GetName(), self, pro)\r
+                if item not in self._protocols:\r
+                    self._protocols.append(item)\r
+\r
+            deps += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('depex'),\r
+                                          self.GetArch())\r
+            for dep in deps:\r
+                item = DepexItem(self, dep)\r
+                self._depexs.append(item)\r
+\r
+            guids += self.FilterObjsByArch(self.GetFileObj().GetSectionObjectsByName('guids'),\r
+                                          self.GetArch())\r
+            for guid in guids:\r
+                item = GuidItem(guid.GetName(), self, guid)\r
+                if item not in self._guids:\r
+                    self._guids.append(item)\r
+\r
+    def _SearchPackage(self):\r
+        objs = self.GetFileObj().GetSectionObjectsByName('packages')\r
+        for obj in objs:\r
+            package = self.GetPlatform().GetPackage(obj.GetPath())\r
+            if package != None:\r
+                self._packages.append(package)\r
+\r
+    def GetPackages(self):\r
+        return self._packages\r
+\r
+    def GetPcdObjects(self):\r
+        if self.GetFileObj() == None:\r
+            return []\r
+\r
+        return self.GetFileObj().GetSectionObjectsByName('pcd')\r
+\r
+    def GetLibraryClassHeaderFilePath(self):\r
+        lcname = self.GetFileObj().GetProduceLibraryClass()\r
+        if lcname == None: return None\r
+\r
+        pkgs = self.GetPackages()\r
+        for package in pkgs:\r
+            path = package.GetLibraryClassHeaderPathByName(lcname)\r
+            if path != None:\r
+                return os.path.realpath(os.path.join(package.GetFileObj().GetPackageRootPath(), path))\r
+        return None\r
+\r
+    def Reload(self, force=False, callback=None):\r
+        if callback != None:\r
+            callback(self, "Starting reload...")\r
+\r
+        ret = SurfaceObject.Reload(self, force)\r
+        if not ret: return False\r
+\r
+        if not force and not self.IsModified():\r
+            return True\r
+\r
+        for lib in self._libs.values():\r
+            if lib != None:\r
+                lib.Destroy()\r
+        self._libs.clear()\r
+\r
+        for pcd in self._pcds.values():\r
+            pcd.Destroy()\r
+        self._pcds.clear()\r
+\r
+        for ppi in self._ppis:\r
+            ppi.DeRef(self)\r
+        del self._ppis[:]\r
+\r
+        for protocol in self._protocols:\r
+            protocol.DeRef(self)\r
+        del self._protocols[:]\r
+\r
+        for guid in self._guids:\r
+            guid.DeRef(self)\r
+        del self._guids[:]\r
+\r
+        del self._packages[:]\r
+        del self._depexs[:]\r
+\r
+        if callback != None:\r
+            callback(self, "Searching libraries...")\r
+        self._SearchLibraries()\r
+        if callback != None:\r
+            callback(self, "Searching packages...")\r
+        self._SearchPackage()\r
+        if callback != None:\r
+            callback(self, "Searching surface items...")\r
+        self._SearchSurfaceItems()\r
+\r
+        self.Modify(False)\r
+        return True\r
+\r
+    def Modify(self, modify=True, modifiedObj=None):\r
+        if modify:\r
+            #LogMsg("%s is modified, modified object is %s" % (self.GetFilename(), modifiedObj))\r
+            if issubclass(modifiedObj.__class__, ini.BaseINIFile) and self._isModify:\r
+                return\r
+            self._isModify = modify\r
+            self.GetParent().Modify(modify, self)\r
+        else:\r
+            if self.GetFileObj().IsModified():\r
+                return\r
+\r
+            self._isModify = modify\r
+            self.GetParent().Modify(modify, self)\r
+\r
+class Library(Module):\r
+    def __init__(self, parent, workspace):\r
+        Module.__init__(self, parent, workspace)\r
+        self._isInherit = True\r
+\r
+    def IsInherit(self):\r
+        return self._isInherit\r
+\r
+    def GetModuleType(self):\r
+        return self.GetParent().GetModuleType()\r
+\r
+    def GetPlatform(self):\r
+        return self.GetParent().GetParent()\r
+\r
+    def GetModuleObj(self):\r
+        return self.GetParent()\r
+\r
+    def GetArch(self):\r
+        return self.GetParent().GetArch()\r
+\r
+    def Destroy(self):\r
+        self._libs.clear()\r
+        self._pcds.clear()\r
+        SurfaceObject.Destroy(self)\r
+\r
+class Package(SurfaceObject):\r
+    def __init__(self, parent, workspace):\r
+        SurfaceObject.__init__(self, parent, workspace)\r
+        self._pcds      = {}\r
+        self._guids     = {}\r
+        self._protocols = {}\r
+        self._ppis      = {}\r
+\r
+    def GetPcds(self):\r
+        return self._pcds\r
+\r
+    def GetPpis(self):\r
+        return self._ppis.values()\r
+\r
+    def GetProtocols(self):\r
+        return self._protocols.values()\r
+\r
+    def GetGuids(self):\r
+        return self._guids.values()\r
+\r
+    def Destroy(self):\r
+        for pcd in self._pcds.values():\r
+            if pcd != None:\r
+                pcd.Destroy()\r
+        for guid in self._guids.values():\r
+            if guid != None:\r
+                guid.Destroy()\r
+        for protocol in self._protocols.values():\r
+            if protocol != None:\r
+                protocol.Destroy()\r
+        for ppi in self._ppis.values():\r
+            if ppi != None:\r
+                ppi.Destroy()\r
+        self._pcds.clear()\r
+        self._guids.clear()\r
+        self._protocols.clear()\r
+        self._ppis.clear()\r
+        self._pcds.clear()\r
+        SurfaceObject.Destroy(self)\r
+\r
+    def Load(self, relativePath):\r
+        ret = SurfaceObject.Load(self, relativePath)\r
+        if not ret: return False\r
+        pcds = self.GetFileObj().GetSectionObjectsByName('pcds')\r
+        for pcd in pcds:\r
+            if pcd.GetPcdName() in self._pcds.keys():\r
+                if self._pcds[pcd.GetPcdName()] != None:\r
+                    self._pcds[pcd.GetPcdName()].AddDecObj(pcd)\r
+            else:\r
+                self._pcds[pcd.GetPcdName()] = PcdItem(pcd.GetPcdName(), self, pcd)\r
+\r
+        guids = self.GetFileObj().GetSectionObjectsByName('guids')\r
+        for guid in guids:\r
+            if guid.GetName() not in self._guids.keys():\r
+                self._guids[guid.GetName()] = GuidItem(guid.GetName(), self, guid)\r
+            else:\r
+                WarnMsg("Duplicate definition for %s" % guid.GetName())\r
+\r
+        ppis = self.GetFileObj().GetSectionObjectsByName('ppis')\r
+        for ppi in ppis:\r
+            if ppi.GetName() not in self._ppis.keys():\r
+                self._ppis[ppi.GetName()] = PpiItem(ppi.GetName(), self, ppi)\r
+            else:\r
+                WarnMsg("Duplicate definition for %s" % ppi.GetName())\r
+\r
+        protocols = self.GetFileObj().GetSectionObjectsByName('protocols')\r
+        for protocol in protocols:\r
+            if protocol.GetName() not in self._protocols.keys():\r
+                self._protocols[protocol.GetName()] = ProtocolItem(protocol.GetName(), self, protocol)\r
+            else:\r
+                WarnMsg("Duplicate definition for %s" % protocol.GetName())\r
+\r
+        return True\r
+\r
+    def GetFileObjectClass(self):\r
+        return dec.DECFile\r
+\r
+    def GetName(self):\r
+        return self.GetFileObj().GetDefine("PACKAGE_NAME")\r
+\r
+    def GetPcdDefineObjs(self, name=None):\r
+        arr = []\r
+        objs = self.GetFileObj().GetSectionObjectsByName('pcds')\r
+        if name == None: return objs\r
+\r
+        for obj in objs:\r
+            if obj.GetPcdName().lower() == name.lower():\r
+                arr.append(obj)\r
+        return arr\r
+\r
+    def GetLibraryClassObjs(self):\r
+        return self.GetFileObj().GetSectionObjectsByName('libraryclasses')\r
+\r
+    def Modify(self, modify=True, modifiedObj=None):\r
+        if modify:\r
+            self._isModify = modify\r
+            self.GetParent().Modify(modify, self)\r
+        else:\r
+            if self.GetFileObj().IsModified():\r
+                return\r
+\r
+            self._isModify = modify\r
+            self.GetParent().Modify(modify, self)\r
+\r
+    def GetLibraryClassHeaderPathByName(self, clsname):\r
+        objs = self.GetLibraryClassObjs()\r
+        for obj in objs:\r
+            if obj.GetClassName() == clsname:\r
+                return obj.GetHeaderFile()\r
+        return None\r
+\r
+class DepexItem(object):\r
+    def __init__(self, parent, infObj):\r
+        self._parent = parent\r
+        self._infObj = infObj\r
+\r
+    def GetDepexString(self):\r
+        return str(self._infObj)\r
+\r
+    def GetInfObject(self):\r
+        return self._infObj\r
+\r
+class ModulePcd(object):\r
+    _type_mapping = {'FeaturePcd': 'PcdsFeatureFlag',\r
+                     'FixedPcd': 'PcdsFixedAtBuild',\r
+                     'PatchPcd': 'PcdsPatchableInModule'}\r
+\r
+    def __init__(self, parent, name, infObj, pcdItem):\r
+        assert issubclass(parent.__class__, Module), "Module's PCD's parent must be module!"\r
+        assert pcdItem != None, 'Pcd %s does not in some package!' % name\r
+\r
+        self._name          = name\r
+        self._parent        = parent\r
+        self._pcdItem       = pcdItem\r
+        self._infObj        = infObj\r
+\r
+    def GetName(self):\r
+        return self._name\r
+\r
+    def GetParent(self):\r
+        return self._name\r
+\r
+    def GetArch(self):\r
+        return self._parent.GetArch()\r
+\r
+    def Destroy(self):\r
+        self._pcdItem.DeRef(self._parent)\r
+        self._infObj = None\r
+\r
+    def GetBuildObj(self):\r
+        platformInfos = self._parent.GetPlatform().GetPcdBuildObjs(self._name, self.GetArch())\r
+        modulePcdType = self._infObj.GetPcdType()\r
+\r
+        # if platform do not gives pcd's value, get default value from package\r
+        if len(platformInfos) == 0:\r
+            if modulePcdType.lower() == 'pcd':\r
+                return self._pcdItem.GetDecObject()\r
+            else:\r
+                for obj in self._pcdItem.GetDecObjects():\r
+                    if modulePcdType not in self._type_mapping.keys():\r
+                        ErrorMsg("Invalid PCD type %s" % modulePcdType)\r
+                        return None\r
+\r
+                    if self._type_mapping[modulePcdType] == obj.GetPcdType():\r
+                        return obj\r
+                ErrorMsg ('Module PCD type %s does not in valied range [%s] in package!' % \\r
+                          (modulePcdType))\r
+        else:\r
+            if modulePcdType.lower() == 'pcd':\r
+                if len(platformInfos) > 1:\r
+                    WarnMsg("Find more than one value for PCD %s in platform %s" % \\r
+                            (self._name, self._parent.GetPlatform().GetFilename()))\r
+                return platformInfos[0]\r
+            else:\r
+                for obj in platformInfos:\r
+                    if modulePcdType not in self._type_mapping.keys():\r
+                        ErrorMsg("Invalid PCD type %s" % modulePcdType)\r
+                        return None\r
+\r
+                    if self._type_mapping[modulePcdType] == obj.GetPcdType():\r
+                        return obj\r
+\r
+                ErrorMsg('Can not find value for pcd %s in pcd type %s' % \\r
+                         (self._name, modulePcdType))\r
+        return None\r
+\r
+\r
+class SurfaceItem(object):\r
+    _objs = {}\r
+\r
+    def __new__(cls, *args, **kwargs):\r
+        """Maintain only a single instance of this object\r
+        @return: instance of this class\r
+\r
+        """\r
+        name    = args[0]\r
+        parent  = args[1]\r
+        fileObj = args[2]\r
+        if issubclass(parent.__class__, Package):\r
+            if name in cls._objs.keys():\r
+                ErrorMsg("%s item is duplicated defined in packages: %s and %s" %\r
+                         (name, parent.GetFilename(), cls._objs[name].GetParent().GetFilename()))\r
+                return None\r
+            obj = object.__new__(cls, *args, **kwargs)\r
+            cls._objs[name] = obj\r
+            return obj\r
+        elif issubclass(parent.__class__, Module):\r
+            if name not in cls._objs.keys():\r
+                ErrorMsg("%s item does not defined in any package! It is used by module %s" % \\r
+                         (name, parent.GetFilename()))\r
+                return None\r
+            return cls._objs[name]\r
+\r
+        return None\r
+\r
+\r
+    def __init__(self, name, parent, fileObj):\r
+        if issubclass(parent.__class__, Package):\r
+            self._name    = name\r
+            self._parent  = parent\r
+            self._decObj  = [fileObj]\r
+            self._refMods = {}\r
+        else:\r
+            self.RefModule(parent, fileObj)\r
+\r
+    @classmethod\r
+    def GetObjectDict(cls):\r
+        return cls._objs\r
+\r
+    def GetParent(self):\r
+        return self._parent\r
+\r
+    def GetReference(self):\r
+        return self._refMods\r
+\r
+    def RefModule(self, mObj, infObj):\r
+        if mObj in self._refMods.keys():\r
+            return\r
+        self._refMods[mObj] = infObj\r
+\r
+    def DeRef(self, mObj):\r
+        if mObj not in self._refMods.keys():\r
+            WarnMsg("%s is not referenced by module %s" % (self._name, mObj.GetFilename()))\r
+            return\r
+        del self._refMods[mObj]\r
+\r
+    def Destroy(self):\r
+        self._refMods.clear()\r
+        cls = self.__class__\r
+        del cls._objs[self._name]\r
+\r
+    def GetName(self):\r
+        return self._name\r
+\r
+    def GetDecObject(self):\r
+        return self._decObj[0]\r
+\r
+    def GetDecObjects(self):\r
+        return self._decObj\r
+\r
+class PcdItem(SurfaceItem):\r
+    def AddDecObj(self, fileObj):\r
+        for decObj in self._decObj:\r
+            if decObj.GetFilename() != fileObj.GetFilename():\r
+                ErrorMsg("Pcd %s defined in more than one packages : %s and %s" % \\r
+                         (self._name, decObj.GetFilename(), fileObj.GetFilename()))\r
+                return\r
+            if decObj.GetPcdType() == fileObj.GetPcdType() and \\r
+               decObj.GetArch().lower() == fileObj.GetArch():\r
+                ErrorMsg("Pcd %s is duplicated defined in pcd type %s in package %s" % \\r
+                         (self._name, decObj.GetPcdType(), decObj.GetFilename()))\r
+                return\r
+        self._decObj.append(fileObj)\r
+\r
+    def GetValidPcdType(self):\r
+        types = []\r
+        for obj in self._decObj:\r
+            if obj.GetPcdType() not in types:\r
+                types += obj.GetPcdType()\r
+        return types\r
+\r
+class GuidItem(SurfaceItem):\r
+    pass\r
+\r
+class PpiItem(SurfaceItem):\r
+    pass\r
+\r
+class ProtocolItem(SurfaceItem):\r
+    pass\r