func annotate(registry rdl.TypeRegistry, typename rdl.TypeRef) string { t := registry.FindType(typename) if t != nil { tName, tType, _ := rdl.TypeInfo(t) if tType != rdl.TypeRef(tName) { return "[" + string(typename) + "](#" + strings.ToLower(string(typename)) + ")" } } return string(typename) }
func (gen *modelGenerator) emitType(t *rdl.Type) { if gen.err == nil { tName, _, _ := rdl.TypeInfo(t) if strings.HasPrefix(string(tName), "rdl.") { return } tName = rdl.TypeName(goTypeName(tName)) bt := gen.registry.BaseType(t) switch bt { case rdl.BaseTypeAny: gen.emit("\n") gen.emitTypeComment(t) gen.emit(fmt.Sprintf("type %s interface{}\n", tName)) case rdl.BaseTypeString, rdl.BaseTypeBool, rdl.BaseTypeInt8, rdl.BaseTypeInt16, rdl.BaseTypeInt32, rdl.BaseTypeInt64, rdl.BaseTypeFloat32, rdl.BaseTypeFloat64, rdl.BaseTypeSymbol: if gen.precise { gen.emit("\n") gen.emitTypeComment(t) gen.emit(fmt.Sprintf("type %s %s\n", tName, goType(gen.registry, rdl.TypeRef(bt.String()), false, "", "", gen.precise, false))) } case rdl.BaseTypeStruct: gen.emit("\n") gen.emitStruct(t) case rdl.BaseTypeUnion: gen.emit("\n") gen.emitUnion(t) case rdl.BaseTypeArray: gen.emit("\n") gen.emitArray(t) case rdl.BaseTypeMap: gen.emit("\n") gen.emitMap(t) case rdl.BaseTypeEnum: gen.emit("\n") gen.emitTypeComment(t) gen.emitEnum(t) } } }
func javaType(reg rdl.TypeRegistry, rdlType rdl.TypeRef, optional bool, items rdl.TypeRef, keys rdl.TypeRef) string { t := reg.FindType(rdlType) if t == nil || t.Variant == 0 { panic("Cannot find type '" + rdlType + "'") } bt := reg.BaseType(t) switch bt { case rdl.BaseTypeAny: return "Object" case rdl.BaseTypeString: return "String" case rdl.BaseTypeSymbol, rdl.BaseTypeTimestamp, rdl.BaseTypeUUID: return string(rdlType) case rdl.BaseTypeBool: if optional { return "Boolean" } return "boolean" case rdl.BaseTypeInt8: if optional { return "Byte" } return "byte" case rdl.BaseTypeInt16: if optional { return "Short" } return "short" case rdl.BaseTypeInt32: if optional { return "Integer" } return "int" case rdl.BaseTypeInt64: if optional { return "Long" } return "long" case rdl.BaseTypeFloat32: if optional { return "Float" } return "float" case rdl.BaseTypeFloat64: if optional { return "Double" } return "double" case rdl.BaseTypeArray: i := rdl.TypeRef("Any") switch t.Variant { case rdl.TypeVariantArrayTypeDef: i = t.ArrayTypeDef.Items default: if items != "" && items != "Any" { i = items } } gitems := javaType(reg, rdl.TypeRef(i), false, "", "") //return gitems + "[]" //if arrays, not lists return "List<" + gitems + ">" case rdl.BaseTypeMap: k := rdl.TypeRef("Any") i := rdl.TypeRef("Any") switch t.Variant { case rdl.TypeVariantMapTypeDef: k = t.MapTypeDef.Keys i = t.MapTypeDef.Items default: if keys != "" && keys != "Any" { k = keys } if items != "" && items != "Any" { i = items } } gkeys := javaType(reg, k, false, "", "") gitems := javaType(reg, i, false, "", "") return "Map<" + gkeys + ", " + gitems + ">" case rdl.BaseTypeStruct: if strings.HasPrefix(string(rdlType), "rdl.") { return string(rdlType)[4:] } switch t.Variant { case rdl.TypeVariantStructTypeDef: if t.StructTypeDef.Name == "Struct" { return "Object" } } return string(rdlType) default: return string(rdlType) } }
func goType(reg rdl.TypeRegistry, rdlType rdl.TypeRef, optional bool, items rdl.TypeRef, keys rdl.TypeRef, precise bool, reference bool) string { rdlPrefix := "rdl." if reg.Name() == "rdl" { rdlPrefix = "" } cleanType := string(rdlType) if !strings.HasPrefix(cleanType, "rdl.") { cleanType = capitalize(strings.Replace(string(rdlType), ".", "_", -1)) } prefix := "" if optional { prefix = "*" } t := reg.FindType(rdlType) if t.Variant == 0 { panic("Cannot find type '" + rdlType + "'") } lrdlType := strings.ToLower(string(rdlType)) if precise { switch lrdlType { case "string": return "string" case "symbol": return rdlPrefix + "Symbol" case "bool", "int32", "int64", "int16", "int8", "float64", "float32": return prefix + strings.ToLower(cleanType) default: bt := reg.BaseType(t) switch bt { case rdl.BaseTypeString, rdl.BaseTypeSymbol: return cleanType case rdl.BaseTypeInt8, rdl.BaseTypeInt16, rdl.BaseTypeInt32, rdl.BaseTypeInt64, rdl.BaseTypeFloat32, rdl.BaseTypeFloat64, rdl.BaseTypeBool: return prefix + cleanType case rdl.BaseTypeTimestamp, rdl.BaseTypeUUID: fullTypeName := rdlPrefix + cleanType return prefix + fullTypeName default: if lrdlType == "struct" { fullTypeName := rdlPrefix + cleanType return prefix + fullTypeName } } } } else { switch lrdlType { case "timestamp": return prefix + rdlPrefix + "Timestamp" case "uuid": return prefix + rdlPrefix + "UUID" case "struct": return prefix + rdlPrefix + "Struct" } } bt := reg.BaseType(t) switch bt { case rdl.BaseTypeAny: return "interface{}" case rdl.BaseTypeString: return "string" case rdl.BaseTypeSymbol: return rdlPrefix + "Symbol" case rdl.BaseTypeBool: return prefix + "bool" case rdl.BaseTypeInt8, rdl.BaseTypeInt16, rdl.BaseTypeInt32, rdl.BaseTypeInt64, rdl.BaseTypeFloat32, rdl.BaseTypeFloat64: return prefix + strings.ToLower(bt.String()) case rdl.BaseTypeArray: if reference { name := "Array" if t.ArrayTypeDef != nil { name = string(t.ArrayTypeDef.Name) } if name != "Array" { return name } } i := rdl.TypeRef("Any") switch t.Variant { case rdl.TypeVariantArrayTypeDef: i = t.ArrayTypeDef.Items default: if items != "" { i = items } } gitems := goType(reg, i, false, "", "", precise, reference) return "[]" + gitems case rdl.BaseTypeMap: if reference { //we check if we have defined a type, i.e. the type name is not "Map" name := rdl.TypeName("Map") if t.MapTypeDef != nil { name = t.MapTypeDef.Name } else if t.AliasTypeDef != nil { name = t.AliasTypeDef.Name } if name != "Map" { return string(name) } } k := rdl.TypeRef("Any") i := rdl.TypeRef("Any") switch t.Variant { case rdl.TypeVariantMapTypeDef: k = t.MapTypeDef.Keys i = t.MapTypeDef.Items default: if keys != "" { k = keys } if items != "" { i = items } } gkeys := goType(reg, k, false, "", "", precise, reference) gitems := goType(reg, i, false, "", "", precise, reference) return "map[" + gkeys + "]" + gitems case rdl.BaseTypeStruct: switch t.Variant { case rdl.TypeVariantAliasTypeDef: if t.AliasTypeDef.Name == "Struct" { return prefix + "map[string]interface{}" } } return "*" + cleanType case rdl.BaseTypeUnion: return "*" + cleanType case rdl.BaseTypeEnum: return prefix + cleanType default: return prefix + cleanType } }
func formatResource(out io.Writer, registry rdl.TypeRegistry, rez *rdl.Resource) { fmt.Fprintf(out, "\n#### %s %s\n", strings.ToUpper(rez.Method), rez.Path) if rez.Comment != "" { fmt.Fprintf(out, "%s", formatBlock(rez.Comment, 0, 80, "")) } if len(rez.Inputs) > 0 { var rows [][]string for _, f := range rez.Inputs { fn := string(f.Name) ft := annotate(registry, f.Type) fs := "" if f.PathParam { fs = "path" } else if f.QueryParam != "" { fs = "query: " + f.QueryParam } else if f.Header != "" { fs = "header: " + f.Header // } else if f.Context != "" { // fs = "context: " + f.Context } else { fs = "body" } fo := "" if f.Optional { fo = "optional" } if f.Default != nil { s := optionalAnyToString(f.Default) if fo == "" { fo = "default=" + s } else { fo += ", default=" + s } } if f.Pattern != "" { if fo != "" { fo += ", " } fo += "pattern: " + f.Pattern } if f.Flag { if fo != "" { fo += ", " } fo += "flag" } fc := "" if f.Comment != "" { fc += f.Comment } row := []string{fn, ft, fs, fo, fc} rows = append(rows, row) } if rows != nil { fmt.Fprintf(out, "\n#### Request parameters:\n\n") formatTable(out, []string{"Name", "Type", "Source", "Options", "Description"}, rows) } } if len(rez.Outputs) > 0 { var rows [][]string for _, f := range rez.Outputs { fn := string(f.Name) ft := annotate(registry, f.Type) fd := "header: " + f.Header fo := "false" if f.Optional { fo = "true" } fc := "" if f.Comment != "" { fc = f.Comment } row := []string{fn, ft, fd, fo, fc} rows = append(rows, row) } if rows != nil { fmt.Fprintf(out, "\n#### Response parameters:\n\n") formatTable(out, []string{"Name", "Type", "Destination", "Optional", "Description"}, rows) } } fmt.Fprintf(out, "\n#### Responses:\n\n") var results [][]string if rez.Expected != "OK" { e := rez.Expected s := "" if e != "NO_CONTENT" { s = annotate(registry, rez.Type) } results = append(results, []string{rdl.StatusCode(e) + " " + rdl.StatusMessage(e), s}) } else { results = append(results, []string{"200 " + rdl.StatusMessage("OK"), string(rez.Type)}) } if len(rez.Alternatives) > 0 { for _, v := range rez.Alternatives { s := "" if v != "NO_CONTENT" { s = annotate(registry, rez.Type) } results = append(results, []string{rdl.StatusCode(v) + " " + rdl.StatusMessage(v), s}) } } fmt.Fprintf(out, "Expected:\n\n") formatTable(out, []string{"Code", "Type"}, results) if len(rez.Exceptions) > 0 { var rows [][]string for ec, edef := range rez.Exceptions { etype := edef.Type et := annotate(registry, rdl.TypeRef(etype)) ecomment := edef.Comment row := []string{rdl.StatusCode(ec) + " " + rdl.StatusMessage(ec), et, ecomment} rows = append(rows, row) } if rows != nil { sort.Sort(byCode(rows)) fmt.Fprintf(out, "\nException:\n\n") formatTable(out, []string{"Code", "Type", "Comment"}, rows) } } }