in tools/go-agent/instrument/plugins/enhance_method.go [143:217]
func (m *MethodEnhance) BuildForDelegator() []dst.Decl {
result := make([]dst.Decl, 0)
result = append(result, tools.GoStringToDecls(fmt.Sprintf(`var %s = &%s{}`, m.InterceptorVarName, m.InterceptorGeneratedName))...)
result = append(result, tools.GoStringToDecls(fmt.Sprintf(`var %s_interTimeCost int64`, m.FuncID))...)
result = append(result, tools.GoStringToDecls(fmt.Sprintf(`var %s_beforeInterStart int64`, m.FuncID))...)
preFunc := &dst.FuncDecl{
Name: &dst.Ident{Name: m.AdapterPreFuncName},
Type: &dst.FuncType{
Params: &dst.FieldList{},
Results: &dst.FieldList{},
},
}
for i, recv := range m.Recvs {
preFunc.Type.Params.List = append(preFunc.Type.Params.List, &dst.Field{
Names: []*dst.Ident{dst.NewIdent(fmt.Sprintf("recv_%d", i))},
Type: &dst.StarExpr{X: recv.PackagedType()},
})
}
for i, parameter := range m.Parameters {
preFunc.Type.Params.List = append(preFunc.Type.Params.List, &dst.Field{
Names: []*dst.Ident{dst.NewIdent(fmt.Sprintf("param_%d", i))},
Type: &dst.StarExpr{X: m.changeTypeIfNeeds(parameter.PackagedType())},
})
}
for i, result := range m.Results {
preFunc.Type.Results.List = append(preFunc.Type.Results.List, &dst.Field{
Names: []*dst.Ident{dst.NewIdent(fmt.Sprintf("ret_%d", i))},
Type: result.PackagedType(),
})
}
preFunc.Type.Results.List = append(preFunc.Type.Results.List, &dst.Field{
Names: []*dst.Ident{dst.NewIdent("invocation")},
Type: &dst.StarExpr{X: &dst.SelectorExpr{X: dst.NewIdent("operator"), Sel: dst.NewIdent("realInvocation")}},
}, &dst.Field{
Names: []*dst.Ident{dst.NewIdent("skip")},
Type: dst.NewIdent("bool"),
})
beforeFile, err := templatesFS.ReadFile("templates/method_intercept_before.tmpl")
if err != nil {
panic(fmt.Errorf("reading method before intercept template failure: %w", err))
}
preFunc.Body = &dst.BlockStmt{
List: tools.GoStringToStats(tools.ExecuteTemplate(string(beforeFile), m)),
}
result = append(result, preFunc)
postFunc := &dst.FuncDecl{
Name: &dst.Ident{Name: m.AdapterPostFuncName},
Type: &dst.FuncType{
Params: &dst.FieldList{},
Results: &dst.FieldList{},
},
}
postFunc.Type.Params.List = append(postFunc.Type.Params.List, &dst.Field{
Names: []*dst.Ident{dst.NewIdent("invocation")},
Type: &dst.StarExpr{X: &dst.SelectorExpr{X: dst.NewIdent("operator"), Sel: dst.NewIdent("realInvocation")}},
})
for inx, f := range m.Results {
postFunc.Type.Params.List = append(postFunc.Type.Params.List, &dst.Field{
Names: []*dst.Ident{dst.NewIdent(fmt.Sprintf("ret_%d", inx))},
Type: &dst.StarExpr{X: f.PackagedType()},
})
}
afterFile, err := templatesFS.ReadFile("templates/method_intercept_after.tmpl")
if err != nil {
panic(fmt.Errorf("reading method after intercept template failure: %w", err))
}
postFunc.Body = &dst.BlockStmt{
List: tools.GoStringToStats(tools.ExecuteTemplate(string(afterFile), m)),
}
result = append(result, postFunc)
return result
}