@SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"})
    private <T extends GraphQLOutputType> T buildOutputType(BuildContext buildCtx, Type rawType) {

        TypeDefinition typeDefinition = buildCtx.getTypeDefinition(rawType);
        TypeInfo typeInfo = TypeInfo.typeInfo(rawType);

        GraphQLOutputType outputType = buildCtx.hasOutputType(typeDefinition);
        if (outputType != null) {
            return typeInfo.decorate(outputType);
        }

        if (buildCtx.stackContains(typeInfo)) {
            // we have circled around so put in a type reference and fix it up later
            // otherwise we will go into an infinite loop
            return typeInfo.decorate(typeRef(typeInfo.getName()));
        }

        buildCtx.push(typeInfo);

        if (typeDefinition instanceof ObjectTypeDefinition) {
            outputType = buildObjectType(buildCtx, (ObjectTypeDefinition) typeDefinition);
        } else if (typeDefinition instanceof InterfaceTypeDefinition) {
            outputType = buildInterfaceType(buildCtx, (InterfaceTypeDefinition) typeDefinition);
        } else if (typeDefinition instanceof UnionTypeDefinition) {
            outputType = buildUnionType(buildCtx, (UnionTypeDefinition) typeDefinition);
        } else if (typeDefinition instanceof EnumTypeDefinition) {
            outputType = buildEnumType(buildCtx, (EnumTypeDefinition) typeDefinition);
        } else if (typeDefinition instanceof ScalarTypeDefinition) {
            outputType = buildScalar(buildCtx, (ScalarTypeDefinition) typeDefinition);
        } else {
            // typeDefinition is not a valid output type
            throw new NotAnOutputTypeError(rawType, typeDefinition);
        }

        buildCtx.putOutputType(outputType);
        buildCtx.pop();
        return (T) typeInfo.decorate(outputType);
    }
@ SuppressWarnings ( { "unchecked" , "TypeParameterUnusedInFormals" } ) private < T extends GraphQLOutputType > T buildOutputType ( BuildContext buildCtx , Type rawType ) { TypeDefinition typeDefinition = buildCtx . getTypeDefinition ( rawType ) ; TypeInfo typeInfo = TypeInfo . typeInfo ( rawType ) ; GraphQLOutputType outputType = buildCtx . hasOutputType ( typeDefinition ) ; if ( outputType != null ) { return typeInfo . decorate ( outputType ) ; } if ( buildCtx . stackContains ( typeInfo ) ) { return typeInfo . decorate ( typeRef ( typeInfo . getName ( ) ) ) ; } buildCtx . push ( typeInfo ) ; if ( typeDefinition instanceof ObjectTypeDefinition ) { outputType = buildObjectType ( buildCtx , ( ObjectTypeDefinition ) typeDefinition ) ; } else if ( typeDefinition instanceof InterfaceTypeDefinition ) { outputType = buildInterfaceType ( buildCtx , ( InterfaceTypeDefinition ) typeDefinition ) ; } else if ( typeDefinition instanceof UnionTypeDefinition ) { outputType = buildUnionType ( buildCtx , ( UnionTypeDefinition ) typeDefinition ) ; } else if ( typeDefinition instanceof EnumTypeDefinition ) { outputType = buildEnumType ( buildCtx , ( EnumTypeDefinition ) typeDefinition ) ; } else if ( typeDefinition instanceof ScalarTypeDefinition ) { outputType = buildScalar ( buildCtx , ( ScalarTypeDefinition ) typeDefinition ) ; } else { throw new NotAnOutputTypeError ( rawType , typeDefinition ) ; } buildCtx . putOutputType ( outputType ) ; buildCtx . pop ( ) ; return ( T ) typeInfo . decorate ( outputType ) ; }
This is the main recursive spot that builds out the various forms of Output types

@param buildCtx the context we need to work out what we are doing
@param rawType  the type to be built

@return an output type