protoc-gen-lua多个proto嵌套的实现

首先我们需要的protobuf导出lua的工具https://github.com/sean-lin/protoc-gen-lua, 具体使用,编写自己的proto文件,使用protoc --lua_out=./ foo.proto 导出lua文件即可,导出lua文件的主要实现是在plugin下的protoc-gen-lua文件。本身此工具不支持proto的嵌套,比如有两个proto文件

basic.proto里包换一个message:

message Item{
     required int32 id = 1;
     ...
}

而另一个proto引用basic.proto的Item这个message,比如user_proc.proto

message Sell{
      optional int32 t = 1;
      repeated Item items = 2;
      ...
} 

如果不加任何引用的话,上述proto会报错的,正常情况下,需要引进package,针对basic.proto和user_proc.proto做如下修改:

#basic.lua
package protobuf_basic_export

.....

#user_proc.proto
import "basic.proto";

message Sell{
     optional int32 t = 1;
     repeated protobuf_basic_export.Item items = 2;
     ...
}
这样导出不会报错了,符合protobuf的书写要求。

但是protoc-gen-lua导出的lua文件就有些问题,执行后发现,user_proc_pb_lua会报错:BAISC_PB_ITEM找不到,这个是工具产生的字段,当该type不在当前proto下时会产生,是合成的字段,lua执行的话肯定找不到这个字段,我们要修改的也是这个地方要改成如下:

USER_PROC_ITEM_FIELD.message_type = BASIC_PB.ITEM

而BASIC_PB要指向导出的basic_pb.lua文件,所以修改导出的python文件,实现我们的要求:

1:去除合并

    if field_desc.HasField('type_name'):
        type_name = env.get_ref_name(field_desc.type_name).upper()

:2:message descriptor设为全局,

def code_gen_message(message_descriptor, env, containing_type = None):
    env.enter(message_descriptor.name)
    full_name = env.get_local_name()
    obj_name = full_name.upper().replace('.', '_')
    env.descriptor.append(
        "%s = protobuf.Descriptor();\n"% obj_name
    ):

3:引用pb大写, 与类型一致 即local BASIC_PB = require("basic_pb")

    if is_gen:
        lua = Writer()
        write_header(lua)
        lua('local protobuf = require "protobuf"\n')
        for i in includes:
            lua('local %s_PB = require("%s_pb")\n' % (i.upper(), i))
        lua("module('%s_pb')\n" % env.filename)

导出后文件变成:

-- Generated By protoc-gen-lua Do not Edit

local protobuf = require "protobuf"
module('basic_pb')


ITEM= protobuf.Descriptor();
local ITEM_ID_FIELD = protobuf.FieldDescriptor();

-- Generated By protoc-gen-lua Do not Edit
local protobuf = require "protobuf"
local BASIC_PB = require("basic_pb")
module('user_proc_pb')


SELL_ITEMS_FIELD.message_type = BASIC_PB.ITEM

这样BASIC_PB.ITEM是可以找到的,就在basic_pb.lua里


git https://github.com/AdamWu/protoc-gen-lua


ps:你可以使用云风的pb,它支持嵌套proto关系


你可能感兴趣的:(lua)