// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Reflection; using EpicGames.Core; using EpicGames.UHT.Types; using EpicGames.UHT.Utils; namespace EpicGames.UHT.Tables { /// /// Delegate used to validate a specifier /// /// Containing type /// Containing meta data /// Key of the meta data entry /// Value of the meta data entry public delegate void UhtSpecifierValidatorDelegate(UhtType type, UhtMetaData metaData, UhtMetaDataKey key, StringView value); /// /// Defines a specifier validated created from the attribute /// public class UhtSpecifierValidator { /// /// Name of the validator /// public string Name { get; set; } /// /// Delegate for the validator /// public UhtSpecifierValidatorDelegate Delegate { get; set; } /// /// Construct a new instance /// /// Name of the validator /// Delegate of the validator public UhtSpecifierValidator(string name, UhtSpecifierValidatorDelegate specifierValidatorDelegate) { Name = name; Delegate = specifierValidatorDelegate; } } /// /// Attribute used to create a specifier validator /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] public sealed class UhtSpecifierValidatorAttribute : Attribute { /// /// Name of the validator. If not supplied "SpecifierValidator" will be removed from the end of the method name /// public string? Name { get; set; } /// /// Name of the table/scope for the validator /// public string? Extends { get; set; } } /// /// A table for validators for a given scope /// public class UhtSpecifierValidatorTable : UhtLookupTable { /// /// Construct a new specifier table /// public UhtSpecifierValidatorTable() : base(StringViewComparer.OrdinalIgnoreCase) { } /// /// Add the given value to the lookup table. It will throw an exception if it is a duplicate. /// /// Validator to add public UhtSpecifierValidatorTable Add(UhtSpecifierValidator specifier) { base.Add(specifier.Name, specifier); return this; } } /// /// Collection of specifier validators /// public class UhtSpecifierValidatorTables : UhtLookupTables { /// /// Construct the validator tables /// public UhtSpecifierValidatorTables() : base("specifier validators") { } /// /// Handle the attribute appearing on a method /// /// Type containing the method /// The method /// Attribute /// Thrown if the validator isn't properly defined public void OnSpecifierValidatorAttribute(Type type, MethodInfo methodInfo, UhtSpecifierValidatorAttribute specifierValidatorAttribute) { string name = UhtLookupTableBase.GetSuffixedName(type, methodInfo, specifierValidatorAttribute.Name, "SpecifierValidator"); if (String.IsNullOrEmpty(specifierValidatorAttribute.Extends)) { throw new UhtIceException($"The 'SpecifierValidator' attribute on the {type.Name}.{methodInfo.Name} method doesn't have a table specified."); } UhtSpecifierValidatorTable table = Get(specifierValidatorAttribute.Extends); table.Add(new UhtSpecifierValidator(name, (UhtSpecifierValidatorDelegate)Delegate.CreateDelegate(typeof(UhtSpecifierValidatorDelegate), methodInfo))); } } }