final GeneratorContext context = this.getGeneratorContext();
context.branch();
context.info("Finding all serializable types reachable from " + type);
final Type map = this.getMap();
final Type list = this.getList();
final Type set = this.getSet();
final ReachableTypesVisitor visitor = new ReachableTypesVisitor() {
@Override
protected boolean skipTypeThatImplementsInterface(final Type type, final Type interfacee) {
return false == SerializationFactoryGenerator.this.isOrHasSerializableSubType(type);
}
@Override
protected boolean skipArray(final Type array) {
Checker.notNull("parameter:array", array);
return false;
}
@Override
protected boolean skipType(final Type type) {
boolean skip = false;
while (true) {
// we dont want to visit the fields of $type we already have
// a reader/writer.
if (typesToReadersOrWriters.containsKey(type)) {
skip = true;
break;
}
if (SerializationFactoryGenerator.this.isOrHasSerializableSubType(type)) {
skip = false;
break;
}
skip = false;
break;
}
return skip;
}
@Override
protected void visitType(final Type type) {
if (false == SerializationFactoryGenerator.this.isOrHasSerializableSubType(type)) {
SerializationFactoryGenerator.this.throwEncounteredUnserializableType(type);
}
context.branch();
context.debug(type.getName());
super.visitType(type);
context.unbranch();
}
@Override
protected boolean skipSuperType(final Type superType) {
return !SerializationFactoryGenerator.this.isOrHasSerializableSubType(superType);
}
@Override
protected void visitSuperType(final Type superType) {
context.branch();
context.debug(superType.getName());
super.visitSuperType(superType);
context.unbranch();
}
@Override
protected boolean skipSubType(final Type subType) {
return !SerializationFactoryGenerator.this.isOrHasSerializableSubType(subType);
}
@Override
protected void visitSubType(final Type subType) {
context.branch();
context.debug(subType.getName());
super.visitSubType(subType);
context.unbranch();
}
@Override
protected void visitFields(final Type type) {
if (false == typesToReadersOrWriters.containsKey(type)) {
super.visitFields(type);
}
}
/**
* Skip transient or static fields.
*/
@Override
protected boolean skipField(final Field field) {
Checker.notNull("parameter:field", field);
return field.isStatic() || field.isTransient();
}
/**
* This method includes special tests to ensure that list/set/map
* element types are visited.
*
* @param field
*/
@Override
protected void visitField(final Field field) {
Checker.notNull("parameter:field", field);
context.branch();
context.debug("Field: " + field.getName());
while (true) {
final Type fieldType = field.getType();
if (field.isFinal()) {
SerializationFactoryGenerator.this.throwFinalFieldEncountered(field);
}
if (list.equals(fieldType)) {
this.processInterface(fieldType);
final Type elementType = SerializationFactoryGenerator.this.getTypeFromAnnotation(field);
context.debug(elementType + " (List)");
this.visitType(elementType);
break;
}
if (set.equals(fieldType)) {
this.processInterface(fieldType);
final Type elementType = SerializationFactoryGenerator.this.getTypeFromAnnotation(field);
context.debug(elementType + " (Set)");
this.visitType(elementType);
break;
}
if (map.equals(fieldType)) {
this.processInterface(fieldType);
final Type keyType = SerializationFactoryGenerator.this.getTypeFromAnnotation(field, 0);
final Type valueType = SerializationFactoryGenerator.this.getTypeFromAnnotation(field, 1);
context.debug(keyType + " (Map key)");
context.debug(valueType + " (Map value)");
this.visitType(keyType);
this.visitType(valueType);