-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathir_server.go
120 lines (98 loc) · 3.76 KB
/
ir_server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package hellososp
import (
"fmt"
"log/slog"
"path/filepath"
"reflect"
"github.com/blueprint-uservices/blueprint/blueprint/pkg/blueprint"
"github.com/blueprint-uservices/blueprint/blueprint/pkg/coreplugins/service"
"github.com/blueprint-uservices/blueprint/blueprint/pkg/ir"
"github.com/blueprint-uservices/blueprint/plugins/golang"
"github.com/blueprint-uservices/blueprint/plugins/golang/gocode"
"github.com/blueprint-uservices/blueprint/plugins/golang/gogen"
)
// Blueprint IRNode for representing the wrapper node that instruments every server-side method in the node that gets wrapped
type HelloInstrumentServerWrapper struct {
golang.Service
golang.GeneratesFuncs
golang.Instantiable
InstanceName string
Wrapped golang.Service
outputPackage string
}
// Implements ir.IRNode
func (node *HelloInstrumentServerWrapper) ImplementsGolangNode() {}
// Implements ir.IRNode
func (node *HelloInstrumentServerWrapper) Name() string {
return node.InstanceName
}
// Implements ir.IRNode
func (node *HelloInstrumentServerWrapper) String() string {
return node.Name() + " = HelloInstrumentServerWrapper(" + node.Wrapped.Name() + ")"
}
// Implements golang.ProvidesInterface
func (node *HelloInstrumentServerWrapper) AddInterfaces(builder golang.ModuleBuilder) error {
return node.Wrapped.AddInterfaces(builder)
}
func newHelloInstrumentServerWrapper(name string, server ir.IRNode) (*HelloInstrumentServerWrapper, error) {
serverNode, ok := server.(golang.Service)
if !ok {
return nil, blueprint.Errorf("tutorial server wrapper requires %s to be a golang service but got %s", server.Name(), reflect.TypeOf(server).String())
}
node := &HelloInstrumentServerWrapper{}
node.InstanceName = name
node.Wrapped = serverNode
node.outputPackage = "sosp"
return node, nil
}
// Implements service.ServiceNode
func (node *HelloInstrumentServerWrapper) GetInterface(ctx ir.BuildContext) (service.ServiceInterface, error) {
return node.Wrapped.GetInterface(ctx)
}
// Implements golang.GeneratesFuncs
func (node *HelloInstrumentServerWrapper) GenerateFuncs(builder golang.ModuleBuilder) error {
iface, err := golang.GetGoInterface(builder, node)
if err != nil {
return err
}
return generateServerInstrumentHandler(builder, iface, node.outputPackage)
}
// Implements golang.Instantiable
func (node *HelloInstrumentServerWrapper) AddInstantiation(builder golang.NamespaceBuilder) error {
if builder.Visited(node.InstanceName) {
return nil
}
iface, err := golang.GetGoInterface(builder, node.Wrapped)
if err != nil {
return err
}
constructor := &gocode.Constructor{
Package: builder.Module().Info().Name + "/" + node.outputPackage,
Func: gocode.Func{
Name: fmt.Sprintf("New_%v_TutorialInstrumentServerWrapper", iface.BaseName),
Arguments: []gocode.Variable{
{Name: "ctx", Type: &gocode.UserType{Package: "context", Name: "Context"}},
{Name: "service", Type: iface},
},
},
}
return builder.DeclareConstructor(node.InstanceName, constructor, []ir.IRNode{node.Wrapped})
}
func generateServerInstrumentHandler(builder golang.ModuleBuilder, wrapped *gocode.ServiceInterface, outputPackage string) error {
pkg, err := builder.CreatePackage(outputPackage)
if err != nil {
return err
}
server := &templateArgs{
Package: pkg,
Service: wrapped,
Iface: wrapped,
Name: wrapped.BaseName + "_TutorialInstrumentServerWrapper",
IfaceName: wrapped.Name,
Imports: gogen.NewImports(pkg.Name),
}
server.Imports.AddPackages("context", "log")
slog.Info(fmt.Sprintf("Generating %v/%v", server.Package.PackageName, wrapped.BaseName+"_TutorialInstrumentServerWrapper"))
outputFile := filepath.Join(server.Package.Path, wrapped.BaseName+"_TutorialInstrumentServerWrapper.go")
return gogen.ExecuteTemplateToFile("Tutorial", serverInstrumentTemplate, server, outputFile)
}