// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) by respective owners including Yahoo!, Microsoft, and
// individual contributors. All rights reserved. Released under a BSD
// license as described in the file LICENSE.
//
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;
using System.Reflection;
using VW.Reflection;
namespace VW.Serializer
{
///
/// Delegate defintion for feature object creation expressions.
///
/// An expression resolving to a VowpalWabbit instance.
/// An expression resolving to a Namespace instance.
/// An expression constructing a new Feature object.
public delegate Expression NewFeatureExpressionDelegate(Expression vw, Expression @namespace);
///
/// Feature data composed during compilation step.
///
[DebuggerDisplay("FeatureExpression({Name})")]
public sealed class FeatureExpression
{
///
/// Initializes a new instance of the class.
///
/// The type of the feature.
/// The name of the feature.
/// Factory to extract the value for a given feature from the example object (input argument).
/// Factories to provide validation before invoking the expression created through .
/// The expression must create new Feature instances.
/// The namespace this feature belongs to.
/// The feature group this feature belongs to.
/// If true the marshaller enumerates the feature (as in creates a 1-hot encoding).
/// The variable name to be used in the generated code.
/// Used to order feature serialization.
/// True if an anchor element should be added at the beginning of a dense feature array.
/// Configures string pre-processing for this feature.
/// An optional method overriding the otherwise auto-resolved serialization method.
/// True if a dictionary should be build for this feature.
/// The parent feature expression.
public FeatureExpression(Type featureType,
string name,
Func valueExpressionFactory,
List> valueValidExpressionFactories = null,
NewFeatureExpressionDelegate featureExpressionFactory = null,
string @namespace = null,
char? featureGroup = null,
bool enumerize = false,
string variableName = null,
int? order = null,
bool addAnchor = false,
StringProcessing stringProcessing = StringProcessing.Split,
MethodInfo overrideSerializeMethod = null,
bool? dictify = null,
FeatureExpression parent = null)
{
if (featureType == null)
throw new ArgumentNullException("featureType");
if (valueExpressionFactory == null)
throw new ArgumentNullException("valueExpressionFactory");
Contract.EndContractBlock();
if(featureType.IsGenericType &&
featureType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
this.IsNullable = true;
this.FeatureType = featureType.GetGenericArguments()[0];
}
else
{
this.IsNullable = false;
this.FeatureType = featureType;
}
this.Name = name;
this.ValueExpressionFactory = valueExpressionFactory;
this.ValueValidExpressionFactories = valueValidExpressionFactories;
this.FeatureExpressionFactory = featureExpressionFactory;
this.Namespace = @namespace;
this.FeatureGroup = featureGroup;
this.Enumerize = enumerize;
this.VariableName = variableName ?? name;
this.Order = order ?? 1;
this.AddAnchor = addAnchor;
this.Dictify = dictify ?? false;
this.StringProcessing = stringProcessing;
this.OverrideSerializeMethod = overrideSerializeMethod;
this.Dictify = dictify ?? false;
this.Parent = parent;
this.DenseFeatureValueElementType = InspectionHelper.GetEnumerableElementType(featureType);
if (!InspectionHelper.IsNumericType(this.DenseFeatureValueElementType))
this.DenseFeatureValueElementType = null;
}
///
/// The parent feature expression.
///
public FeatureExpression Parent { get; private set; }
///
/// True if the type is nullable.
///
public bool IsNullable { get; set; }
///
/// Serializer variable name.
///
/// Useful to debug
public string VariableName { get; set; }
///
/// The type of the feature.
///
public Type FeatureType { get; private set; }
internal Type IntermediateFeatureType { get; set; }
///
/// The name of the feature.
///
public string Name { get; set; }
///
/// The namespace.
///
public string Namespace { get; set; }
///
/// The feature group.
///
public char? FeatureGroup { get; set; }
///
/// An optional method overriding the otherwise auto-resolved serialization method.
///
public MethodInfo OverrideSerializeMethod { get; set; }
///
/// True if this feature should be enumerized.
///
public bool Enumerize { get; set; }
///
/// True if an anchor element should be added at the beginning of a dense feature array.
///
public bool AddAnchor { get; set; }
///
/// True if a dictionary should be build for this feature.
///
public bool Dictify { get; set; }
///
/// Factory to extract the value for a given feature from the example object (input argument).
///
public Func ValueExpressionFactory { get; set; }
///
/// Factories to provide validation before invoking the expression created through .
///
public List> ValueValidExpressionFactories { get; set; }
///
/// The expression must create new Feature instances.
///
public NewFeatureExpressionDelegate FeatureExpressionFactory { get; set; }
///
/// The element type of an enumerable feature type.
///
public Type DenseFeatureValueElementType { get; set; }
///
/// Used to order feature serialization.
///
public int Order { get; set; }
///
/// Configures string pre-processing for this feature.
///
public StringProcessing StringProcessing { get; set; }
}
}