github.com/99designs/gqlgen@v0.17.45/plugin/federation/testdata/entityinterfaces/generated/federation.go (about) 1 // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. 2 3 package generated 4 5 import ( 6 "context" 7 "errors" 8 "fmt" 9 "strings" 10 "sync" 11 12 "github.com/99designs/gqlgen/plugin/federation/fedruntime" 13 ) 14 15 var ( 16 ErrUnknownType = errors.New("unknown type") 17 ErrTypeNotFound = errors.New("type not found") 18 ) 19 20 func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime.Service, error) { 21 if ec.DisableIntrospection { 22 return fedruntime.Service{}, errors.New("federated introspection disabled") 23 } 24 25 var sdl []string 26 27 for _, src := range sources { 28 if src.BuiltIn { 29 continue 30 } 31 sdl = append(sdl, src.Input) 32 } 33 34 return fedruntime.Service{ 35 SDL: strings.Join(sdl, "\n"), 36 }, nil 37 } 38 39 func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) []fedruntime.Entity { 40 list := make([]fedruntime.Entity, len(representations)) 41 42 repsMap := map[string]struct { 43 i []int 44 r []map[string]interface{} 45 }{} 46 47 // We group entities by typename so that we can parallelize their resolution. 48 // This is particularly helpful when there are entity groups in multi mode. 49 buildRepresentationGroups := func(reps []map[string]interface{}) { 50 for i, rep := range reps { 51 typeName, ok := rep["__typename"].(string) 52 if !ok { 53 // If there is no __typename, we just skip the representation; 54 // we just won't be resolving these unknown types. 55 ec.Error(ctx, errors.New("__typename must be an existing string")) 56 continue 57 } 58 59 _r := repsMap[typeName] 60 _r.i = append(_r.i, i) 61 _r.r = append(_r.r, rep) 62 repsMap[typeName] = _r 63 } 64 } 65 66 isMulti := func(typeName string) bool { 67 switch typeName { 68 default: 69 return false 70 } 71 } 72 73 resolveEntity := func(ctx context.Context, typeName string, rep map[string]interface{}, idx []int, i int) (err error) { 74 // we need to do our own panic handling, because we may be called in a 75 // goroutine, where the usual panic handling can't catch us 76 defer func() { 77 if r := recover(); r != nil { 78 err = ec.Recover(ctx, r) 79 } 80 }() 81 82 switch typeName { 83 case "Hello": 84 resolverName, err := entityResolverNameForHello(ctx, rep) 85 if err != nil { 86 return fmt.Errorf(`finding resolver for Entity "Hello": %w`, err) 87 } 88 switch resolverName { 89 90 case "findHelloByID": 91 id0, err := ec.unmarshalNString2string(ctx, rep["id"]) 92 if err != nil { 93 return fmt.Errorf(`unmarshalling param 0 for findHelloByID(): %w`, err) 94 } 95 entity, err := ec.resolvers.Entity().FindHelloByID(ctx, id0) 96 if err != nil { 97 return fmt.Errorf(`resolving Entity "Hello": %w`, err) 98 } 99 100 list[idx[i]] = entity 101 return nil 102 } 103 case "World": 104 resolverName, err := entityResolverNameForWorld(ctx, rep) 105 if err != nil { 106 return fmt.Errorf(`finding resolver for Entity "World": %w`, err) 107 } 108 switch resolverName { 109 110 case "findWorldByID": 111 id0, err := ec.unmarshalNString2string(ctx, rep["id"]) 112 if err != nil { 113 return fmt.Errorf(`unmarshalling param 0 for findWorldByID(): %w`, err) 114 } 115 entity, err := ec.resolvers.Entity().FindWorldByID(ctx, id0) 116 if err != nil { 117 return fmt.Errorf(`resolving Entity "World": %w`, err) 118 } 119 120 list[idx[i]] = entity 121 return nil 122 } 123 124 } 125 return fmt.Errorf("%w: %s", ErrUnknownType, typeName) 126 } 127 128 resolveManyEntities := func(ctx context.Context, typeName string, reps []map[string]interface{}, idx []int) (err error) { 129 // we need to do our own panic handling, because we may be called in a 130 // goroutine, where the usual panic handling can't catch us 131 defer func() { 132 if r := recover(); r != nil { 133 err = ec.Recover(ctx, r) 134 } 135 }() 136 137 switch typeName { 138 139 default: 140 return errors.New("unknown type: " + typeName) 141 } 142 } 143 144 resolveEntityGroup := func(typeName string, reps []map[string]interface{}, idx []int) { 145 if isMulti(typeName) { 146 err := resolveManyEntities(ctx, typeName, reps, idx) 147 if err != nil { 148 ec.Error(ctx, err) 149 } 150 } else { 151 // if there are multiple entities to resolve, parallelize (similar to 152 // graphql.FieldSet.Dispatch) 153 var e sync.WaitGroup 154 e.Add(len(reps)) 155 for i, rep := range reps { 156 i, rep := i, rep 157 go func(i int, rep map[string]interface{}) { 158 err := resolveEntity(ctx, typeName, rep, idx, i) 159 if err != nil { 160 ec.Error(ctx, err) 161 } 162 e.Done() 163 }(i, rep) 164 } 165 e.Wait() 166 } 167 } 168 buildRepresentationGroups(representations) 169 170 switch len(repsMap) { 171 case 0: 172 return list 173 case 1: 174 for typeName, reps := range repsMap { 175 resolveEntityGroup(typeName, reps.r, reps.i) 176 } 177 return list 178 default: 179 var g sync.WaitGroup 180 g.Add(len(repsMap)) 181 for typeName, reps := range repsMap { 182 go func(typeName string, reps []map[string]interface{}, idx []int) { 183 resolveEntityGroup(typeName, reps, idx) 184 g.Done() 185 }(typeName, reps.r, reps.i) 186 } 187 g.Wait() 188 return list 189 } 190 } 191 192 func entityResolverNameForHello(ctx context.Context, rep map[string]interface{}) (string, error) { 193 for { 194 var ( 195 m map[string]interface{} 196 val interface{} 197 ok bool 198 ) 199 _ = val 200 m = rep 201 if _, ok = m["id"]; !ok { 202 break 203 } 204 return "findHelloByID", nil 205 } 206 return "", fmt.Errorf("%w for Hello", ErrTypeNotFound) 207 } 208 209 func entityResolverNameForWorld(ctx context.Context, rep map[string]interface{}) (string, error) { 210 for { 211 var ( 212 m map[string]interface{} 213 val interface{} 214 ok bool 215 ) 216 _ = val 217 m = rep 218 if _, ok = m["id"]; !ok { 219 break 220 } 221 return "findWorldByID", nil 222 } 223 return "", fmt.Errorf("%w for World", ErrTypeNotFound) 224 }