美文网首页
protoc-gen-lua 多嵌套引用修改

protoc-gen-lua 多嵌套引用修改

作者: nameLogen | 来源:发表于2020-06-08 20:37 被阅读0次

    protobuf 使我们经常使用的通信数据传输格式,为了方便lua直接使用proto 生成的文件,使用了protoc-gen-lua 工具,但是这个使用嵌套的proto 文件时,protoc.exe 无法正常引用,报错找不到对应的文件。所以后来参考下面两篇文章,修改了 protoc-gen-lua 这个Python文件,得到了想要的结果。废话不多说,直接上图:

    目标文件

    proto 文件夹结构
    option java_package = "com.road.ddt.pb.game.login";
    option java_outer_classname = "LoginMsgProto";
    import "com/net/TestInfo.proto";
    
    /* 登陆请求 code:8002*/
    message LoginMsg {
        optional string userName = 1;
        optional string unixTime = 2;
        optional string signKey = 3;
        optional string host = 4;
        optional int32 port = 5;
        optional int32 userId = 6;
        optional int32 loginCode = 7;
        repeated TestInfoProto reslut = 8;
    }
    
    option java_package = "com.road.ddt.pb.com.net";
    option java_outer_classname = "TestMsg";
    
    message TestInfoProto {
        optional bool bool = 1;
        optional int32 int = 2;
    }
    
    option java_package = "com.road.ddt.pb.client.login";
    option java_outer_classname = "LoginOutMsgProto";
    
    import "com/net/TestInfo.proto";
    
    /* 登陆结果返回 code:2*/
    message LoginOutMsg {
        repeated TestInfoProto reslut = 1;
    }
    

    修改 protoc-gen-lua

    修改 code_gen_field 方法


        if field_desc.HasField('type_name'):
            # type_name = env.get_ref_name(field_desc.type_name).upper().replace('.', '_')
            if field_desc.type == FDP.TYPE_MESSAGE:
                # 修改 引用其他文件夹下的message 时,把左边的文件名截取出来,再把右边的字段名大写处理 如: TestInfo_pb.TESTINFOPROTO
                typeNameL = env.get_ref_name(field_desc.type_name).split(".")[0]
                typeNameR = env.get_ref_name(field_desc.type_name).split(".")[1]
    
                typeNameLL = typeNameL.split("/")
                typeNameL = typeNameLL[len(typeNameLL) - 1]
                type_name = typeNameL +"."+ (typeNameR.upper())
                context('.message_type = %s\n' % type_name)
            else:
                type_name = env.get_ref_name(field_desc.type_name).upper().replace('.', '_')
                context('.enum_type = %s\n' % type_name)
    

    修改 code_gen_message 方法


    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('.', '_')
        # 修改 把local 去掉了,方便 TestInfo_pb.TESTINFOPROTO 能否直接访问到
        env.descriptor.append(
            "%s = protobuf.Descriptor();\n"% obj_name
        )
        # "local %s = protobuf.Descriptor();\n"% obj_name
    

    修改 code_gen_file 方法


        if is_gen:
            lua = Writer()
            write_header(lua)
            lua('local protobuf = require "protobuf"\n')
            for i in includes:
                # 修改 将前面的local xx_pb 去掉 了,因为 这个require 返回的是 一个 true or false 
                lua('require("%s_pb")\n' % (i))
                # lua('local %s_pb = require("%s_pb")\n' % (i, i))
            # 修改 修改文件名,将文件名中的路径去掉
            typeNameLL = env.filename.split("/")
            typeNameL = typeNameLL[len(typeNameLL) - 1]
            # 修改 增加了",package.seeall" 多传入一个package.seeall的参数,相当于 setmetatable(M, {__index = _G}) .
            lua("module('%s_pb',package.seeall)\n" % typeNameL)
    

    生成结果,保留了目录结构

    image.png

    LoginOutMsg_pb.lua

    -- Generated By protoc-gen-lua Do not Edit
    local protobuf = require "protobuf"
    require("com/net/TestInfo_pb")
    module('LoginOutMsg_pb',package.seeall)
    
    
    LOGINOUTMSG = protobuf.Descriptor();
    local LOGINOUTMSG_RESLUT_FIELD = protobuf.FieldDescriptor();
    
    LOGINOUTMSG_RESLUT_FIELD.name = "reslut"
    LOGINOUTMSG_RESLUT_FIELD.full_name = ".LoginOutMsg.reslut"
    LOGINOUTMSG_RESLUT_FIELD.number = 1
    LOGINOUTMSG_RESLUT_FIELD.index = 0
    LOGINOUTMSG_RESLUT_FIELD.label = 3
    LOGINOUTMSG_RESLUT_FIELD.has_default_value = false
    LOGINOUTMSG_RESLUT_FIELD.default_value = {}
    LOGINOUTMSG_RESLUT_FIELD.message_type = TestInfo_pb.TESTINFOPROTO
    LOGINOUTMSG_RESLUT_FIELD.type = 11
    LOGINOUTMSG_RESLUT_FIELD.cpp_type = 10
    
    LOGINOUTMSG.name = "LoginOutMsg"
    LOGINOUTMSG.full_name = ".LoginOutMsg"
    LOGINOUTMSG.nested_types = {}
    LOGINOUTMSG.enum_types = {}
    LOGINOUTMSG.fields = {LOGINOUTMSG_RESLUT_FIELD}
    LOGINOUTMSG.is_extendable = false
    LOGINOUTMSG.extensions = {}
    
    LoginOutMsg = protobuf.Message(LOGINOUTMSG)
    
    

    TestInfo_pb.lua

    -- Generated By protoc-gen-lua Do not Edit
    local protobuf = require "protobuf"
    module('TestInfo_pb',package.seeall)
    
    
    TESTINFOPROTO = protobuf.Descriptor();
    local TESTINFOPROTO_BOOL_FIELD = protobuf.FieldDescriptor();
    local TESTINFOPROTO_INT_FIELD = protobuf.FieldDescriptor();
    
    TESTINFOPROTO_BOOL_FIELD.name = "bool"
    TESTINFOPROTO_BOOL_FIELD.full_name = ".TestInfoProto.bool"
    TESTINFOPROTO_BOOL_FIELD.number = 1
    TESTINFOPROTO_BOOL_FIELD.index = 0
    TESTINFOPROTO_BOOL_FIELD.label = 1
    TESTINFOPROTO_BOOL_FIELD.has_default_value = false
    TESTINFOPROTO_BOOL_FIELD.default_value = false
    TESTINFOPROTO_BOOL_FIELD.type = 8
    TESTINFOPROTO_BOOL_FIELD.cpp_type = 7
    
    TESTINFOPROTO_INT_FIELD.name = "int"
    TESTINFOPROTO_INT_FIELD.full_name = ".TestInfoProto.int"
    TESTINFOPROTO_INT_FIELD.number = 2
    TESTINFOPROTO_INT_FIELD.index = 1
    TESTINFOPROTO_INT_FIELD.label = 1
    TESTINFOPROTO_INT_FIELD.has_default_value = false
    TESTINFOPROTO_INT_FIELD.default_value = 0
    TESTINFOPROTO_INT_FIELD.type = 5
    TESTINFOPROTO_INT_FIELD.cpp_type = 1
    
    TESTINFOPROTO.name = "TestInfoProto"
    TESTINFOPROTO.full_name = ".TestInfoProto"
    TESTINFOPROTO.nested_types = {}
    TESTINFOPROTO.enum_types = {}
    TESTINFOPROTO.fields = {TESTINFOPROTO_BOOL_FIELD, TESTINFOPROTO_INT_FIELD}
    TESTINFOPROTO.is_extendable = false
    TESTINFOPROTO.extensions = {}
    
    TestInfoProto = protobuf.Message(TESTINFOPROTO)
    

    调用方法示例

    image.png

    调试结果

    image.png

    注意事项

    一、.proto 文件不能重名,必须保证名字唯一,因为这里的module 使用了文件名。

    工具下载路径

    参考

    protoc-gen-lua多个proto嵌套的实现
    protoc-gen-lua 编译、安装、使用教程
    Lua中module函数的作用和用法
    工具下载protoToLua

    相关文章

      网友评论

          本文标题:protoc-gen-lua 多嵌套引用修改

          本文链接:https://www.haomeiwen.com/subject/puddtktx.html