zoukankan      html  css  js  c++  java
  • tarsgo为protoc-gen-go添加tarsrpc插件

    tarsgo对Protobuf的支持是直接编写protoc-gen-go的插件,类似gRPC插件。
    我们下面就利用tarsgo写的tarsrpc这个插件,一步步生成protoc-gen-go

    首先我们引用《Go语言高级编程》中的介绍:
    Protobuf的protoc编译器是通过插件机制实现对不同语言的支持。比如protoc命令出现--xxx_out格式的参数,那么protoc将首先查询是否有内置的xxx插件,如果没有内置的xxx插件那么将继续查询当前系统中是否存在protoc-gen-xxx命名的可执行程序,最终通过查询到的插件生成代码。对于Go语言的protoc-gen-go插件来说,里面又实现了一层静态插件系统。比如protoc-gen-go内置了一个gRPC插件,用户可以通过--go_out=plugins=grpc参数来生成gRPC相关代码,否则只会针对message生成相关代码。

    参考gRPC插件的代码,可以发现generator.RegisterPlugin函数可以用来注册插件。插件是一个generator.Plugin接口:

    // A Plugin provides functionality to add to the output during
    // Go code generation, such as to produce RPC stubs.
    type Plugin interface {
        // Name identifies the plugin.
        Name() string
        // Init is called once after data structures are built but before
        // code generation begins.
        Init(g *Generator)
        // Generate produces the code generated by the plugin for this file,
        // except for the imports, by calling the generator's methods P, In,
        // and Out.
        Generate(file *FileDescriptor)
        // GenerateImports produces the import declarations for this file.
        // It is called after Generate.
        GenerateImports(file *FileDescriptor)
    }
    

    第一步,我们创建一个叫protoc-gen-go的项目

    第二步,goland打开,简单设置一下代理

    第三步,初始化项目

    go mod init protoc-gen-go
    

    第四步,复制tarsrpc这个插件,地址如下:

    https://github.com/TarsCloud/TarsGo/tree/master/tars/tools/pb2tarsgo/protoc-gen-go
    

    将下面的tarsrpc文件夹复制到proto这个目录中,并添加main.go文件

    第五步,安装https://github.com/golang/protobuf/ v1.3.5版本

    go get github.com/golang/protobuf@v1.3.5
    

    第六步,添加mian.go 引入tarsrpc

    // Go support for Protocol Buffers - Google's data interchange format
    //
    // Copyright 2010 The Go Authors.  All rights reserved.
    // https://github.com/golang/protobuf
    //
    // Redistribution and use in source and binary forms, with or without
    // modification, are permitted provided that the following conditions are
    // met:
    //
    //     * Redistributions of source code must retain the above copyright
    // notice, this list of conditions and the following disclaimer.
    //     * Redistributions in binary form must reproduce the above
    // copyright notice, this list of conditions and the following disclaimer
    // in the documentation and/or other materials provided with the
    // distribution.
    //     * Neither the name of Google Inc. nor the names of its
    // contributors may be used to endorse or promote products derived from
    // this software without specific prior written permission.
    //
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
    // protoc-gen-go is a plugin for the Google protocol buffer compiler to generate
    // Go code.  Run it by building this program and putting it in your path with
    // the name
    // 	protoc-gen-go
    // That word 'go' at the end becomes part of the option string set for the
    // protocol compiler, so once the protocol compiler (protoc) is installed
    // you can run
    // 	protoc --go_out=output_directory input_directory/file.proto
    // to generate Go bindings for the protocol defined by file.proto.
    // With that input, the output will be written to
    // 	output_directory/file.pb.go
    //
    // The generated code is documented in the package comment for
    // the library.
    //
    // See the README and documentation for protocol buffers to learn more:
    // 	https://developers.google.com/protocol-buffers/
    package main
    
    import (
    	"io/ioutil"
    	"os"
    
    	"github.com/golang/protobuf/proto"
    	"github.com/golang/protobuf/protoc-gen-go/generator"
    	_ "protoc-gen-go/tarsrpc"
    )
    
    func main() {
    	// Begin by allocating a generator. The request and response structures are stored there
    	// so we can do error handling easily - the response structure contains the field to
    	// report failure.
    	g := generator.New()
    
    	data, err := ioutil.ReadAll(os.Stdin)
    	if err != nil {
    		g.Error(err, "reading input")
    	}
    
    	if err := proto.Unmarshal(data, g.Request); err != nil {
    		g.Error(err, "parsing input proto")
    	}
    
    	if len(g.Request.FileToGenerate) == 0 {
    		g.Fail("no files to generate")
    	}
    
    	g.CommandLineParameters(g.Request.GetParameter())
    
    	// Create a wrapped version of the Descriptors and EnumDescriptors that
    	// point to the file that defines them.
    	g.WrapTypes()
    
    	g.SetPackageNames()
    	g.BuildTypeNameMap()
    
    	g.GenerateAllFiles()
    
    	// Send back the results.
    	data, err = proto.Marshal(g.Response)
    	if err != nil {
    		g.Error(err, "failed to marshal output proto")
    	}
    	_, err = os.Stdout.Write(data)
    	if err != nil {
    		g.Error(err, "failed to write output proto")
    	}
    }
    
    

    第七步,生成protoc-gen-go.exe

    go build .
    

    最后,我们得到了protoc-gen-go.exe,可以将这个程序放入$GOPATH/bin(go下面的bin目录)中使用。

    参考资料:
    《Go语言高级编程》
    https://chai2010.cn/advanced-go-programming-book/ch4-rpc/ch4-02-pb-intro.html
    《自定义 golang protobuf plugin》
    https://blog.csdn.net/wanmei002/article/details/106097849/

  • 相关阅读:
    ZooKeeperACL机制
    windows结束端口对应的进程
    facenet模型训练
    sourcetree git合并问题
    人脸识别学习
    爬虫 第八天
    WCF nginx反向代理遇到的问题
    WPF WindowChrome 自定义窗口
    WPF svg 转 xmal
    WPF MVVM笔记
  • 原文地址:https://www.cnblogs.com/cnlihao/p/12903160.html
Copyright © 2011-2022 走看看