in codegen/method.go [580:730]
func (ms *MethodSpec) setEndpointRequestHeaderFields(
funcSpec *compile.FunctionSpec, packageHelper *PackageHelper,
) error {
fields := compile.FieldGroup(funcSpec.ArgsSpec)
// ms.ReqHeaderFields = map[string]HeaderFieldInfo{}
statements := LineBuilder{}
var finalError error
var seenHeaders bool
var headersMap = map[string]int{}
var seenOptStructs = map[string]string{}
// Scan for all annotations
visitor := func(
goPrefix string, thriftPrefix string, field *compile.FieldSpec,
) bool {
realType := compile.RootTypeSpec(field.Type)
longFieldName := goPrefix + "." + PascalCase(field.Name)
// If the type is a struct then we cannot really do anything
if _, ok := realType.(*compile.StructSpec); ok {
// if a field is a struct then we must do a nil check
typeName, err := GoType(packageHelper, realType)
if err != nil {
finalError = err
return true
}
if field.Required {
statements.appendf("if requestBody%s == nil {", longFieldName)
statements.appendf("\trequestBody%s = &%s{}",
longFieldName, typeName,
)
statements.append("}")
} else {
seenOptStructs[longFieldName] = typeName
}
return false
}
if param, ok := field.Annotations[ms.annotations.HTTPRef]; ok {
if strings.HasPrefix(param, headerAnnotationPrefix) {
headerName := strings.TrimPrefix(param, headerAnnotationPrefix)
camelHeaderName := CamelCase(headerName)
fieldThriftType, err := GoType(packageHelper, field.Type)
if err != nil {
finalError = err
return true
}
bodyIdentifier := goPrefix + "." + PascalCase(field.Name)
seenCount := headersMap[camelHeaderName]
var variableName string
if seenCount > 0 {
variableName = camelHeaderName + "No" +
strconv.Itoa(seenCount) + "Value"
} else {
variableName = camelHeaderName + "Value"
}
headersMap[camelHeaderName] = seenCount + 1
if field.Required {
statements.appendf("%s, _ := req.Header.Get(%q)",
variableName, headerName,
)
for seenStruct, typeName := range seenOptStructs {
if strings.HasPrefix(longFieldName, seenStruct) {
statements.appendf("if requestBody%s == nil {",
seenStruct,
)
statements.appendf("\trequestBody%s = &%s{}",
seenStruct, typeName,
)
statements.append("}")
}
}
statements.appendf("requestBody%s = %s(%s)",
bodyIdentifier, fieldThriftType, variableName,
)
} else {
statements.appendf("%s, %sExists := req.Header.Get(%q)",
variableName, variableName, headerName,
)
statements.appendf("if %sExists {", variableName)
for seenStruct, typeName := range seenOptStructs {
if strings.HasPrefix(longFieldName, seenStruct) {
statements.appendf("\tif requestBody%s == nil {",
seenStruct,
)
statements.appendf("\t\trequestBody%s = &%s{}",
seenStruct, typeName,
)
statements.append("\t}")
}
}
switch fieldThriftType {
case "string":
statements.appendf("\trequestBody%s = ptr.String(%s)",
bodyIdentifier, variableName,
)
case "int64":
statements.appendf("body, _ := strconv.ParseInt(%s, 10, 64)",
variableName,
)
statements.appendf("requestBody%s = &body", bodyIdentifier)
case "bool":
statements.appendf("body, _ := strconv.ParseBool(%s)",
variableName,
)
statements.appendf("requestBody%s = &body", bodyIdentifier)
case "float64":
case "float32":
statements.appendf("body, _ := strconv.ParseFloat(%s, 64)",
variableName,
)
statements.appendf("requestBody%s = &body", bodyIdentifier)
default:
statements.appendf("body := %s(%s)",
fieldThriftType, variableName,
)
statements.appendf("requestBody%s = &body", bodyIdentifier)
}
statements.append("}")
}
seenHeaders = true
}
}
return false
}
walkFieldGroups(fields, visitor)
if finalError != nil {
return finalError
}
if seenHeaders {
ms.ReqHeaderGoStatements = statements.GetLines()
}
return nil
}