in codegen/gateway.go [608:673]
func resolveHeaderModels(ms *ModuleSpec, modelPath string) (map[string]*TypedHeader, error) {
const (
headerPreix = "headers"
httpRefSuffix = "http.ref"
)
loadModuleFromInclude := func(moduleName string) *compile.Module {
for pkgKey, pkg := range ms.CompiledModule.Includes {
if pkgKey == moduleName {
return pkg.Module
}
}
return nil
}
loadHeaderKeyFromField := func(field *compile.FieldSpec) *string {
for ak, av := range field.Annotations {
if avs := strings.Split(av, "."); len(avs) == 2 &&
avs[0] == headerPreix &&
strings.HasSuffix(ak, httpRefSuffix) {
headerKey := avs[1]
return &headerKey
}
}
return nil
}
loadHeadersFromCompiledModule := func(module *compile.Module, structName string) (map[string]*TypedHeader, error) {
var typeStruct *compile.StructSpec
var typedHeaders = make(map[string]*TypedHeader)
for tk, tv := range module.Types {
if ts, ok := tv.(*compile.StructSpec); tk == structName && ok {
typeStruct = ts
break
}
}
if typeStruct == nil {
return nil, errors.Errorf("unable to find typedHeaders %q", structName)
}
for _, field := range typeStruct.Fields {
hk := loadHeaderKeyFromField(field)
if hk == nil {
return nil, errors.Errorf("unable to find header key %q", field.Name)
}
headerKey := textproto.CanonicalMIMEHeaderKey(*hk)
typedHeaders[headerKey] = &TypedHeader{
Name: headerKey,
TransformTo: headerKey,
Field: field,
}
}
return typedHeaders, nil
}
switch paths := strings.Split(modelPath, "."); len(paths) {
case 2:
moduleName := paths[0]
structName := paths[1]
module := loadModuleFromInclude(moduleName)
if module == nil {
return nil, errors.Errorf("missing module spec %q", moduleName)
}
return loadHeadersFromCompiledModule(module, structName)
default:
// TODO case 1:
// default header schema path to .
return nil, errors.Errorf(
"malformed header model %q, expecting <module>.<struct>", modelPath)
}
}