// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using EpicGames.Core; namespace UnrealBuildTool { /// /// Names of restricted folders. Note: The name of each entry is used to search for/create folders /// public partial struct RestrictedFolder { /// /// Unique Id for this folder /// private int Id; /// /// Mapping for unique ids /// private static UniqueStringRegistry StringRegistry = new UniqueStringRegistry(); /// /// Array of all restricted folder names /// private static string[]? Names; /// /// Array of all restricted folders /// private static RestrictedFolder[]? Values; /// /// Set of permitted references for each restricted folder. Determined via data-driven platform info. /// private static Dictionary? PermittedReferences; /// /// Constructor /// /// Id of the string private RestrictedFolder(int Id) { this.Id = Id; } /// /// Creates a restricted folder instance from a string /// /// Name of the folder /// New restricted folder instance private static RestrictedFolder FindOrAddByName(string Name) { return new RestrictedFolder(StringRegistry.FindOrAddByName(Name)); } /// /// Tests for equality between two restricted folder instances /// /// First instance /// Second instance /// True if the two instances are equal public static bool operator ==(RestrictedFolder A, RestrictedFolder B) { return A.Id == B.Id; } /// /// Tests for inequality between two restricted folder instances /// /// First instance /// Second instance /// True if the two instances are not equal public static bool operator !=(RestrictedFolder A, RestrictedFolder B) { return A.Id != B.Id; } /// /// Tests whether two restricted folder instances are equal /// /// The restricted folder to compare against /// True if the restricted folder is equal to the other instance public override bool Equals(object? Other) { return Other is RestrictedFolder folder && Id == folder.Id; } /// /// Gets a hash code for this object /// /// Hash code for the object public override int GetHashCode() { return Id; } /// /// Returns an array of folders which are allowed to be referenced from this restricted folder /// /// Collection of restricted folders public IEnumerable GetPermittedReferences() { RestrictedFolder[]? References; if (PermittedReferences != null && PermittedReferences.TryGetValue(this, out References)) { foreach (RestrictedFolder Reference in References) { yield return Reference; } } } /// /// Creates entries for all the confidential platforms. Should be called before returning any list of all folder values. /// private static void AddConfidentialPlatforms() { if (PermittedReferences == null) { Dictionary NewPermittedReferences = new Dictionary(); foreach (KeyValuePair Pair in DataDrivenPlatformInfo.GetAllPlatformInfos()) { if (Pair.Value.bIsConfidential) { RestrictedFolder Folder = FindOrAddByName(Pair.Key); if (Pair.Value.AdditionalRestrictedFolders != null && Pair.Value.AdditionalRestrictedFolders.Length > 0) { RestrictedFolder[] References = Array.ConvertAll(Pair.Value.AdditionalRestrictedFolders, x => FindOrAddByName(x)); NewPermittedReferences[Folder] = References; } } } PermittedReferences = NewPermittedReferences; } } /// /// Gets an array of all the restricted folder names /// /// public static string[] GetNames() { if (Names == null) { AddConfidentialPlatforms(); Names = StringRegistry.GetStringNames(); } return Names; } /// /// Ensures that we've added all the restricted folders, and return an array of them /// /// Array of restricted folder values public static RestrictedFolder[] GetValues() { if (Values == null) { AddConfidentialPlatforms(); Values = Array.ConvertAll(StringRegistry.GetStringIds(), x => new RestrictedFolder(x)); } return Values; } /// /// Return the string representation /// /// public override string ToString() { return StringRegistry.GetStringForId(Id); } } /// /// Values for RestrictedFolder /// public partial struct RestrictedFolder { /// /// Legacy. Should not be used any more. /// public static RestrictedFolder EpicInternal = FindOrAddByName("EpicInternal"); /// /// Can be used by UE but not required /// public static RestrictedFolder CarefullyRedist = FindOrAddByName("CarefullyRedist"); /// /// Epic Employees and Contractors as well as some explicitly permitted external groups /// public static RestrictedFolder LimitedAccess = FindOrAddByName("LimitedAccess"); /// /// Epic Employees and Contractors /// public static RestrictedFolder NotForLicensees = FindOrAddByName("NotForLicensees"); /// /// Epic Employees only /// public static RestrictedFolder NoRedist = FindOrAddByName("NoRedist"); } /// /// Utility functions for getting restricted folder /// public static class RestrictedFolders { /// /// Finds all the restricted folder names relative to a base directory /// /// The base directory to check against /// The file or directory to check /// Array of restricted folder names public static List FindRestrictedFolders(DirectoryReference BaseDir, DirectoryReference OtherDir) { List Folders = new List(); if (OtherDir.IsUnderDirectory(BaseDir)) { foreach (RestrictedFolder Value in RestrictedFolder.GetValues()) { string Name = Value.ToString(); if (OtherDir.ContainsName(Name, BaseDir.FullName.Length)) { Folders.Add(Value); } } } return Folders; } /// /// Finds all the permitted restricted folder references for a given path /// /// The base directory to check against /// The file or directory to check /// Array of restricted folder names public static List FindPermittedRestrictedFolderReferences(DirectoryReference BaseDir, DirectoryReference OtherDir) { List Folders = FindRestrictedFolders(BaseDir, OtherDir); for (int Idx = 0; Idx < Folders.Count; Idx++) { foreach (RestrictedFolder Folder in Folders[Idx].GetPermittedReferences()) { if (!Folders.Contains(Folder)) { Folders.Add(Folder); } } } return Folders; } } }