def __init__(self, log: Log, xmlElement: ET.Element,
                 filename: str) -> None:
        super().__init__(log, xmlElement)
        #raise Exception("ExtendedProject not implemented");
        self.Parent = self._ReadAttrib(xmlElement, 'Parent')  # type: str
        self.ParentRoot = self._ReadAttrib(xmlElement,
                                           'ParentRoot')  # type: str
        configFilename = IOUtil.GetFileName(filename)  # type: str
        self.ParentConfigFilename = IOUtil.Join(self.ParentRoot,
                                                configFilename)  # type: str

        variableProcessor = VariableProcessor(log)
        self.AbsoluteParentConfigFilename = variableProcessor.ResolveAbsolutePathWithLeadingEnvironmentVariablePath(
            self.ParentConfigFilename)
        self.XmlPackageConfiguration = _LoadPackageConfigurations(
            log, xmlElement,
            filename)  # type: List[XmlConfigPackageConfiguration]
        self.XmlRootDirectories = _LoadAddRootDirectory(
            log, xmlElement,
            filename)  # type: List[XmlConfigFileAddRootDirectory]
        self.XmlNewProjectTemplatesRootDirectories = LoadUtil.LoadAddNewProjectTemplatesRootDirectory(
            log, xmlElement, filename)
        self.XmlBuildDocConfiguration = _LoadBuildDocConfiguration(
            log, xmlElement, filename)  # type: List[XmlBuildDocConfiguration]
        self.XmlClangFormatConfiguration = _LoadClangFormatConfiguration(
            log, xmlElement,
            filename)  # type: List[XmlClangFormatConfiguration]
        self.XmlClangTidyConfiguration = _LoadClangTidyConfiguration(
            log, xmlElement, filename)  # type: List[XmlClangTidyConfiguration]
        self.XmlCompilerConfiguration = _LoadCompilerConfiguration(
            log, xmlElement,
            filename)  # type: List[XmlConfigCompilerConfiguration]
        self.XmlExperimental = _TryLoadExperimental(
            log, xmlElement, filename)  # type: Optional[XmlExperimental]
def _LoadPackageConfigurations(log: Log, projectElem: ET.Element, filename: str) -> List[XmlConfigPackageConfiguration]:
    xmlPackageConfigurations = LoadUtil.XMLLoadPackageConfiguration(log, projectElem, filename)
    for entry in xmlPackageConfigurations:
        # if no locations has been supplied then we assume the root folder of the project file
        #if entry.Name == 'default' and len(entry.Locations) <= 0:
        if len(entry.Locations) <= 0:
            xmlConfigPackageLocation = XmlConfigPackageLocation(log, FakeXmlElementFactory.CreateWithName("PackageLocation", MagicStrings.ProjectRoot))
            entry.Locations = [xmlConfigPackageLocation]
    return xmlPackageConfigurations
    def __init__(self, log: Log, filename: str, projectRootConfig: XmlProjectRootConfigFile) -> None:
        if projectRootConfig is None:
            raise Exception("projectRootConfig can not be None")
        if not os.path.isfile(filename):
            raise FileNotFoundException("Could not locate config file %s", filename)

        tree = ET.parse(filename)
        elem = tree.getroot()
        if elem.tag != 'FslBuildGenConfig':
            raise XmlInvalidRootElement("The file did not contain the expected root tag 'FslBuildGenConfig'")

        super().__init__(log, elem)
        currentVersion = '2'
        fileVersion = self._ReadAttrib(elem, 'Version')
        if fileVersion != currentVersion:
            raise XmlException("The file was not of the expected version {0}".format(currentVersion))

        # In V2 we do not support local AddRootDirectory elements, we use the ones in ProjectRootConfig
        rootDirs = projectRootConfig.XmlRootDirectories
        if len(rootDirs) < 1:
            raise XmlException("The file did not contain at least one AddRootDirectory element")

        templateImportDirectory = self.__LoadAddTemplateImportDirectory(elem)

        self.__CheckForLegacyElements(elem, filename)

        # In V2 we do not support local PackageConfiguration elements, we use the ones in ProjectRootConfig
        xmlPackageConfigurations = projectRootConfig.XmlPackageConfiguration  # type: List[XmlConfigPackageConfiguration]
        if len(xmlPackageConfigurations) < 1:
            if projectRootConfig.SourceFileName is None:
                raise XmlException("The file '{0}' did not contain at least one PackageConfiguration element".format(filename))
            else:
                raise XmlException("The file '{0}' and {1} did not contain at least one PackageConfiguration element".format(filename, projectRootConfig.SourceFileName))

        newProjectTemplatesRootDirectories = LoadUtil.LoadAddNewProjectTemplatesRootDirectory(log, elem, filename)
        newProjectTemplatesRootDirectories = self.__MergeNewProjectTemplatesRootDirectories(newProjectTemplatesRootDirectories, projectRootConfig.XmlNewProjectTemplatesRootDirectories)

        xmlContentBuilderConfiguration = self.__LoadContentBuilderConfiguration(elem)

        xmlConfigFileTemplateFolder = self.__LoadTemplateFolder(elem)

        self.Version = int(fileVersion)  # type: int
        self.RootDirectories = rootDirs  # type: List[XmlConfigFileAddRootDirectory]
        self.TemplateImportDirectories = templateImportDirectory  # type: List[XmlConfigFileAddTemplateImportDirectory]
        self.PackageConfiguration = self.__ResolvePackageConfiguration(xmlPackageConfigurations)  # type: Dict[str, XmlConfigPackageConfiguration]
        self.NewProjectTemplateRootDirectories = newProjectTemplatesRootDirectories  # type: List[XmlConfigFileAddNewProjectTemplatesRootDirectory]
        self.TemplateFolder = xmlConfigFileTemplateFolder  # type: XmlConfigFileTemplateFolder
        self.GenFileName = self.__LoadGenFileName(elem)  # type: XmlConfigFileGenFile
        self.ContentBuilderConfiguration = xmlContentBuilderConfiguration  # type: XmlConfigContentBuilderConfiguration
        self.BuildDocConfiguration = projectRootConfig.XmlBuildDocConfiguration # type: List[XmlBuildDocConfiguration]
        self.ClangFormatConfiguration = projectRootConfig.XmlClangFormatConfiguration  # type: List[XmlClangFormatConfiguration]
        self.ClangTidyConfiguration = projectRootConfig.XmlClangTidyConfiguration  # type: List[XmlClangTidyConfiguration]
        self.CMakeConfiguration = projectRootConfig.XmlCMakeConfiguration  # type: List[XmlCMakeConfiguration]
        self.CompilerConfiguration = projectRootConfig.XmlCompilerConfiguration  # type: List[XmlConfigCompilerConfiguration]
        self.Experimental = self.__ResolveExperimental(projectRootConfig.XmlExperimental)  # type: Optional[XmlExperimental]
    def __LoadFromXml(self,
                      log: Log,
                      xmlElement: ET.Element,
                      filename: str,
                      canExtend: bool = True) -> None:
        self.Version = '1'  # type: str
        self.RootDirectory = LocalInvalidValues.INVALID_FILE_NAME  # type: str
        self.DefaultPackageLanguage = PackageLanguage.CPP  # type: int
        self.DefaultCompany = LocalInvalidValues.INVALID_COMPANY_NAME  # type: str
        self.ToolConfigFile = LocalInvalidValues.INVALID_FILE_NAME  # type: str
        self.RequirePackageCreationYear = False
        self.XmlExperimental = None  # type: Optional[XmlExperimental]
        self.XmlPackageConfiguration = [
        ]  # type: List[XmlConfigPackageConfiguration]
        self.XmlRootDirectories = [
        ]  #  type: List[XmlConfigFileAddRootDirectory]
        self.XmlNewProjectTemplatesRootDirectories = [
        ]  # type: List[XmlConfigFileAddNewProjectTemplatesRootDirectory]
        self.XmlCompilerConfiguration = [
        ]  # type: List[XmlConfigCompilerConfiguration]
        self.SourceFileName = LocalInvalidValues.INVALID_FILE_NAME  # type: str
        self.DefaultTemplate = MagicStrings.VSDefaultCPPTemplate  # type: str
        self.ExtendedProject = []  # type: List[XmlExtendedProject]
        if xmlElement is not None:
            extendedElement = xmlElement.find(
                "ExtendedProject") if canExtend else None
            if extendedElement is None:
                rootDirectory = IOUtil.GetDirectoryName(filename)
                variableEnvironment = VariableEnvironment(self.Log)
                variableEnvironment.Set("PROJECT_ROOT", rootDirectory)
                variableProcessor = VariableProcessor(self.Log,
                                                      variableEnvironment)
                self.Version = self._ReadAttrib(xmlElement, 'Version')
                self.RootDirectory = rootDirectory
                projectElem = XmlBase._GetElement(
                    self, xmlElement, "Project")  # type: ET.Element
                toolConfigFilePath = self._ReadAttrib(
                    projectElem, 'ToolConfigFile')  # type: str
                self.DefaultPackageLanguage = self.__GetDefaultPackageLanguage(
                    projectElem)
                self.DefaultCompany = self._ReadAttrib(projectElem,
                                                       'DefaultCompany')
                # if this is set to true each package is required to contian a 'CreationYear=""' attribute
                self.RequirePackageCreationYear = self._ReadBoolAttrib(
                    projectElem, 'RequirePackageCreationYear', False)
                self.ToolConfigFile = variableProcessor.ResolvePathToAbsolute(
                    toolConfigFilePath, self.XMLElement)
                self.XmlPackageConfiguration = _LoadPackageConfigurations(
                    log, projectElem, filename)
                self.XmlRootDirectories = _LoadAddRootDirectory(
                    log, projectElem, filename)
                self.XmlNewProjectTemplatesRootDirectories = LoadUtil.LoadAddNewProjectTemplatesRootDirectory(
                    log, projectElem, filename)
                self.XmlBuildDocConfiguration = _LoadBuildDocConfiguration(
                    log, projectElem, filename)
                self.XmlClangFormatConfiguration = _LoadClangFormatConfiguration(
                    log, projectElem, filename)
                self.XmlClangTidyConfiguration = _LoadClangTidyConfiguration(
                    log, projectElem, filename)
                self.XmlCompilerConfiguration = _LoadCompilerConfiguration(
                    log, projectElem, filename)
                self.XmlExperimental = _TryLoadExperimental(
                    log, projectElem, filename)
                self.SourceFileName = filename
                self.DefaultTemplate = self._ReadAttrib(
                    projectElem, 'DefaultTemplate',
                    MagicStrings.VSDefaultCPPTemplate)
            else:
                # Do something with the extended element
                extendedProject = XmlExtendedProject(log, extendedElement,
                                                     filename)
                parentFileName = extendedProject.AbsoluteParentConfigFilename
                parentElem = self.__LoadXml(log, parentFileName)
                self.__LoadFromXml(log, parentElem, parentFileName,
                                   True)  # True to allow multiple extensions
                self.ExtendedProject.append(extendedProject)
                self.__ApplyExtended(self.XmlPackageConfiguration,
                                     extendedProject.XmlPackageConfiguration,
                                     True)
                self.__ApplyExtended(self.XmlRootDirectories,
                                     extendedProject.XmlRootDirectories, False)
                self.__ApplyExtended(
                    self.XmlNewProjectTemplatesRootDirectories,
                    extendedProject.XmlNewProjectTemplatesRootDirectories,
                    False)
                self.__ApplyExtended(self.XmlBuildDocConfiguration,
                                     extendedProject.XmlBuildDocConfiguration,
                                     False)
                self.__ApplyExtended(
                    self.XmlClangFormatConfiguration,
                    extendedProject.XmlClangFormatConfiguration, False)
                self.__ApplyExtended(self.XmlCompilerConfiguration,
                                     extendedProject.XmlCompilerConfiguration,
                                     False)
                self.__ApplyExtendedExperimental(
                    self.XmlExperimental, extendedProject.XmlExperimental)

        if self.RootDirectory == LocalInvalidValues.INVALID_FILE_NAME:
            raise Exception("RootDirectory not configured")
        if self.DefaultCompany == LocalInvalidValues.INVALID_COMPANY_NAME:
            raise Exception("Default company not configured")
        if self.ToolConfigFile == LocalInvalidValues.INVALID_FILE_NAME:
            raise Exception("ToolConfigFile not configured")
        if self.SourceFileName == LocalInvalidValues.INVALID_FILE_NAME:
            raise Exception("SourceFileName not configured")
        if len(self.XmlBuildDocConfiguration) > 1:
            raise Exception(
                "There can only be one BuildDocConfiguration entry")
        if len(self.XmlClangFormatConfiguration) > 1:
            raise Exception(
                "There can only be one ClangFormatConfiguration entry")
        if len(self.XmlClangTidyConfiguration) > 1:
            raise Exception(
                "There can only be one ClangTidyConfiguration entry")