protected PrimitiveTypeDescriptor GetTypeDescriptor(XdrPropertySerializationDescriptor prop)
        {
            if (prop.PrimitiveType == typeof(List <>))
            {
                var subtype = ResolveRegistiredTypeDescriptor(prop.PropertyType.GenericTypeArguments[0]);
                return(PrimitiveTypesMap[typeof(List <>)].CreateSubtypeContainer(subtype));
            }
            if (prop.PropertyType.IsArray)
            {
                var elementType = prop.PropertyType.GetElementType();
                if (elementType == typeof(byte))
                {
                    return(PrimitiveTypesMap[typeof(byte[])]);
                }
                var subtype = ResolveRegistiredTypeDescriptor(prop.PropertyType.GetElementType());
                return(PrimitiveTypesMap[typeof(Array)].CreateSubtypeContainer(subtype));
            }
            if (prop.PropertyType.IsEnum)
            {
                return(PrimitiveTypesMap[typeof(int)].CreateEnum(prop.PropertyType));
            }
            if (prop.PrimitiveType == typeof(object))
            {
                var subtype = ResolveRegistiredTypeDescriptor(prop.PropertyType);
                return(PrimitiveTypesMap[typeof(Object)].CreateSubtypeContainer(subtype));
            }
            var wellKnown = ResolveRegistiredTypeDescriptor(prop.PropertyType);

            if (wellKnown != null)
            {
                return(wellKnown);
            }
            throw new NotSupportedException($"Type {prop.PropertyType.FullName} is not supported by the {GetType().FullName} code generator.");
        }
        private string ResolveReflectedPropTypeName(XdrPropertySerializationDescriptor prop)
        {
            var typeDescriptor = GetTypeDescriptor(prop);

            if (typeDescriptor.SubType == null)
            {
                return(typeDescriptor.TargetType);
            }
            return($"{typeDescriptor.TargetType}<{typeDescriptor.SubType.TargetType}>");
        }
        private string GeneratePropertyDeserializeInstructions(XdrPropertySerializationDescriptor prop)
        {
            var propTypeDescriptor = GetTypeDescriptor(prop);
            var fieldAccessor      = $"value.{prop.PropertyName}";

            if (!prop.IsOptional)
            {
                return(GeneratePlainPropertyDeserializeInstructions(propTypeDescriptor, fieldAccessor));
            }
            return($@"if (reader.ReadInt32() > 0) 
                {{
                    {GeneratePlainPropertyDeserializeInstructions(propTypeDescriptor, fieldAccessor)}
                }}
");
        }
        private string GeneratePropertySerializeInstructions(XdrPropertySerializationDescriptor prop)
        {
            var propTypeDescriptor = GetTypeDescriptor(prop);
            var fieldAccessor      = $"value.{prop.PropertyName}";

            if (!prop.IsOptional)
            {
                return(GeneratePlainPropertySerializeInstructions(propTypeDescriptor, fieldAccessor));
            }
            return($@"if ({fieldAccessor} == null) 
                {{
                    writer.WriteInt32(0);
                }}
                else
                {{
                    writer.WriteInt32(1);
                    {GeneratePlainPropertySerializeInstructions(propTypeDescriptor, fieldAccessor)}
                }}
");
        }