in cs/src/core/expressions/ParserFactory.cs [39:102]
static Cache()
{
Type parserType;
var attribute = typeof(R).GetAttribute<ParserAttribute>();
if (attribute == null)
{
if (typeof(ITaggedProtocolReader).IsAssignableFrom(typeof(R)))
{
parserType = typeof(TaggedParser<R>);
}
else if (typeof(IUntaggedProtocolReader).IsAssignableFrom(typeof(R)))
{
parserType = typeof(UntaggedParser<R>);
}
else
{
throw new InvalidOperationException(
string.Format(
CultureInfo.InvariantCulture,
"Can't determine parser type for reader type {0}, specify using ParserAttribute.",
typeof(R)));
}
}
else
{
var genericParserType = attribute.ParserType;
if (!genericParserType.IsGenericType() || genericParserType.GetTypeInfo().GenericTypeParameters.Length != 1)
{
throw new InvalidOperationException(
"Parser type is expected to be a generic type with one type param for Reader.");
}
parserType = genericParserType.MakeGenericType(typeof(R));
if (!typeof(IParser).IsAssignableFrom(parserType))
{
throw new InvalidOperationException(
string.Format(
CultureInfo.InvariantCulture,
"Parser type {0} specified in attribute for Reader type {1} is not an IParser.",
parserType,
typeof(R)));
}
}
var ctor = parserType.GetConstructor(typeof(S), typeof(PayloadBondedFactory)) ??
parserType.GetConstructor(typeof(S));
if (ctor == null)
{
throw new InvalidOperationException(
string.Format(CultureInfo.InvariantCulture,
"Can't find constructor for type '{0}' with either ({1}) or ({1}, {2}) signature.",
parserType, typeof(S), typeof(PayloadBondedFactory)));
}
var schema = Expression.Parameter(typeof(S));
var bondedFactory = Expression.Parameter(typeof(PayloadBondedFactory));
var newExpression = ctor.GetParameters().Length == 2
? Expression.New(ctor, schema, bondedFactory)
: Expression.New(ctor, schema);
Create = Expression.Lambda<Func<S, PayloadBondedFactory, IParser>>(newExpression, schema, bondedFactory).Compile();
}