in types/types.go [222:262]
func (types TypeMap) InlineTypes(propagateReference func(original *Type, additional *Type)) {
// If C is inlined in B, and B is inlined in A; the fields of C are copied
// into B before the fields of B is copied into A. The ideal order of
// iterating and inlining fields is NOT known. Worst-case, only one type's
// fields are inlined in its parent type in each iteration.
maxDepth := 100
var numTypesToBeInlined int
for iteration := 0; iteration < maxDepth; iteration++ {
numTypesToBeInlined = 0
for _, t := range types {
// By iterating backwards, it is safe to delete field at current index
// and copy the fields of the inlined type.
for i := len(t.Fields) - 1; i >= 0; i-- {
if !t.Fields[i].Inlined {
continue
}
numTypesToBeInlined += 1
embeddedType, ok := types[t.Fields[i].Type.UID]
if !ok {
zap.S().Warnw("Unable to find embedded type", "type", t,
"embeddedType", t.Fields[i].Type)
continue
}
// Only inline type's fields if the inlined type itself has no
// types yet to be inlined.
if !embeddedType.ContainsInlinedTypes() {
zap.S().Debugw("Inlining embedded type", "type", t,
"embeddedType", t.Fields[i].Type)
t.Fields.inlineType(i, embeddedType)
propagateReference(embeddedType, t)
}
}
}
if numTypesToBeInlined == 0 {
return
}
}
zap.S().Warnw("Failed to inline all inlined types", "remaining", numTypesToBeInlined)
}