You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: hw.go
    path of file: ./repos/learning_tools/grpc/protoc-gen-hw/plugin/hw
    
    the code of the file until where you have to start completion: package hw

import (
	"fmt"
	pb "github.com/golang/protobuf/protoc-gen-go/descriptor"
	"path"
	"protoc-gen-hw/generator"
	"strconv"
	"strings"
)

const (
	msgPkgPath     = "git.huoys.com/kit/gomsg/pkg"
	contextPkgPath = "context"
	serverPkgPath  = "git.huoys.com/kit/gomsg/pkg/ws/server"
)

type Hw struct {
	gen *generator.Generator
}

func (g *Hw) Name() string {
	return "hw"
}

var (
	msgPkg     string
	contextPkg string
	serverPkg  string
	pkgImports map[generator.GoPackageName]bool
)

func (g *Hw) Ini
    
func (g *Hw) generateService(file *generator.FileDescriptor, service *pb.ServiceDescriptorProto, index int) {
	path := fmt.Sprintf("6,%d", index) // 6 means service.
	origServName := service.GetName()
	/*serviceName := strings.ToLower(service.GetName())
	if pkg := file.GetPackage(); pkg != "" {
		serviceName = pkg
	}*/
	servName := generator.CamelCase(origServName)
	servAlias := servName + "Server"
	servWsAlias := servName + "WsServer"

	// strip suffix
	if strings.HasSuffix(servAlias, "ServerServer") {
		servAlias = strings.TrimSuffix(servAlias, "Server")
	}
	// Client interface.
	g.P("type ", servWsAlias, " interface {")
	for i, method := range service.Method {
		g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service.
		g.P("StartNotify(ws *server.Server)")
		g.P(g.generateClientSignature(method))
	}
	g.P("}")
	g.P()
	g.P("var srv ", servAlias)
	g.P("type shandler struct {")
	g.P("closeChan chan string")
	g.P("}")
	g.P()
	g.P("func (h *shandler) OnOpen(p pkg.Session) {}")
	g.P("func (h *shandler) OnClose(p pkg.Session, b bool) {")
	g.P("h.closeChan <- fmt.Sprint(p.ID())")
	g.P("}")
	g.P()
	g.P("func (h *shandler) OnReq(pk pkg.Session, data []byte) pkg.IRet {")
	g.P("var (\n\t\tpb  Message\n\t\tctx = context.WithValue(context.Background(), \"id\", pk.ID())\n\t)\n\terr := proto.Unmarshal(data, &pb)\n\tif err != nil {\n\t\treturn nil\n\t}\n\tswitch pb.Ops {")
	for i, method := range service.Method {
		g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i))
		g.generateWsHandler(method)
	}
	g.P("default:\n\t\treturn pkg.Error(int16(pkg.NoHandler), \"not implemented\")\n\t}")
	g.P("}")
	g.P()
	g.P("func (h *shandler) OnPush(pk pkg.Session, data []byte) pkg.IRet {")
	g.P("return pkg.Ok(nil)")
	g.P("}")
	g.P()
	g.P("func RegisterDemoWsServer(e *server.Server, addr string, closeChan chan string, s ", servAlias, ") error {")
	g.P("srv = s")
	g.P("return e.ListenAndServe(addr, &shandler{closeChan: closeChan})")
	g.P("}")
	g.P()
}