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關係


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章