private int DeriveNestedSerialization(FieldInfo thatField, int annotationType)
{
int result = annotationType;
Type thatFieldType = thatField.FieldType;
switch (annotationType)
{
case FieldTypes.CompositeElement:
String compositeTag = XmlTools.GetAnnotation<SimplComposite>(thatField).TagName;
Boolean isWrap = XmlTools.IsAnnotationPresent<SimplWrap>(thatField);
Boolean compositeTagIsNullOrEmpty = String.IsNullOrEmpty(compositeTag);
if (!IsPolymorphic)
{
if (isWrap && compositeTagIsNullOrEmpty)
{
String msg = "In " + declaringClassDescriptor.DescribedClass
+ "\n\tCan't translate [SimplComposite] " + thatField.Name
+ " because its tag argument is missing.";
Debug.WriteLine(msg);
return FieldTypes.IgnoredAttribute;
}
_elementClassDescriptor = ClassDescriptor.GetClassDescriptor(thatFieldType);
_elementClass = _elementClassDescriptor.DescribedClass;
compositeTag = XmlTools.GetXmlTagName(thatField);
}
else
{
if (!compositeTagIsNullOrEmpty)
{
String msg = "In " + declaringClassDescriptor.DescribedClass
+ "\n\tCan't translate [SimplComposite] " + thatField.Name
+ " because its tag argument is missing.";
Debug.WriteLine(msg);
}
}
compositeTagName = compositeTag;
break;
case FieldTypes.CollectionElement:
if (!(typeof(IList).GetTypeInfo().IsAssignableFrom(thatField.FieldType.GetTypeInfo())))
{
String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tCan't translate "
+ "[SimplCollection] " + field.Name
+ " because the annotated field is not an instance of " +
typeof (IList).Name
+ ".";
Debug.WriteLine(msg);
return FieldTypes.IgnoredAttribute;
}
String collectionTag = XmlTools.GetAnnotation<SimplCollection>(thatField).TagName;
if (!IsPolymorphic)
{
Type collectionElementType = GetTypeArgs(thatField, 0);
if (String.IsNullOrEmpty(collectionTag))
{
String msg = "In " + declaringClassDescriptor.DescribedClass
+ "\n\tCan't translate [SimplCollection]" + field.Name
+ " because its tag argument is missing.";
Debug.WriteLine(msg);
return FieldTypes.IgnoredElement;
}
if (collectionElementType == null)
{
String msg = "In " + declaringClassDescriptor.DescribedClass
+ "\n\tCan't translate [SimplCollection] " + field.Name
+ " because the parameterized type argument for the Collection is missing.";
Debug.WriteLine(msg);
return FieldTypes.IgnoredElement;
}
if (!TypeRegistry.ScalarTypes.Contains(collectionElementType))
{
_elementClassDescriptor = ClassDescriptor.GetClassDescriptor(collectionElementType);
_elementClass = _elementClassDescriptor.DescribedClass;
}
else
{
result = FieldTypes.CollectionScalar;
DeriveScalarSerialization(collectionElementType, field);
if (ScalarType == null)
{
result = FieldTypes.IgnoredElement;
String msg = "Can't identify ScalarType for serialization of " + collectionElementType;
Debug.WriteLine(msg);
}
}
}
else
{
if (!String.IsNullOrEmpty(collectionTag))
{
String msg = "In " + declaringClassDescriptor.DescribedClass
+ "\n\tIgnoring argument to [SimplCollection] " + field.Name
+ " because it is declared polymorphic with [SimplClasses].";
}
}
_collectionOrMapTagName = collectionTag;
collectionType = TypeRegistry.GetCollectionType(thatField);
break;
case FieldTypes.MapElement:
if (!(typeof(IDictionary).GetTypeInfo().IsAssignableFrom(thatField.FieldType.GetTypeInfo())))
{
String msg = "In " + declaringClassDescriptor.DescribedClass + "\n\tCan't translate "
+ "[SimplMap] " + field.Name
+ " because the annotated field is not an instance of " +
typeof (IDictionary).Name
+ ".";
Debug.WriteLine(msg);
return FieldTypes.IgnoredAttribute;
}
String mapTag = XmlTools.GetAnnotation<SimplMap>(thatField).TagName;
if (!IsPolymorphic)
{
Type mapElementType = GetTypeArgs(thatField, 1);
if (String.IsNullOrEmpty(mapTag))
{
String msg = "In " + declaringClassDescriptor.DescribedClass
+ "\n\tCan't translate [SimplMap]" + field.Name
+ " because its tag argument is missing.";
Debug.WriteLine(msg);
return FieldTypes.IgnoredElement;
}
if (mapElementType == null)
{
String msg = "In " + declaringClassDescriptor.DescribedClass
+ "\n\tCan't translate [SimplMap] " + field.Name
+ " because the parameterized type argument for the map is missing.";
Debug.WriteLine(msg);
return FieldTypes.IgnoredElement;
}
if (!TypeRegistry.ScalarTypes.Contains(mapElementType))
{
_elementClassDescriptor = ClassDescriptor.GetClassDescriptor(mapElementType);
_elementClass = _elementClassDescriptor.DescribedClass;
}
}
else
{
if (!String.IsNullOrEmpty(mapTag))
{
String msg = "In " + declaringClassDescriptor.DescribedClass
+ "\n\tIgnoring argument to [SimplMap] " + field.Name
+ " because it is declared polymorphic with [SimplClasses].";
}
}
_collectionOrMapTagName = mapTag;
collectionType = TypeRegistry.GetCollectionType(thatField);
break;
}
switch (annotationType)
{
case FieldTypes.CollectionElement:
case FieldTypes.MapElement:
if (!XmlTools.IsAnnotationPresent<SimplNoWrap>(thatField))
{
_wrapped = true;
}
collectionType = TypeRegistry.GetCollectionType(thatField);
break;
case FieldTypes.CompositeElement:
if (XmlTools.IsAnnotationPresent<SimplWrap>(thatField))
{
_wrapped = true;
}
break;
}
return result;
}