Ejemplo n.º 1
0
Archivo: types.go Proyecto: cw2018/goa
// godef is the common implementation for both GoTypeDef and GoResDef.
// The only difference between the two is how the type names for fields that refer to a media type
// is generated: GoTypeDef uses the type name but GoResDef uses the underlying resource name if the
// type is a media type that corresponds to the canonical representation of a resource.
func godef(ds design.DataStructure, tabs int, jsonTags, inner, res bool) string {
	var buffer bytes.Buffer
	def := ds.Definition()
	t := def.Type
	switch actual := t.(type) {
	case design.Primitive:
		return GoTypeName(t, tabs)
	case *design.Array:
		return "[]" + godef(actual.ElemType, tabs, jsonTags, true, res)
	case *design.Hash:
		keyDef := godef(actual.KeyType, tabs, jsonTags, true, res)
		elemDef := godef(actual.ElemType, tabs, jsonTags, true, res)
		return fmt.Sprintf("map[%s]%s", keyDef, elemDef)
	case design.Object:
		if inner {
			buffer.WriteByte('*')
		}
		buffer.WriteString("struct {\n")
		keys := make([]string, len(actual))
		i := 0
		for n := range actual {
			keys[i] = n
			i++
		}
		sort.Strings(keys)
		for _, name := range keys {
			WriteTabs(&buffer, tabs+1)
			typedef := godef(actual[name], tabs+1, jsonTags, true, res)
			fname := Goify(name, true)
			var tags string
			if jsonTags {
				var omit string
				if !def.IsRequired(name) {
					omit = ",omitempty"
				}
				tags = fmt.Sprintf(" `json:\"%s%s\"`", name, omit)
			}
			desc := actual[name].Description
			if desc != "" {
				desc = fmt.Sprintf("// %s\n", desc)
			}
			buffer.WriteString(fmt.Sprintf("%s%s %s%s\n", desc, fname, typedef, tags))
		}
		WriteTabs(&buffer, tabs)
		buffer.WriteString("}")
		return buffer.String()
	case *design.UserTypeDefinition:
		name := GoTypeName(actual, tabs)
		if actual.Type.IsObject() {
			return "*" + name
		}
		return name
	case *design.MediaTypeDefinition:
		if res && actual.Resource != nil {
			return "*" + Goify(actual.Resource.Name, true)
		}
		name := GoTypeName(actual, tabs)
		if actual.Type.IsObject() {
			return "*" + name
		}
		return name
	default:
		panic("goa bug: unknown data structure type")
	}
}
Ejemplo n.º 2
0
// GoTypeDef returns the Go code that defines a Go type which matches the data structure
// definition (the part that comes after `type foo`).
// versioned indicates whether the type is being referenced from a version package (true) or the
// default package (false).
// tabs is the number of tab character(s) used to tabulate the definition however the first
// line is never indented.
// jsonTags controls whether to produce json tags.
func GoTypeDef(ds design.DataStructure, versioned bool, defPkg string, tabs int, jsonTags bool) string {
	var buffer bytes.Buffer
	def := ds.Definition()
	t := def.Type
	switch actual := t.(type) {
	case design.Primitive:
		return GoTypeName(t, nil, tabs)
	case *design.Array:
		d := GoTypeDef(actual.ElemType, versioned, defPkg, tabs, jsonTags)
		if actual.ElemType.Type.IsObject() {
			d = "*" + d
		}
		return "[]" + d
	case *design.Hash:
		keyDef := GoTypeDef(actual.KeyType, versioned, defPkg, tabs, jsonTags)
		if actual.KeyType.Type.IsObject() {
			keyDef = "*" + keyDef
		}
		elemDef := GoTypeDef(actual.ElemType, versioned, defPkg, tabs, jsonTags)
		if actual.ElemType.Type.IsObject() {
			elemDef = "*" + elemDef
		}
		return fmt.Sprintf("map[%s]%s", keyDef, elemDef)
	case design.Object:
		buffer.WriteString("struct {\n")
		keys := make([]string, len(actual))
		i := 0
		for n := range actual {
			keys[i] = n
			i++
		}
		sort.Strings(keys)
		for _, name := range keys {
			WriteTabs(&buffer, tabs+1)
			field := actual[name]
			typedef := GoTypeDef(field, versioned, defPkg, tabs+1, jsonTags)
			if field.Type.IsObject() || def.IsPrimitivePointer(name) {
				typedef = "*" + typedef
			}
			fname := Goify(name, true)
			var tags string
			if jsonTags {
				var omit string
				if !def.IsRequired(name) {
					omit = ",omitempty"
				}
				tags = fmt.Sprintf(" `json:\"%s%s\"`", name, omit)
			}
			desc := actual[name].Description
			if desc != "" {
				desc = fmt.Sprintf("// %s\n", desc)
			}
			buffer.WriteString(fmt.Sprintf("%s%s %s%s\n", desc, fname, typedef, tags))
		}
		WriteTabs(&buffer, tabs)
		buffer.WriteString("}")
		return buffer.String()
	case *design.UserTypeDefinition:
		return GoPackageTypeName(actual, actual.AllRequired(), versioned, defPkg, tabs)
	case *design.MediaTypeDefinition:
		return GoPackageTypeName(actual, actual.AllRequired(), versioned, defPkg, tabs)
	default:
		panic("goa bug: unknown data structure type")
	}
	return GoTypeDef(ds, versioned, defPkg, tabs, jsonTags)
}