federation.go 4.5 KB

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