func (c *_Context) completeValue( returnType typs.QLType, fieldASTs []*lang.Field, info typs.QLResolveInfo, result interface{}, ) interface{} { if returnType, ok := returnType.(*typs.QLNonNull); ok { completed := c.completeValue(returnType.OfType, fieldASTs, info, result) if completed == nil { nodes := make([]lang.INode, len(fieldASTs)) for i, node := range fieldASTs { nodes[i] = node } panic(lang.NewQLError( fmt.Sprintf( `Cannot return null for non-nullable field %v.%v.`, info.ParentType, info.FieldName), nodes)) } return completed } v := reflect.ValueOf(result) if result == nil { return nil } v = reflect.Indirect(v) t := v.Type() switch returnType := returnType.(type) { case *typs.QLList: if t.Kind() == reflect.Slice || t.Kind() == reflect.Array { itemType := returnType.OfType list := make([]interface{}, t.NumField()) for i, n := 0, t.NumField(); i < n; i++ { list[i] = c.completeValueCatchingError(itemType, fieldASTs, info, v.Field(i).Interface()) } return list } panic("User Error: expected array of slice, but did not find one.") case *typs.QLScalar: if returnType.Serialize == nil { panic("Missing serialize method on type") } serializedResult := returnType.Serialize(result) if serializedResult == nil { return nil } return serializedResult case *typs.QLEnum: return returnType.Serialize(result) case *typs.QLObject: runtimeType := returnType subFieldASTs := map[string][]*lang.Field{} visitedFragmentNames := map[string]struct{}{} for _, fieldAST := range fieldASTs { selectionSet := fieldAST.SelectionSet if selectionSet != nil { subFieldASTs = c.collectFields(runtimeType, selectionSet, subFieldASTs, visitedFragmentNames) } } return c.executeFields(runtimeType, result, subFieldASTs) case typs.QLAbstractType: panic("not implemented") default: panic("unreachable") } }