func()

in pkg/swagger/typewalker.go [87:184]


func (tw *typeWalker) schemaFromType(t types.Type, deps map[*types.Named]struct{}) (s *Schema) {
	s = &Schema{}

	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.Bool:
			s.Type = "boolean"
		case types.Int:
			s.Type = "integer"
			s.Format = "int32"
		case types.String:
			s.Type = "string"
		default:
			panic(t)
		}

	case *types.Map:
		s.Type = "object"
		s.AdditionalProperties = tw.schemaFromType(t.Elem(), deps)

	case *types.Named:
		s.Ref = "#/definitions/" + t.Obj().Name()
		deps[t] = struct{}{}

	case *types.Pointer:
		s = tw.schemaFromType(t.Elem(), deps)

	case *types.Slice:
		if e, ok := t.Elem().(*types.Basic); ok {
			// handle []byte as a string (it'll be base64 encoded by json.Marshal)
			if e.Kind() == types.Uint8 {
				s.Type = "string"
			}
		} else {
			s.Type = "array"
			s.Items = tw.schemaFromType(t.Elem(), deps)
			// https://github.com/Azure/autorest/tree/main/docs/extensions#x-ms-identifiers
			// we do not use this field, but the upstream validation requires at least an empty array
			if tw.xmsIdentifiers != nil {
				s.XMSIdentifiers = &[]string{}
			}
		}

	case *types.Struct:
		s.Type = "object"
		for i := 0; i < t.NumFields(); i++ {
			field := t.Field(i)
			if field.Exported() {
				nodes, _ := tw.getNodes(field.Pos())
				nodeField, ok := getNodeField(nodes)
				if !ok {
					panic("could not find field for nodes")
				}
				tag, _ := strconv.Unquote(nodeField.Tag.Value)

				name := strings.SplitN(reflect.StructTag(tag).Get("json"), ",", 2)[0]
				if name == "-" {
					continue
				}

				properties := tw.schemaFromType(field.Type(), deps)
				properties.Description = strings.Trim(nodeField.Doc.Text(), "\n")

				if swaggerTag, ok := reflect.StructTag(tag).Lookup("swagger"); ok {
					// XXX In theory this would be a comma-delimited
					//     list, but "readonly" is the only value we
					//     currently recognize.
					if strings.EqualFold(swaggerTag, "readOnly") {
						properties.ReadOnly = true
					}
				}

				ns := NameSchema{
					Name:   name,
					Schema: properties,
				}

				for _, xname := range tw.xmsSecretList {
					if xname == name {
						ns.Schema.XMSSecret = true
					}
				}
				s.Properties = append(s.Properties, ns)
			}
			if field.Name() == "proxyResource" {
				s.AllOf = []Schema{
					{
						Ref: fmt.Sprintf("../../../../../../common-types/resource-management/%s/types.json#/definitions/ProxyResource", tw.commonTypesVersion),
					},
				}
			}
		}
	default:
		panic(t)
	}
	return
}