1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-24 20:52:22 +00:00

Merge branch 'master' of github.com:chai2010/advanced-go-programming-book

This commit is contained in:
Xargin 2018-08-01 13:16:14 +08:00
commit 7635cd7a64

View File

@ -168,7 +168,7 @@ func init() {
}
```
因为Go语言的包只能静态导入我们无法向已经安装的protoc-gen-go添加我们新编写的插件。我们将重新克隆protoc-gen-go对应main函数
因为Go语言的包只能静态导入我们无法向已经安装的protoc-gen-go添加我们新编写的插件。我们将重新克隆protoc-gen-go对应main函数
```go
package main
@ -232,7 +232,7 @@ $ protoc --go-netrpc_out=plugins=netrpc:. hello.proto
## 自动生成完整的RPC代码
在前面的例子中我们已经构了最小化的netrpcPlugin插件并且通过克隆protoc-gen-go的主程序创建了新的protoc-gen-go-netrpc的插件程序。现在开始继续完善netrpcPlugin插件最终目标是生成RPC安全接口。
在前面的例子中我们已经构了最小化的netrpcPlugin插件并且通过克隆protoc-gen-go的主程序创建了新的protoc-gen-go-netrpc的插件程序。现在开始继续完善netrpcPlugin插件最终目标是生成RPC安全接口。
首先是自定义的genImportCode方法中生成导入包的代码
@ -279,24 +279,22 @@ func (p *netrpcPlugin) buildServiceSpec(svc *descriptor.ServiceDescriptorProto)
}
```
其中输入参数是`*descriptor.ServiceDescriptorProto`类型,完整描述了一个服务的所有信息。然后通过`svc.GetName()`就可以获取Protobuf文件中定义对服务对名字。Protobuf文件中的名字转为Go语言对名字后,需要通过`generator.CamelCase`函数进行一次转换。类似的在for循环中我们通过`m.GetName()`获取方法的名字然后再转为Go语言中对应的名字。比较复杂的是对输入和输出参数名字的解析首先需要通过`m.GetInputType()`获取输入参数的类型,然后通过`p.ObjectNamed`类型对应的类对象信息,最后获取类对象的名字。
其中输入参数是`*descriptor.ServiceDescriptorProto`类型,完整描述了一个服务的所有信息。然后通过`svc.GetName()`就可以获取Protobuf文件中定义的服务的名字。Protobuf文件中的名字转为Go语言的名字后,需要通过`generator.CamelCase`函数进行一次转换。类似的在for循环中我们通过`m.GetName()`获取方法的名字然后再转为Go语言中对应的名字。比较复杂的是对输入和输出参数名字的解析首先需要通过`m.GetInputType()`获取输入参数的类型,然后通过`p.ObjectNamed`获取类型对应的类对象信息,最后获取类对象的名字。
然后我们就可以基于buildServiceSpec方法构造的服务的元信息生成服务的代码
```go
func (p *netrpcPlugin) genServiceCode(svc *descriptor.ServiceDescriptorProto) {
for _, svc := range file.Service {
spec := p.buildServiceSpec(svc)
spec := p.buildServiceSpec(svc)
var buf bytes.Buffer
t := template.Must(template.New("").Parse(tmplService))
err := t.Execute(&buf, spec)
if err != nil {
log.Fatal(err)
}
p.P(buf.String())
var buf bytes.Buffer
t := template.Must(template.New("").Parse(tmplService))
err := t.Execute(&buf, spec)
if err != nil {
log.Fatal(err)
}
p.P(buf.String())
}
```