func()

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")
}