private static IComponentFactory GetComponentJson(IExceptionContext ectx, Type signatureType, string name, JObject settings, ModuleCatalog catalog) { Contracts.AssertValue(ectx); ectx.AssertValue(signatureType); ectx.AssertNonEmpty(name); ectx.AssertValueOrNull(settings); ectx.AssertValue(catalog); if (!catalog.TryGetComponentKind(signatureType, out string kind)) { throw ectx.Except($"Component type '{signatureType}' is not a valid signature type."); } if (!catalog.TryFindComponent(kind, name, out ModuleCatalog.ComponentInfo component)) { var available = catalog.GetAllComponents(kind).Select(x => $"'{x.Name}'"); throw ectx.Except($"Component '{name}' of kind '{kind}' is not found. Available components are: {string.Join(", ", available)}"); } var inputBuilder = new InputBuilder(ectx, component.ArgumentType, catalog); if (settings != null) { foreach (var pair in settings) { if (!inputBuilder.TrySetValueJson(pair.Key, pair.Value)) { throw ectx.Except($"Unexpected value for component '{name}', field '{pair.Key}': '{pair.Value}'"); } } } var missing = inputBuilder.GetMissingValues().ToArray(); if (missing.Length > 0) { throw ectx.Except($"The following required inputs were not provided for component '{name}': {string.Join(", ", missing)}"); } return(inputBuilder.GetInstance() as IComponentFactory); }
private static JToken BuildTypeToken(IExceptionContext ectx, FieldInfo fieldInfo, Type type, ModuleCatalog catalog) { Contracts.AssertValueOrNull(ectx); ectx.AssertValue(type); ectx.AssertValue(catalog); // REVIEW: Allows newly introduced types to not break the manifest bulding process. // Where possible, these types should be replaced by component kinds. if (type == typeof(CommonInputs.IEvaluatorInput) || type == typeof(CommonOutputs.IEvaluatorOutput)) { var jo = new JObject(); var typeString = $"{type}".Replace("Microsoft.ML.Runtime.EntryPoints.", ""); jo[FieldNames.Kind] = "EntryPoint"; jo[FieldNames.ItemType] = typeString; return(jo); } type = CSharpGeneratorUtils.ExtractOptionalOrNullableType(type); // Dive inside Var. if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Var <>)) { type = type.GetGenericArguments()[0]; } var typeEnum = TlcModule.GetDataType(type); switch (typeEnum) { case TlcModule.DataKind.Unknown: var jo = new JObject(); if (type == typeof(JArray)) { jo[FieldNames.Kind] = TlcModule.DataKind.Array.ToString(); jo[FieldNames.ItemType] = "Node"; return(jo); } if (type == typeof(JObject)) { return("Bindings"); } var fields = BuildInputManifest(ectx, type, catalog); if (fields.Count == 0) { throw ectx.Except("Unexpected parameter type: {0}", type); } jo[FieldNames.Kind] = "Struct"; jo[FieldNames.Fields] = fields; return(jo); case TlcModule.DataKind.Float: case TlcModule.DataKind.Int: case TlcModule.DataKind.UInt: case TlcModule.DataKind.Char: case TlcModule.DataKind.String: case TlcModule.DataKind.Bool: case TlcModule.DataKind.DataView: case TlcModule.DataKind.TransformModel: case TlcModule.DataKind.PredictorModel: case TlcModule.DataKind.FileHandle: return(typeEnum.ToString()); case TlcModule.DataKind.Enum: jo = new JObject(); jo[FieldNames.Kind] = typeEnum.ToString(); var values = Enum.GetNames(type); jo[FieldNames.Values] = new JArray(values); return(jo); case TlcModule.DataKind.Array: jo = new JObject(); jo[FieldNames.Kind] = typeEnum.ToString(); jo[FieldNames.ItemType] = BuildTypeToken(ectx, fieldInfo, type.GetElementType(), catalog); return(jo); case TlcModule.DataKind.Dictionary: jo = new JObject(); jo[FieldNames.Kind] = typeEnum.ToString(); jo[FieldNames.ItemType] = BuildTypeToken(ectx, fieldInfo, type.GetGenericArguments()[1], catalog); return(jo); case TlcModule.DataKind.Component: string kind; if (!catalog.TryGetComponentKind(type, out kind)) { throw ectx.Except("Field '{0}' is a component of unknown kind", fieldInfo.Name); } jo = new JObject(); jo[FieldNames.Kind] = typeEnum.ToString(); jo[FieldNames.ComponentKind] = kind; return(jo); case TlcModule.DataKind.State: jo = new JObject(); var typeString = $"{type}".Replace("Microsoft.ML.Runtime.Interfaces.", ""); jo[FieldNames.Kind] = "C# Object"; jo[FieldNames.ItemType] = typeString; return(jo); default: ectx.Assert(false); throw ectx.ExceptNotSupp(); } }
public static string GetInputType(ModuleCatalog catalog, Type inputType, GeneratedClasses generatedClasses, string rootNameSpace) { if (inputType.IsGenericType && inputType.GetGenericTypeDefinition() == typeof(Var <>)) { return($"Var<{GetCSharpTypeName(inputType.GetGenericTypeArgumentsEx()[0])}>"); } if (inputType.IsArray && Var <int> .CheckType(inputType.GetElementType())) { return($"ArrayVar<{GetCSharpTypeName(inputType.GetElementType())}>"); } if (inputType.IsGenericType && inputType.GetGenericTypeDefinition() == typeof(Dictionary <,>) && inputType.GetGenericTypeArgumentsEx()[0] == typeof(string)) { return($"DictionaryVar<{GetCSharpTypeName(inputType.GetGenericTypeArgumentsEx()[1])}>"); } if (Var <int> .CheckType(inputType)) { return($"Var<{GetCSharpTypeName(inputType)}>"); } var type = ExtractOptionalOrNullableType(inputType, out bool isNullable, out bool isOptional); var typeEnum = TlcModule.GetDataType(type); switch (typeEnum) { case TlcModule.DataKind.Float: case TlcModule.DataKind.Int: case TlcModule.DataKind.UInt: case TlcModule.DataKind.Char: case TlcModule.DataKind.String: case TlcModule.DataKind.Bool: case TlcModule.DataKind.DataView: case TlcModule.DataKind.TransformModel: case TlcModule.DataKind.PredictorModel: case TlcModule.DataKind.FileHandle: return(GetCSharpTypeName(inputType)); case TlcModule.DataKind.Array: return(GetInputType(catalog, inputType.GetElementType(), generatedClasses, rootNameSpace) + "[]"); case TlcModule.DataKind.Component: string kind; bool success = catalog.TryGetComponentKind(type, out kind); Contracts.Assert(success); return($"{kind}"); case TlcModule.DataKind.Enum: var enumName = generatedClasses.GetApiName(type, rootNameSpace); if (isNullable) { return($"{enumName}?"); } if (isOptional) { return($"Optional<{enumName}>"); } return($"{enumName}"); default: if (isNullable) { return(generatedClasses.GetApiName(type, rootNameSpace) + "?"); } if (isOptional) { return($"Optional<{generatedClasses.GetApiName(type, rootNameSpace)}>"); } return(generatedClasses.GetApiName(type, rootNameSpace)); } }