public static async getLocation()

in ui/src/wizard/LocationListStep.ts [94:160]


    public static async getLocation<T extends ILocationWizardContextInternal>(wizardContext: T, provider?: string, supportsExtendedLocations?: boolean): Promise<types.AzExtLocation> {
        let location: types.AzExtLocation = nonNullProp(wizardContext, '_location');

        function warnAboutRelatedLocation(loc: types.AzExtLocation): void {
            ext.outputChannel.appendLog(localize('relatedLocWarning', 'WARNING: Provider "{0}" does not support location "{1}". Using "{2}" instead.', provider, location.displayName, loc.displayName));
        }

        if (location.type === 'EdgeZone') {
            if (supportsExtendedLocations) {
                // The `providerLocations` list doesn't seem to include EdgeZones, so there's no point in falling through to provider checks below
                return location;
            } else {
                const homeLocName = nonNullProp(nonNullProp(location, 'metadata'), 'homeLocation');
                const [allLocationsTask,] = this.getInternalVariables(wizardContext);
                const allLocations = await allLocationsTask;
                const homeLocation = nonNullValue(allLocations.find(l => LocationListStep.locationMatchesName(l, homeLocName)), 'homeLocation');
                wizardContext.telemetry.properties.relatedLocationSource = 'home';
                ext.outputChannel.appendLog(localize('homeLocationWarning', 'WARNING: Resource does not support extended location "{0}". Using "{1}" instead.', location.displayName, homeLocation.displayName));
                location = homeLocation;
            }
        }

        if (provider) {
            const [allLocationsTask, providerLocationsMap] = this.getInternalVariables(wizardContext);
            const providerLocations = await providerLocationsMap.get(provider.toLowerCase());
            if (providerLocations) {
                function isSupportedByProvider(loc: types.AzExtLocation): boolean {
                    return !!providerLocations?.find(name => LocationListStep.locationMatchesName(loc, name));
                }
                function useProviderName(loc: types.AzExtLocation): types.AzExtLocation {
                    // Some providers prefer their version of the name over the standard one, so we'll create a shallow clone using theirs
                    return { ...loc, name: nonNullValue(providerLocations?.find(name => LocationListStep.locationMatchesName(loc, name), 'providerName')) };
                }

                if (isSupportedByProvider(location)) {
                    return useProviderName(location);
                }

                const allLocations = await allLocationsTask;
                if (location.metadata?.pairedRegion) {
                    const pairedLocation: types.AzExtLocation | undefined = location.metadata?.pairedRegion
                        .map(paired => allLocations.find(l => paired.name && LocationListStep.locationMatchesName(l, paired.name)))
                        .find(pairedLoc => pairedLoc && isSupportedByProvider(pairedLoc));
                    if (pairedLocation) {
                        wizardContext.telemetry.properties.relatedLocationSource = 'paired';
                        warnAboutRelatedLocation(pairedLocation);
                        return useProviderName(pairedLocation);
                    }
                }

                if (location.name.toLowerCase().endsWith('stage')) {
                    const nonStageName = location.name.replace(/stage/i, '');
                    const nonStageLocation = allLocations.find(l => LocationListStep.locationMatchesName(l, nonStageName));
                    if (nonStageLocation && isSupportedByProvider(nonStageLocation)) {
                        wizardContext.telemetry.properties.relatedLocationSource = 'nonStage';
                        warnAboutRelatedLocation(nonStageLocation);
                        return useProviderName(nonStageLocation);
                    }
                }

                // Fall through to use the selected location just in case our "supported" list is wrong and since Azure should give them an error anyways
                wizardContext.telemetry.properties.locationProviderNotFound = provider;
            }
        }

        return location;
    }