getFields performs a breadth-first search for all fields, including embedded ones. It may return multiple fields with the same name, the first of which represents the outermost declaration.
(typ reflect.Type, visited map[reflect.Type]struct{})
| 689 | // ones. It may return multiple fields with the same name, the first of which |
| 690 | // represents the outermost declaration. |
| 691 | func getFields(typ reflect.Type, visited map[reflect.Type]struct{}) []fieldInfo { |
| 692 | fields := make([]fieldInfo, 0, typ.NumField()) |
| 693 | var embedded []reflect.StructField |
| 694 | |
| 695 | if _, ok := visited[typ]; ok { |
| 696 | return fields |
| 697 | } |
| 698 | visited[typ] = struct{}{} |
| 699 | |
| 700 | for i := 0; i < typ.NumField(); i++ { |
| 701 | f := typ.Field(i) |
| 702 | if !f.IsExported() { |
| 703 | continue |
| 704 | } |
| 705 | |
| 706 | if f.Anonymous && f.Tag.Get("json") == "" { |
| 707 | embedded = append(embedded, f) |
| 708 | continue |
| 709 | } |
| 710 | |
| 711 | fields = append(fields, fieldInfo{typ, f}) |
| 712 | } |
| 713 | |
| 714 | for _, f := range embedded { |
| 715 | newTyp := f.Type |
| 716 | for newTyp.Kind() == reflect.Pointer { |
| 717 | newTyp = newTyp.Elem() |
| 718 | } |
| 719 | if newTyp.Kind() == reflect.Struct { |
| 720 | fields = append(fields, getFields(newTyp, visited)...) |
| 721 | } |
| 722 | } |
| 723 | |
| 724 | return fields |
| 725 | } |
| 726 | |
| 727 | // SchemaProvider is an interface that can be implemented by types to provide |
| 728 | // a custom schema for themselves, overriding the built-in schema generation. |
no test coverage detected
searching dependent graphs…