美文网首页
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 多嵌套引用修改

    protobuf 使我们经常使用的通信数据传输格式,为了方便lua直接使用proto 生成的文件,使用了proto...

  • Atom 编辑器的 Markdown书写学习(二)

    【5】文字引用 > 引用文字1 引用文字2 >> 嵌套引用文字3 >>> 嵌套引用文字4 表现效果 【6】文字强调...

  • Markdown 引用

    引用的多层嵌套 区块引用可以嵌套(例如:引用内的引用),只要根据层次加上不同数量的 > : 代码: 显示效果: 请...

  • swift 嵌套类型

    嵌套类型实践示例官方demo 引用嵌套类型

  • 结构体嵌套

    结构体嵌套 结构体嵌套时应逐级引用

  • 初学和使用 markdown

    h1 h1 h2 h3 h4 h5 h6 区块引用1.区块引用嵌套1层112.区块引用嵌套1层区块引用嵌套2层区块...

  • Go语言之结构体嵌套

    Go语言之结构体嵌套 在type Student2 struct结构体中,注意book参数引用的是地址,方便修改数据

  • SCSS

    scss语法scss常见用法阮一峰 sass语法 变量 $ 定义 嵌套引用 多值变量 变量计算 定义 嵌套引用,特...

  • C++引用进阶和多线程

    1、引用进阶 在getName函数中,如果返回的是引用,可以直接通过赋值修改。如果返回的是值,则不能修改。 2、多...

  • Markdown||引用

    今天我来学习引用。 语法: 效果: 引用二级嵌套三级嵌套 今天学习的引用比较简单,只需要在文字内容前加 > 即可,...

网友评论

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

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