in internal/build/cmd/generate/commands/gensource/generator.go [484:821]
func (r ` + g.Endpoint.MethodWithNamespace() + `Request) Do(ctx context.Context, transport Transport) (*Response, error) {
var (
method string
path strings.Builder
params map[string]string
)` + "\n\n")
switch g.Endpoint.Name {
case "index":
g.w("\t")
g.w(`if r.DocumentID != "" {
method = "PUT"
} else {
method = "POST"
}`)
g.w("\n\n")
default:
var httpMethod string
// If endpoint has both GET and POST available
// Prefer POST usage in order to prevent go routine leak
// See https://github.com/golang/go/issues/29246
if g.Endpoint.URL.ContainsMethods("GET", "POST") {
httpMethod = "POST"
} else {
httpMethod = g.Endpoint.URL.Paths[0].Methods[0]
}
g.w("\t" + `method = "` + httpMethod + `"` + "\n\n")
}
// Get default part values for specific APIs
// TODO: Move to overrides
var defparts bool
switch g.Endpoint.Name {
case "index", "create", "delete", "explain", "exists", "get", "get_source", "update", "termvectors":
for _, p := range g.Endpoint.URL.AllParts {
if p.Default != nil {
var fieldName string
var fieldValue string
var fieldCondition string
fieldName = p.GoName()
switch p.Type {
case "string", "enum":
fieldCondition = `r.` + fieldName + ` == ""`
fieldValue = `"` + p.Default.(string) + `"`
case "number":
fieldCondition = `r.` + fieldName + ` == 0`
fieldValue = p.Default.(string)
case "list":
fieldCondition = ` len(r.` + fieldName + `) < 1`
fieldValue = `[]string{"` + p.Default.(string) + `"}`
default:
panic(fmt.Sprintf("FAIL: %q: unexpected parameter type %q for URL part %q", g.Endpoint.Name, p.Type, p.Name))
}
g.w("\t")
g.w(`if ` + fieldCondition + ` {
r.` + fieldName + ` = ` + fieldValue + `
}` + "\n")
defparts = true
}
}
}
if defparts {
g.w("\n")
}
// Generate the URL path
//
if f := g.GetOverride("url", g.Endpoint.Name); f != nil {
g.w(f(g.Endpoint))
} else {
var (
pathGrow strings.Builder
pathContent strings.Builder
)
pathGrow.WriteString(` path.Grow(`)
// FIXME: Select longest path based on number of template entries, not string length
longestPath := g.Endpoint.URL.Paths[0]
for _, v := range g.Endpoint.URL.Paths {
if len(v.Path) > len(longestPath.Path) {
longestPath = v
}
}
if len(longestPath.Parts) < 1 {
if len(g.Endpoint.URL.Paths) < 1 {
panic(fmt.Sprintf("FAIL: %q: empty endpoint\n", g.Endpoint.Name))
}
pathGrow.WriteString(`len("` + longestPath.Path + `")`)
pathContent.WriteString(` path.WriteString("` + longestPath.Path + `")` + "\n")
} else {
pathParts := make([]string, 0)
apiArgs := g.Endpoint.RequiredArguments()
for _, v := range strings.Split(longestPath.Path, "/") {
if v != "" {
pathParts = append(pathParts, v)
}
}
r := strings.NewReplacer("{", "", "}", "")
for _, v := range pathParts {
var p string
// Required arguments
for _, a := range apiArgs {
if strings.HasPrefix(v, "{") && a.Name == r.Replace(v) {
p = a.GoName()
pathGrow.WriteString(`1 + `)
pathContent.WriteString(` path.WriteString("/")` + "\n")
switch a.Type {
case "string":
pathGrow.WriteString(`len(r.` + p + `) + `)
pathContent.WriteString(` path.WriteString(r.` + p + `)` + "\n")
case "list":
pathGrow.WriteString(`len(strings.Join(r.` + p + `, ",")) + `)
pathContent.WriteString(` path.WriteString(strings.Join(r.` + p + `, ","))` + "\n")
default:
panic(fmt.Sprintf("FAIL: %q: unexpected type %q for URL part %q\n", g.Endpoint.Name, a.Type, a.Name))
}
break
}
}
// Optional arguments
if p == "" {
for _, a := range longestPath.Parts {
// fmt.Printf("a: %+v\n", a)
if strings.HasPrefix(v, "{") && a.Name == r.Replace(v) {
p = a.GoName()
switch a.Type {
case "string":
pathGrow.WriteString(`1 + len(r.` + p + `) + `)
pathContent.WriteString(` if r.` + p + ` != "" {` + "\n")
pathContent.WriteString(` path.WriteString("/")` + "\n")
pathContent.WriteString(` path.WriteString(r.` + p + `)` + "\n")
pathContent.WriteString(` }` + "\n")
case "list":
pathGrow.WriteString(`1 + len(strings.Join(r.` + p + `, ",")) + `)
pathContent.WriteString(` if len(r.` + p + `) > 0 {` + "\n")
pathContent.WriteString(` path.WriteString("/")` + "\n")
pathContent.WriteString(` path.WriteString(strings.Join(r.` + p + `, ","))` + "\n")
pathContent.WriteString(` }` + "\n")
case "int", "long":
pathContent.WriteString(` if r.` + p + ` != nil {` + "\n")
pathContent.WriteString(` value := strconv.FormatInt(int64(*r.` + p + `), 10)` + "\n")
pathContent.WriteString(` path.Grow(1 + len(value))` + "\n")
pathContent.WriteString(` path.WriteString("/")` + "\n")
pathContent.WriteString(` path.WriteString(value)` + "\n")
pathContent.WriteString(` }` + "\n")
default:
panic(fmt.Sprintf("FAIL: %q: unexpected type %q for URL part %q\n", g.Endpoint.Name, a.Type, a.Name))
}
break
}
}
}
// Optional arguments
if p == "" {
for _, a := range g.Endpoint.URL.Params {
if strings.HasPrefix(v, "{") && a.Name == r.Replace(v) {
p = a.GoName()
pathGrow.WriteString("1 +")
pathContent.WriteString(` path.WriteString("/")` + "\n")
switch a.Type {
case "string":
pathGrow.WriteString(`len(r.` + p + `)`)
pathContent.WriteString(` path.WriteString(r.` + p + `)` + "\n")
case "list":
pathGrow.WriteString(`len(strings.Join(r.` + p + `, ","))`)
pathContent.WriteString(` path.WriteString(strings.Join(r.` + p + `, ","))` + "\n")
default:
panic(fmt.Sprintf("FAIL: %q: unexpected type %q for URL param %q\n", g.Endpoint.Name, a.Type, a.Name))
}
break
}
}
}
// Static parts
if p == "" {
pathGrow.WriteString(`1 + len("` + v + `") + `)
pathContent.WriteString(` path.WriteString("/")` + "\n")
pathContent.WriteString(` path.WriteString("` + v + `")` + "\n")
}
}
}
// Write out the content
pathGrow.WriteString(`)`)
g.w(strings.Replace(pathGrow.String(), " + )", ")", 1) + "\n")
g.w(pathContent.String() + "\n")
}
// Generate the URL params
g.w(`
params = make(map[string]string)` + "\n")
for _, n := range g.Endpoint.URL.ParamNamesSorted {
if p, ok := g.Endpoint.URL.Params[n]; ok {
var (
fieldName string
fieldType string
fieldValue string
fieldCondition string
)
fieldName = p.GoName()
fieldType = p.GoType()
switch fieldType {
case "bool":
fieldCondition = `r.` + fieldName
fieldValue = `strconv.FormatBool(r.` + fieldName + `)`
case "*bool":
fieldCondition = `r.` + fieldName + ` != nil`
fieldValue = `strconv.FormatBool(*r.` + fieldName + `)`
case "string":
fieldCondition = `r.` + fieldName + ` != ""`
fieldValue = `r.` + fieldName
case "int":
fieldCondition = `r.` + fieldName + ` != 0`
fieldValue = `strconv.FormatInt(int64(r.` + fieldName + `), 10)`
case "*int":
fieldCondition = `r.` + fieldName + ` != nil`
fieldValue = `strconv.FormatInt(int64(*r.` + fieldName + `), 10)`
case "uint":
fieldCondition = `r.` + fieldName + ` != 0`
fieldValue = `strconv.FormatUint(uint64(r.` + fieldName + `), 10)`
case "*uint":
fieldCondition = `r.` + fieldName + ` != 0`
fieldValue = `strconv.FormatUint(uint64(*r.` + fieldName + `), 10)`
case "[]string":
fieldCondition = ` len(r.` + fieldName + `) > 0`
fieldValue = `strings.Join(r.` + fieldName + `, ",")`
case "time.Duration":
fieldCondition = `r.` + fieldName + ` != 0`
fieldValue = `formatDuration(r.` + fieldName + `)`
default: // interface{}
fieldCondition = `r.` + fieldName + ` != nil`
// TODO: Use type switching instead?
fieldValue = `fmt.Sprintf("%v", r.` + fieldName + `)`
}
g.w(`
if ` + fieldCondition + ` {
params["` + p.Name + `"] = ` + fieldValue + `
}` + "\n")
} else {
panic(fmt.Sprintf("FAIL: %q: Unknown parameter %q in URL parameters", g.Endpoint.Name, n))
}
}
// Common parameters
g.w(`
if r.Pretty {
params["pretty"] = "true"
}
if r.Human {
params["human"] = "true"
}
if r.ErrorTrace {
params["error_trace"] = "true"
}
if len(r.FilterPath) > 0 {
params["filter_path"] = strings.Join(r.FilterPath, ",")
}
`)
g.w("\n\n")
// Generate the HTTP request options
var httpBody string
if g.Endpoint.Body != nil {
httpBody = "r.Body"
} else {
httpBody = "nil"
}
g.w(`req, err := newRequest(method, path.String(), ` + httpBody + `)` + "\n")
g.w(`if err != nil {
return nil, err
}` + "\n\n")
g.w(`if len(params) > 0 {
q := req.URL.Query()
for k, v := range params {
q.Set(k, v)
}
req.URL.RawQuery = q.Encode()
}` + "\n\n")
if g.Endpoint.Body != nil {
g.w(`if r.Body != nil {
req.Header[headerContentType] = headerContentTypeJSON
}` + "\n\n")
}
g.w(`if len(r.Header) > 0 {
if len(req.Header) == 0 {
req.Header = r.Header
} else {
for k, vv := range r.Header {
for _, v := range vv {
req.Header.Add(k, v)
}
}
}
}` + "\n\n")
g.w(`if ctx != nil {
req = req.WithContext(ctx)
}` + "\n\n")
g.w(`
res, err := transport.Perform(req)
if err != nil {
return nil, err
}` + "\n\n")
// Generate the return value
g.w(`
response := Response{
StatusCode: res.StatusCode,
Body: res.Body,
Header: res.Header,
}` + "\n")
g.w("\n\treturn &response, nil\n")
g.w("}\n")
}