├── .gitignore ├── LICENSE ├── README.md ├── example ├── Lua │ └── Protol │ │ ├── common_pb.lua │ │ └── person_pb.lua ├── common.proto ├── make_proto.bat ├── person.proto └── protoc.exe ├── plugin ├── build.bat ├── plugin_pb2.py └── protoc-gen-lua └── protobuf ├── Makefile ├── containers.lua ├── decoder.lua ├── descriptor.lua ├── encoder.lua ├── listener.lua ├── pb.c ├── protobuf.lua ├── text_format.lua ├── type_checkers.lua └── wire_format.lua /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.so 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, sean-lin 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the {organization} nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | protoc-gen-lua 2 | ============== 3 | **默认放在C盘目录C:\protoc-gen-lua-master\protoc-gen-lua-master, 生成lua放在 Lua/Protol 目录
4 | 修改说明:
5 | 1. 支持嵌套类(必需在使用类之前声明)
6 | 2. 支持int64, uint64
7 | 3. 解包的协议对象支持 tostring 操作
8 | 编译环境:
9 | 1. Python2.7.8
10 | https://www.python.org/downloads/release/python-278/
11 | 2. 编译好的protobuf2.5下载地址
12 | http://pan.baidu.com/s/1slEUfXb
13 | 注意:
14 | 1. 嵌套的proto 必须在当前 proto 之前声明
15 | 2. 安装python后, 需要在protobuf2.5 的python 目录下执行命令 Python setup.py install
** 16 | 17 | 18 | Google's Protocol Buffers project, ported to Lua 19 | 20 | "[Protocol Buffers](http://code.google.com/p/protobuf/)" is a binary serialization format and technology, released to the open source community by Google in 2008. 21 | 22 | There are various implementations of Protocol Buffers and this is for Lua. 23 | 24 | ## Install 25 | 26 | Install python runtime and the protobuf 2.3 for python. 27 | 28 | checkout the code. 29 | 30 | Compile the C code: 31 | 32 | `$cd protobuf && make` 33 | 34 | Make a link to protoc-gen-lua in your $PATH: 35 | 36 | `$cd /usr/local/bin && sudo ln -s /path/to/protoc-gen-lua/plugin/protoc-gen-lua` 37 | 38 | Then you can compile the .proto like this: 39 | 40 | `protoc --lua_out=./ foo.proto` 41 | 42 | 43 | ## Quick Example 44 | You write a .proto file like this: 45 | 46 | person.proto : 47 | ``` 48 | message Person { 49 | required int32 id = 1; 50 | required string name = 2; 51 | optional string email = 3; 52 | } 53 | ``` 54 | 55 | Then you compile it. 56 | 57 | Then, make sure that protobuf/ in package.cpath and package.path, you use that code like this: 58 | 59 | ``` 60 | require "person_pb" 61 | 62 | -- Serialize Example 63 | local msg = person_pb.Person() 64 | msg.id = 100 65 | msg.name = "foo" 66 | msg.email = "bar" 67 | local pb_data = msg:SerializeToString() 68 | 69 | -- Parse Example 70 | local msg = person_pb.Person() 71 | msg:ParseFromString(pb_data) 72 | print(msg.id, msg.name, msg.email) 73 | ``` 74 | 75 | The API of this library is similar the protobuf library for python. 76 | For a more complete example, read the [python documentation](http://code.google.com/apis/protocolbuffers/docs/pythontutorial.html). 77 | 78 | 79 | -------------------------------------------------------------------------------- /example/Lua/Protol/common_pb.lua: -------------------------------------------------------------------------------- 1 | --Generated By protoc-gen-lua Do not Edit 2 | local protobuf = require "protobuf.protobuf" 3 | module('Protol.common_pb') 4 | 5 | HEADER = protobuf.Descriptor(); 6 | HEADER_CMD_FIELD = protobuf.FieldDescriptor(); 7 | HEADER_SEQ_FIELD = protobuf.FieldDescriptor(); 8 | 9 | HEADER_CMD_FIELD.name = "cmd" 10 | HEADER_CMD_FIELD.full_name = ".Header.cmd" 11 | HEADER_CMD_FIELD.number = 1 12 | HEADER_CMD_FIELD.index = 0 13 | HEADER_CMD_FIELD.label = 2 14 | HEADER_CMD_FIELD.has_default_value = false 15 | HEADER_CMD_FIELD.default_value = 0 16 | HEADER_CMD_FIELD.type = 3 17 | HEADER_CMD_FIELD.cpp_type = 2 18 | 19 | HEADER_SEQ_FIELD.name = "seq" 20 | HEADER_SEQ_FIELD.full_name = ".Header.seq" 21 | HEADER_SEQ_FIELD.number = 2 22 | HEADER_SEQ_FIELD.index = 1 23 | HEADER_SEQ_FIELD.label = 2 24 | HEADER_SEQ_FIELD.has_default_value = false 25 | HEADER_SEQ_FIELD.default_value = 0 26 | HEADER_SEQ_FIELD.type = 5 27 | HEADER_SEQ_FIELD.cpp_type = 1 28 | 29 | HEADER.name = "Header" 30 | HEADER.full_name = ".Header" 31 | HEADER.nested_types = {} 32 | HEADER.enum_types = {} 33 | HEADER.fields = {HEADER_CMD_FIELD, HEADER_SEQ_FIELD} 34 | HEADER.is_extendable = false 35 | HEADER.extensions = {} 36 | 37 | Header = protobuf.Message(HEADER) 38 | 39 | -------------------------------------------------------------------------------- /example/Lua/Protol/person_pb.lua: -------------------------------------------------------------------------------- 1 | --Generated By protoc-gen-lua Do not Edit 2 | local protobuf = require "protobuf.protobuf" 3 | local common_pb = require("Protol.common_pb") 4 | module('Protol.person_pb') 5 | 6 | PERSON = protobuf.Descriptor(); 7 | PERSON_HEADER_FIELD = protobuf.FieldDescriptor(); 8 | PERSON_ID_FIELD = protobuf.FieldDescriptor(); 9 | PERSON_NAME_FIELD = protobuf.FieldDescriptor(); 10 | PERSON_AGE_FIELD = protobuf.FieldDescriptor(); 11 | PERSON_EMAIL_FIELD = protobuf.FieldDescriptor(); 12 | PERSON_ARRAY_FIELD = protobuf.FieldDescriptor(); 13 | PHONE = protobuf.Descriptor(); 14 | PHONE_PHONE_TYPE = protobuf.EnumDescriptor(); 15 | PHONE_PHONE_TYPE_MOBILE_ENUM = protobuf.EnumValueDescriptor(); 16 | PHONE_PHONE_TYPE_HOME_ENUM = protobuf.EnumValueDescriptor(); 17 | PHONE_NUM_FIELD = protobuf.FieldDescriptor(); 18 | PHONE_TYPE_FIELD = protobuf.FieldDescriptor(); 19 | PHONE_PHONES_FIELD = protobuf.FieldDescriptor(); 20 | 21 | PERSON_HEADER_FIELD.name = "header" 22 | PERSON_HEADER_FIELD.full_name = ".Person.header" 23 | PERSON_HEADER_FIELD.number = 1 24 | PERSON_HEADER_FIELD.index = 0 25 | PERSON_HEADER_FIELD.label = 2 26 | PERSON_HEADER_FIELD.has_default_value = false 27 | PERSON_HEADER_FIELD.default_value = nil 28 | PERSON_HEADER_FIELD.message_type = common_pb.HEADER 29 | PERSON_HEADER_FIELD.type = 11 30 | PERSON_HEADER_FIELD.cpp_type = 10 31 | 32 | PERSON_ID_FIELD.name = "id" 33 | PERSON_ID_FIELD.full_name = ".Person.id" 34 | PERSON_ID_FIELD.number = 2 35 | PERSON_ID_FIELD.index = 1 36 | PERSON_ID_FIELD.label = 2 37 | PERSON_ID_FIELD.has_default_value = false 38 | PERSON_ID_FIELD.default_value = 0 39 | PERSON_ID_FIELD.type = 3 40 | PERSON_ID_FIELD.cpp_type = 2 41 | 42 | PERSON_NAME_FIELD.name = "name" 43 | PERSON_NAME_FIELD.full_name = ".Person.name" 44 | PERSON_NAME_FIELD.number = 3 45 | PERSON_NAME_FIELD.index = 2 46 | PERSON_NAME_FIELD.label = 2 47 | PERSON_NAME_FIELD.has_default_value = false 48 | PERSON_NAME_FIELD.default_value = "" 49 | PERSON_NAME_FIELD.type = 9 50 | PERSON_NAME_FIELD.cpp_type = 9 51 | 52 | PERSON_AGE_FIELD.name = "age" 53 | PERSON_AGE_FIELD.full_name = ".Person.age" 54 | PERSON_AGE_FIELD.number = 4 55 | PERSON_AGE_FIELD.index = 3 56 | PERSON_AGE_FIELD.label = 1 57 | PERSON_AGE_FIELD.has_default_value = true 58 | PERSON_AGE_FIELD.default_value = 18 59 | PERSON_AGE_FIELD.type = 5 60 | PERSON_AGE_FIELD.cpp_type = 1 61 | 62 | PERSON_EMAIL_FIELD.name = "email" 63 | PERSON_EMAIL_FIELD.full_name = ".Person.email" 64 | PERSON_EMAIL_FIELD.number = 5 65 | PERSON_EMAIL_FIELD.index = 4 66 | PERSON_EMAIL_FIELD.label = 1 67 | PERSON_EMAIL_FIELD.has_default_value = true 68 | PERSON_EMAIL_FIELD.default_value = "topameng@qq.com" 69 | PERSON_EMAIL_FIELD.type = 9 70 | PERSON_EMAIL_FIELD.cpp_type = 9 71 | 72 | PERSON_ARRAY_FIELD.name = "array" 73 | PERSON_ARRAY_FIELD.full_name = ".Person.array" 74 | PERSON_ARRAY_FIELD.number = 6 75 | PERSON_ARRAY_FIELD.index = 5 76 | PERSON_ARRAY_FIELD.label = 3 77 | PERSON_ARRAY_FIELD.has_default_value = false 78 | PERSON_ARRAY_FIELD.default_value = {} 79 | PERSON_ARRAY_FIELD.type = 5 80 | PERSON_ARRAY_FIELD.cpp_type = 1 81 | 82 | PERSON.name = "Person" 83 | PERSON.full_name = ".Person" 84 | PERSON.nested_types = {} 85 | PERSON.enum_types = {} 86 | PERSON.fields = {PERSON_HEADER_FIELD, PERSON_ID_FIELD, PERSON_NAME_FIELD, PERSON_AGE_FIELD, PERSON_EMAIL_FIELD, PERSON_ARRAY_FIELD} 87 | PERSON.is_extendable = true 88 | PERSON.extensions = {} 89 | PHONE_PHONE_TYPE_MOBILE_ENUM.name = "MOBILE" 90 | PHONE_PHONE_TYPE_MOBILE_ENUM.index = 0 91 | PHONE_PHONE_TYPE_MOBILE_ENUM.number = 1 92 | PHONE_PHONE_TYPE_HOME_ENUM.name = "HOME" 93 | PHONE_PHONE_TYPE_HOME_ENUM.index = 1 94 | PHONE_PHONE_TYPE_HOME_ENUM.number = 2 95 | PHONE_PHONE_TYPE.name = "PHONE_TYPE" 96 | PHONE_PHONE_TYPE.full_name = ".Phone.PHONE_TYPE" 97 | PHONE_PHONE_TYPE.values = {PHONE_PHONE_TYPE_MOBILE_ENUM,PHONE_PHONE_TYPE_HOME_ENUM} 98 | PHONE_NUM_FIELD.name = "num" 99 | PHONE_NUM_FIELD.full_name = ".Phone.num" 100 | PHONE_NUM_FIELD.number = 1 101 | PHONE_NUM_FIELD.index = 0 102 | PHONE_NUM_FIELD.label = 1 103 | PHONE_NUM_FIELD.has_default_value = false 104 | PHONE_NUM_FIELD.default_value = "" 105 | PHONE_NUM_FIELD.type = 9 106 | PHONE_NUM_FIELD.cpp_type = 9 107 | 108 | PHONE_TYPE_FIELD.name = "type" 109 | PHONE_TYPE_FIELD.full_name = ".Phone.type" 110 | PHONE_TYPE_FIELD.number = 2 111 | PHONE_TYPE_FIELD.index = 1 112 | PHONE_TYPE_FIELD.label = 1 113 | PHONE_TYPE_FIELD.has_default_value = false 114 | PHONE_TYPE_FIELD.default_value = nil 115 | PHONE_TYPE_FIELD.enum_type = PHONE_PHONE_TYPE 116 | PHONE_TYPE_FIELD.type = 14 117 | PHONE_TYPE_FIELD.cpp_type = 8 118 | 119 | PHONE_PHONES_FIELD.name = "phones" 120 | PHONE_PHONES_FIELD.full_name = ".Phone.phones" 121 | PHONE_PHONES_FIELD.number = 10 122 | PHONE_PHONES_FIELD.index = 0 123 | PHONE_PHONES_FIELD.label = 3 124 | PHONE_PHONES_FIELD.has_default_value = false 125 | PHONE_PHONES_FIELD.default_value = {} 126 | PHONE_PHONES_FIELD.message_type = PHONE 127 | PHONE_PHONES_FIELD.type = 11 128 | PHONE_PHONES_FIELD.cpp_type = 10 129 | 130 | PHONE.name = "Phone" 131 | PHONE.full_name = ".Phone" 132 | PHONE.nested_types = {} 133 | PHONE.enum_types = {PHONE_PHONE_TYPE} 134 | PHONE.fields = {PHONE_NUM_FIELD, PHONE_TYPE_FIELD} 135 | PHONE.is_extendable = false 136 | PHONE.extensions = {PHONE_PHONES_FIELD} 137 | 138 | Person = protobuf.Message(PERSON) 139 | Phone = protobuf.Message(PHONE) 140 | 141 | Person.RegisterExtension(PHONE_PHONES_FIELD) 142 | -------------------------------------------------------------------------------- /example/common.proto: -------------------------------------------------------------------------------- 1 | 2 | message Header 3 | { 4 | required int64 cmd = 1; 5 | required int32 seq = 2; 6 | } -------------------------------------------------------------------------------- /example/make_proto.bat: -------------------------------------------------------------------------------- 1 | for %%i in (*.proto) do ( 2 | protoc.exe --plugin=protoc-gen-lua="..\plugin\build.bat" --lua_out=.\Lua\Protol %%i 3 | ) -------------------------------------------------------------------------------- /example/person.proto: -------------------------------------------------------------------------------- 1 | import "common.proto"; 2 | 3 | message Person 4 | { 5 | required Header header = 1; 6 | required int64 id = 2; 7 | required string name = 3; 8 | optional int32 age = 4 [default = 18]; 9 | optional string email = 5 [default = "topameng@qq.com"]; 10 | repeated int32 array = 6; 11 | 12 | extensions 10 to max; 13 | } 14 | 15 | message Phone 16 | { 17 | extend Person { repeated Phone phones = 10;} 18 | 19 | enum PHONE_TYPE 20 | { 21 | MOBILE = 1; 22 | HOME = 2; 23 | } 24 | optional string num = 1; 25 | optional PHONE_TYPE type = 2; 26 | } 27 | -------------------------------------------------------------------------------- /example/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topameng/protoc-gen-lua/9001c5a9075f29e8a30aad3de0f6aaaf13fb06b9/example/protoc.exe -------------------------------------------------------------------------------- /plugin/build.bat: -------------------------------------------------------------------------------- 1 | @python %~dp0protoc-gen-lua -------------------------------------------------------------------------------- /plugin/plugin_pb2.py: -------------------------------------------------------------------------------- 1 | # Generated by the protocol buffer compiler. DO NOT EDIT! 2 | 3 | from google.protobuf import descriptor 4 | from google.protobuf import message 5 | from google.protobuf import reflection 6 | from google.protobuf import descriptor_pb2 7 | # @@protoc_insertion_point(imports) 8 | 9 | 10 | DESCRIPTOR = descriptor.FileDescriptor( 11 | name='google/protobuf/compiler/plugin.proto', 12 | package='google.protobuf.compiler', 13 | serialized_pb='\n%google/protobuf/compiler/plugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"}\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xaa\x01\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a>\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\t') 14 | 15 | 16 | 17 | 18 | _CODEGENERATORREQUEST = descriptor.Descriptor( 19 | name='CodeGeneratorRequest', 20 | full_name='google.protobuf.compiler.CodeGeneratorRequest', 21 | filename=None, 22 | file=DESCRIPTOR, 23 | containing_type=None, 24 | fields=[ 25 | descriptor.FieldDescriptor( 26 | name='file_to_generate', full_name='google.protobuf.compiler.CodeGeneratorRequest.file_to_generate', index=0, 27 | number=1, type=9, cpp_type=9, label=3, 28 | has_default_value=False, default_value=[], 29 | message_type=None, enum_type=None, containing_type=None, 30 | is_extension=False, extension_scope=None, 31 | options=None), 32 | descriptor.FieldDescriptor( 33 | name='parameter', full_name='google.protobuf.compiler.CodeGeneratorRequest.parameter', index=1, 34 | number=2, type=9, cpp_type=9, label=1, 35 | has_default_value=False, default_value=unicode("", "utf-8"), 36 | message_type=None, enum_type=None, containing_type=None, 37 | is_extension=False, extension_scope=None, 38 | options=None), 39 | descriptor.FieldDescriptor( 40 | name='proto_file', full_name='google.protobuf.compiler.CodeGeneratorRequest.proto_file', index=2, 41 | number=15, type=11, cpp_type=10, label=3, 42 | has_default_value=False, default_value=[], 43 | message_type=None, enum_type=None, containing_type=None, 44 | is_extension=False, extension_scope=None, 45 | options=None), 46 | ], 47 | extensions=[ 48 | ], 49 | nested_types=[], 50 | enum_types=[ 51 | ], 52 | options=None, 53 | is_extendable=False, 54 | extension_ranges=[], 55 | serialized_start=101, 56 | serialized_end=226, 57 | ) 58 | 59 | 60 | _CODEGENERATORRESPONSE_FILE = descriptor.Descriptor( 61 | name='File', 62 | full_name='google.protobuf.compiler.CodeGeneratorResponse.File', 63 | filename=None, 64 | file=DESCRIPTOR, 65 | containing_type=None, 66 | fields=[ 67 | descriptor.FieldDescriptor( 68 | name='name', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.name', index=0, 69 | number=1, type=9, cpp_type=9, label=1, 70 | has_default_value=False, default_value=unicode("", "utf-8"), 71 | message_type=None, enum_type=None, containing_type=None, 72 | is_extension=False, extension_scope=None, 73 | options=None), 74 | descriptor.FieldDescriptor( 75 | name='insertion_point', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point', index=1, 76 | number=2, type=9, cpp_type=9, label=1, 77 | has_default_value=False, default_value=unicode("", "utf-8"), 78 | message_type=None, enum_type=None, containing_type=None, 79 | is_extension=False, extension_scope=None, 80 | options=None), 81 | descriptor.FieldDescriptor( 82 | name='content', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.content', index=2, 83 | number=15, type=9, cpp_type=9, label=1, 84 | has_default_value=False, default_value=unicode("", "utf-8"), 85 | message_type=None, enum_type=None, containing_type=None, 86 | is_extension=False, extension_scope=None, 87 | options=None), 88 | ], 89 | extensions=[ 90 | ], 91 | nested_types=[], 92 | enum_types=[ 93 | ], 94 | options=None, 95 | is_extendable=False, 96 | extension_ranges=[], 97 | serialized_start=337, 98 | serialized_end=399, 99 | ) 100 | 101 | _CODEGENERATORRESPONSE = descriptor.Descriptor( 102 | name='CodeGeneratorResponse', 103 | full_name='google.protobuf.compiler.CodeGeneratorResponse', 104 | filename=None, 105 | file=DESCRIPTOR, 106 | containing_type=None, 107 | fields=[ 108 | descriptor.FieldDescriptor( 109 | name='error', full_name='google.protobuf.compiler.CodeGeneratorResponse.error', index=0, 110 | number=1, type=9, cpp_type=9, label=1, 111 | has_default_value=False, default_value=unicode("", "utf-8"), 112 | message_type=None, enum_type=None, containing_type=None, 113 | is_extension=False, extension_scope=None, 114 | options=None), 115 | descriptor.FieldDescriptor( 116 | name='file', full_name='google.protobuf.compiler.CodeGeneratorResponse.file', index=1, 117 | number=15, type=11, cpp_type=10, label=3, 118 | has_default_value=False, default_value=[], 119 | message_type=None, enum_type=None, containing_type=None, 120 | is_extension=False, extension_scope=None, 121 | options=None), 122 | ], 123 | extensions=[ 124 | ], 125 | nested_types=[_CODEGENERATORRESPONSE_FILE, ], 126 | enum_types=[ 127 | ], 128 | options=None, 129 | is_extendable=False, 130 | extension_ranges=[], 131 | serialized_start=229, 132 | serialized_end=399, 133 | ) 134 | 135 | import google.protobuf.descriptor_pb2 136 | 137 | _CODEGENERATORREQUEST.fields_by_name['proto_file'].message_type = google.protobuf.descriptor_pb2._FILEDESCRIPTORPROTO 138 | _CODEGENERATORRESPONSE_FILE.containing_type = _CODEGENERATORRESPONSE; 139 | _CODEGENERATORRESPONSE.fields_by_name['file'].message_type = _CODEGENERATORRESPONSE_FILE 140 | 141 | class CodeGeneratorRequest(message.Message): 142 | __metaclass__ = reflection.GeneratedProtocolMessageType 143 | DESCRIPTOR = _CODEGENERATORREQUEST 144 | 145 | # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) 146 | 147 | class CodeGeneratorResponse(message.Message): 148 | __metaclass__ = reflection.GeneratedProtocolMessageType 149 | 150 | class File(message.Message): 151 | __metaclass__ = reflection.GeneratedProtocolMessageType 152 | DESCRIPTOR = _CODEGENERATORRESPONSE_FILE 153 | 154 | # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) 155 | DESCRIPTOR = _CODEGENERATORRESPONSE 156 | 157 | # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse) 158 | 159 | # @@protoc_insertion_point(module_scope) 160 | -------------------------------------------------------------------------------- /plugin/protoc-gen-lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- encoding:utf8 -*- 3 | # protoc-gen-erl 4 | # Google's Protocol Buffers project, ported to lua. 5 | # https://code.google.com/p/protoc-gen-lua/ 6 | # 7 | # Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com 8 | # All rights reserved. 9 | # 10 | # Use, modification and distribution are subject to the "New BSD License" 11 | # as listed at . 12 | 13 | import sys 14 | import os.path as path 15 | from cStringIO import StringIO 16 | 17 | import plugin_pb2 18 | import google.protobuf.descriptor_pb2 as descriptor_pb2 19 | 20 | _packages = {} 21 | _files = {} 22 | _message = {} 23 | 24 | FDP = plugin_pb2.descriptor_pb2.FieldDescriptorProto 25 | 26 | if sys.platform == "win32": 27 | import msvcrt, os 28 | msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) 29 | msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) 30 | 31 | class CppType: 32 | CPPTYPE_INT32 = 1 33 | CPPTYPE_INT64 = 2 34 | CPPTYPE_UINT32 = 3 35 | CPPTYPE_UINT64 = 4 36 | CPPTYPE_DOUBLE = 5 37 | CPPTYPE_FLOAT = 6 38 | CPPTYPE_BOOL = 7 39 | CPPTYPE_ENUM = 8 40 | CPPTYPE_STRING = 9 41 | CPPTYPE_MESSAGE = 10 42 | 43 | CPP_TYPE ={ 44 | FDP.TYPE_DOUBLE : CppType.CPPTYPE_DOUBLE, 45 | FDP.TYPE_FLOAT : CppType.CPPTYPE_FLOAT, 46 | FDP.TYPE_INT64 : CppType.CPPTYPE_INT64, 47 | FDP.TYPE_UINT64 : CppType.CPPTYPE_UINT64, 48 | FDP.TYPE_INT32 : CppType.CPPTYPE_INT32, 49 | FDP.TYPE_FIXED64 : CppType.CPPTYPE_UINT64, 50 | FDP.TYPE_FIXED32 : CppType.CPPTYPE_UINT32, 51 | FDP.TYPE_BOOL : CppType.CPPTYPE_BOOL, 52 | FDP.TYPE_STRING : CppType.CPPTYPE_STRING, 53 | FDP.TYPE_MESSAGE : CppType.CPPTYPE_MESSAGE, 54 | FDP.TYPE_BYTES : CppType.CPPTYPE_STRING, 55 | FDP.TYPE_UINT32 : CppType.CPPTYPE_UINT32, 56 | FDP.TYPE_ENUM : CppType.CPPTYPE_ENUM, 57 | FDP.TYPE_SFIXED32 : CppType.CPPTYPE_INT32, 58 | FDP.TYPE_SFIXED64 : CppType.CPPTYPE_INT64, 59 | FDP.TYPE_SINT32 : CppType.CPPTYPE_INT32, 60 | FDP.TYPE_SINT64 : CppType.CPPTYPE_INT64 61 | } 62 | 63 | def printerr(*args): 64 | sys.stderr.write(" ".join(args)) 65 | sys.stderr.write("\n") 66 | sys.stderr.flush() 67 | 68 | class TreeNode(object): 69 | def __init__(self, name, parent=None, filename=None, package=None): 70 | super(TreeNode, self).__init__() 71 | self.child = [] 72 | self.parent = parent 73 | self.filename = filename 74 | self.package = package 75 | if parent: 76 | self.parent.add_child(self) 77 | self.name = name 78 | 79 | def add_child(self, child): 80 | self.child.append(child) 81 | 82 | def find_child(self, child_names): 83 | if child_names: 84 | for i in self.child: 85 | if i.name == child_names[0]: 86 | return i.find_child(child_names[1:]) 87 | raise StandardError 88 | else: 89 | return self 90 | 91 | def get_child(self, child_name): 92 | for i in self.child: 93 | if i.name == child_name: 94 | return i 95 | return None 96 | 97 | def get_path(self, end = None): 98 | pos = self 99 | out = [] 100 | while pos and pos != end: 101 | out.append(pos.name) 102 | pos = pos.parent 103 | out.reverse() 104 | return '.'.join(out) 105 | 106 | def get_global_name(self): 107 | return self.get_path() 108 | 109 | def get_local_name(self): 110 | pos = self 111 | while pos.parent: 112 | pos = pos.parent 113 | if self.package and pos.name == self.package[-1]: 114 | break 115 | return self.get_path(pos) 116 | 117 | def __str__(self): 118 | return self.to_string(0) 119 | 120 | def __repr__(self): 121 | return str(self) 122 | 123 | def to_string(self, indent = 0): 124 | return ' '*indent + '\n' 127 | 128 | class Env(object): 129 | filename = None 130 | package = None 131 | extend = None 132 | descriptor = None 133 | message = None 134 | context = None 135 | register = None 136 | def __init__(self): 137 | self.message_tree = TreeNode('') 138 | self.scope = self.message_tree 139 | 140 | def get_global_name(self): 141 | return self.scope.get_global_name() 142 | 143 | def get_local_name(self): 144 | return self.scope.get_local_name() 145 | 146 | def get_ref_name(self, type_name): 147 | try: 148 | node = self.lookup_name(type_name) 149 | except: 150 | # if the child doesn't be founded, it must be in this file 151 | return type_name[len('.'.join(self.package)) + 1:] 152 | if node.filename != self.filename: 153 | return node.filename + '_pb.' + node.get_local_name() 154 | return node.get_local_name() 155 | 156 | def get_msg_name(self, type_name): 157 | try: 158 | node = self.lookup_name(type_name) 159 | except: 160 | # if the child doesn't be founded, it must be in this file 161 | name = type_name[len('.'.join(self.package)) + 1:] 162 | return name.upper().replace('.', '_') 163 | if node.filename != self.filename: 164 | name = node.get_local_name() 165 | name = name.upper().replace('.', '_') 166 | return node.filename + '_pb.' + name 167 | name = node.get_local_name() 168 | return name.upper().replace('.', '_') 169 | 170 | def lookup_name(self, name): 171 | names = name.split('.') 172 | if names[0] == '': 173 | return self.message_tree.find_child(names[1:]) 174 | else: 175 | return self.scope.parent.find_child(names) 176 | 177 | def enter_package(self, package): 178 | if not package: 179 | return self.message_tree 180 | names = package.split('.') 181 | pos = self.message_tree 182 | for i, name in enumerate(names): 183 | new_pos = pos.get_child(name) 184 | if new_pos: 185 | pos = new_pos 186 | else: 187 | return self._build_nodes(pos, names[i:]) 188 | return pos 189 | 190 | def enter_file(self, filename, package): 191 | self.filename = filename 192 | self.package = package.split('.') 193 | self._init_field() 194 | self.scope = self.enter_package(package) 195 | 196 | def exit_file(self): 197 | self._init_field() 198 | self.filename = None 199 | self.package = [] 200 | self.scope = self.scope.parent 201 | 202 | def enter(self, message_name): 203 | self.scope = TreeNode(message_name, self.scope, self.filename, 204 | self.package) 205 | 206 | def exit(self): 207 | self.scope = self.scope.parent 208 | 209 | def _init_field(self): 210 | self.descriptor = [] 211 | self.context = [] 212 | self.message = [] 213 | self.register = [] 214 | 215 | def _build_nodes(self, node, names): 216 | parent = node 217 | for i in names: 218 | parent = TreeNode(i, parent, self.filename, self.package) 219 | return parent 220 | 221 | class Writer(object): 222 | def __init__(self, prefix=None): 223 | self.io = StringIO() 224 | self.__indent = '' 225 | self.__prefix = prefix 226 | 227 | def getvalue(self): 228 | return self.io.getvalue() 229 | 230 | def __enter__(self): 231 | self.__indent += ' ' 232 | return self 233 | 234 | def __exit__(self, type, value, trackback): 235 | self.__indent = self.__indent[:-4] 236 | 237 | def __call__(self, data): 238 | self.io.write(self.__indent) 239 | if self.__prefix: 240 | self.io.write(self.__prefix) 241 | self.io.write(data) 242 | 243 | DEFAULT_VALUE = { 244 | FDP.TYPE_DOUBLE : '0.0', 245 | FDP.TYPE_FLOAT : '0.0', 246 | FDP.TYPE_INT64 : '0', 247 | FDP.TYPE_UINT64 : '0', 248 | FDP.TYPE_INT32 : '0', 249 | FDP.TYPE_FIXED64 : '0', 250 | FDP.TYPE_FIXED32 : '0', 251 | FDP.TYPE_BOOL : 'false', 252 | FDP.TYPE_STRING : '""', 253 | FDP.TYPE_MESSAGE : 'nil', 254 | FDP.TYPE_BYTES : '""', 255 | FDP.TYPE_UINT32 : '0', 256 | FDP.TYPE_ENUM : '1', 257 | FDP.TYPE_SFIXED32 : '0', 258 | FDP.TYPE_SFIXED64 : '0', 259 | FDP.TYPE_SINT32 : '0', 260 | FDP.TYPE_SINT64 : '0', 261 | } 262 | 263 | def code_gen_enum_item(index, enum_value, env): 264 | full_name = env.get_local_name() + '.' + enum_value.name 265 | obj_name = full_name.upper().replace('.', '_') + '_ENUM' 266 | env.descriptor.append( 267 | "%s = protobuf.EnumValueDescriptor();\n"% obj_name 268 | ) 269 | 270 | context = Writer(obj_name) 271 | context('.name = "%s"\n' % enum_value.name) 272 | context('.index = %d\n' % index) 273 | context('.number = %d\n' % enum_value.number) 274 | 275 | env.context.append(context.getvalue()) 276 | return obj_name 277 | 278 | def code_gen_enum(enum_desc, env): 279 | env.enter(enum_desc.name) 280 | full_name = env.get_local_name() 281 | obj_name = full_name.upper().replace('.', '_') 282 | env.descriptor.append( 283 | "%s = protobuf.EnumDescriptor();\n"% obj_name 284 | ) 285 | 286 | context = Writer(obj_name) 287 | context('.name = "%s"\n' % enum_desc.name) 288 | context('.full_name = "%s"\n' % env.get_global_name()) 289 | 290 | values = [] 291 | for i, enum_value in enumerate(enum_desc.value): 292 | values.append(code_gen_enum_item(i, enum_value, env)) 293 | context('.values = {%s}\n' % ','.join(values)) 294 | 295 | env.context.append(context.getvalue()) 296 | env.exit() 297 | return obj_name 298 | 299 | def code_gen_field(index, field_desc, env): 300 | full_name = env.get_local_name() + '.' + field_desc.name 301 | obj_name = full_name.upper().replace('.', '_') + '_FIELD' 302 | env.descriptor.append( 303 | "%s = protobuf.FieldDescriptor();\n"% obj_name 304 | ) 305 | 306 | context = Writer(obj_name) 307 | 308 | context('.name = "%s"\n' % field_desc.name) 309 | context('.full_name = "%s"\n' % ( 310 | env.get_global_name() + '.' + field_desc.name)) 311 | context('.number = %d\n' % field_desc.number) 312 | context('.index = %d\n' % index) 313 | context('.label = %d\n' % field_desc.label) 314 | 315 | if field_desc.HasField("default_value"): 316 | context('.has_default_value = true\n') 317 | value = field_desc.default_value 318 | if field_desc.type == FDP.TYPE_STRING: 319 | context('.default_value = "%s"\n'%value) 320 | else: 321 | context('.default_value = %s\n'%value) 322 | else: 323 | context('.has_default_value = false\n') 324 | if field_desc.label == FDP.LABEL_REPEATED: 325 | default_value = "{}" 326 | elif field_desc.HasField('type_name'): 327 | default_value = "nil" 328 | else: 329 | default_value = DEFAULT_VALUE[field_desc.type] 330 | context('.default_value = %s\n' % default_value) 331 | 332 | if field_desc.HasField('type_name'): 333 | type_name = env.get_msg_name(field_desc.type_name) 334 | if field_desc.type == FDP.TYPE_MESSAGE: 335 | context('.message_type = %s\n' % type_name) 336 | else: 337 | context('.enum_type = %s\n' % type_name) 338 | 339 | if field_desc.HasField('extendee'): 340 | type_name = env.get_ref_name(field_desc.extendee) 341 | env.register.append( 342 | "%s.RegisterExtension(%s)\n" % (type_name, obj_name) 343 | ) 344 | 345 | context('.type = %d\n' % field_desc.type) 346 | context('.cpp_type = %d\n\n' % CPP_TYPE[field_desc.type]) 347 | env.context.append(context.getvalue()) 348 | return obj_name 349 | 350 | def code_gen_message(message_descriptor, env, containing_type = None): 351 | env.enter(message_descriptor.name) 352 | full_name = env.get_local_name() 353 | obj_name = full_name.upper().replace('.', '_') 354 | env.descriptor.append( 355 | "%s = protobuf.Descriptor();\n"% obj_name 356 | ) 357 | 358 | context = Writer(obj_name) 359 | context('.name = "%s"\n' % message_descriptor.name) 360 | context('.full_name = "%s"\n' % env.get_global_name()) 361 | 362 | nested_types = [] 363 | for msg_desc in message_descriptor.nested_type: 364 | msg_name = code_gen_message(msg_desc, env, obj_name) 365 | nested_types.append(msg_name) 366 | context('.nested_types = {%s}\n' % ', '.join(nested_types)) 367 | 368 | enums = [] 369 | for enum_desc in message_descriptor.enum_type: 370 | enums.append(code_gen_enum(enum_desc, env)) 371 | context('.enum_types = {%s}\n' % ', '.join(enums)) 372 | 373 | fields = [] 374 | for i, field_desc in enumerate(message_descriptor.field): 375 | fields.append(code_gen_field(i, field_desc, env)) 376 | 377 | context('.fields = {%s}\n' % ', '.join(fields)) 378 | if len(message_descriptor.extension_range) > 0: 379 | context('.is_extendable = true\n') 380 | else: 381 | context('.is_extendable = false\n') 382 | 383 | extensions = [] 384 | for i, field_desc in enumerate(message_descriptor.extension): 385 | extensions.append(code_gen_field(i, field_desc, env)) 386 | context('.extensions = {%s}\n' % ', '.join(extensions)) 387 | 388 | if containing_type: 389 | context('.containing_type = %s\n' % containing_type) 390 | 391 | env.message.append('%s = protobuf.Message(%s)\n' % (full_name, 392 | obj_name)) 393 | 394 | env.context.append(context.getvalue()) 395 | env.exit() 396 | return obj_name 397 | 398 | def write_header(writer): 399 | writer("""--Generated By protoc-gen-lua Do not Edit 400 | """) 401 | 402 | def code_gen_file(proto_file, env, is_gen): 403 | filename = path.splitext(proto_file.name)[0] 404 | env.enter_file(filename, proto_file.package) 405 | 406 | includes = [] 407 | for f in proto_file.dependency: 408 | inc_file = path.splitext(f)[0] 409 | includes.append(inc_file) 410 | 411 | # for field_desc in proto_file.extension: 412 | # code_gen_extensions(field_desc, field_desc.name, env) 413 | 414 | for enum_desc in proto_file.enum_type: 415 | code_gen_enum(enum_desc, env) 416 | for enum_value in enum_desc.value: 417 | env.message.append('%s = %d\n' % (enum_value.name, 418 | enum_value.number)) 419 | 420 | for msg_desc in proto_file.message_type: 421 | code_gen_message(msg_desc, env) 422 | 423 | if is_gen: 424 | lua = Writer() 425 | write_header(lua) 426 | lua('local protobuf = require "protobuf.protobuf"\n') 427 | for i in includes: 428 | lua('local %s_pb = require("Protol.%s_pb")\n' % (i, i)) 429 | lua("module('Protol.%s_pb')" % env.filename) 430 | 431 | lua('\n\n') 432 | map(lua, env.descriptor) 433 | lua('\n') 434 | map(lua, env.context) 435 | lua('\n') 436 | env.message.sort() 437 | map(lua, env.message) 438 | lua('\n') 439 | map(lua, env.register) 440 | 441 | _files[env.filename+ '_pb.lua'] = lua.getvalue() 442 | env.exit_file() 443 | 444 | def main(): 445 | plugin_require_bin = sys.stdin.read() 446 | code_gen_req = plugin_pb2.CodeGeneratorRequest() 447 | code_gen_req.ParseFromString(plugin_require_bin) 448 | 449 | env = Env() 450 | for proto_file in code_gen_req.proto_file: 451 | code_gen_file(proto_file, env, 452 | proto_file.name in code_gen_req.file_to_generate) 453 | 454 | code_generated = plugin_pb2.CodeGeneratorResponse() 455 | for k in _files: 456 | file_desc = code_generated.file.add() 457 | file_desc.name = k 458 | file_desc.content = _files[k] 459 | 460 | sys.stdout.write(code_generated.SerializeToString()) 461 | 462 | if __name__ == "__main__": 463 | main() 464 | 465 | -------------------------------------------------------------------------------- /protobuf/Makefile: -------------------------------------------------------------------------------- 1 | SRC=pb.c 2 | 3 | TARGET=pb.so 4 | CFLAGS=`pkg-config --cflags lua5.1` -std=gnu99 5 | LDFLAGS=`pkg-config --libs lua5.1` 6 | 7 | all:$(TARGET) 8 | 9 | $(TARGET):$(SRC) 10 | gcc -O3 -shared -fPIC $(SRC) $(CFLAGS) $(LDFLAGS) -o $@ 11 | -------------------------------------------------------------------------------- /protobuf/containers.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -------------------------------------------------------------------------------- 3 | -- FILE: containers.lua 4 | -- DESCRIPTION: protoc-gen-lua 5 | -- Google's Protocol Buffers project, ported to lua. 6 | -- https://code.google.com/p/protoc-gen-lua/ 7 | -- 8 | -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com 9 | -- All rights reserved. 10 | -- 11 | -- Use, modification and distribution are subject to the "New BSD License" 12 | -- as listed at . 13 | -- 14 | -- COMPANY: NetEase 15 | -- CREATED: 2010年08月02日 16时15分42秒 CST 16 | -------------------------------------------------------------------------------- 17 | -- 18 | local setmetatable = setmetatable 19 | local table = table 20 | local rawset = rawset 21 | local error = error 22 | 23 | module "protobuf.containers" 24 | 25 | local _RCFC_meta = { 26 | add = function(self) 27 | local value = self._message_descriptor._concrete_class() 28 | local listener = self._listener 29 | rawset(self, #self + 1, value) 30 | value:_SetListener(listener) 31 | if listener.dirty == false then 32 | listener:Modified() 33 | end 34 | return value 35 | end, 36 | remove = function(self, key) 37 | local listener = self._listener 38 | table.remove(self, key) 39 | listener:Modified() 40 | end, 41 | __newindex = function(self, key, value) 42 | error("RepeatedCompositeFieldContainer Can't set value directly") 43 | end 44 | } 45 | _RCFC_meta.__index = _RCFC_meta 46 | 47 | function RepeatedCompositeFieldContainer(listener, message_descriptor) 48 | local o = { 49 | _listener = listener, 50 | _message_descriptor = message_descriptor 51 | } 52 | return setmetatable(o, _RCFC_meta) 53 | end 54 | 55 | local _RSFC_meta = { 56 | append = function(self, value) 57 | self._type_checker(value) 58 | rawset(self, #self + 1, value) 59 | self._listener:Modified() 60 | end, 61 | remove = function(self, key) 62 | table.remove(self, key) 63 | self._listener:Modified() 64 | end, 65 | __newindex = function(self, key, value) 66 | error("RepeatedCompositeFieldContainer Can't set value directly") 67 | end 68 | } 69 | _RSFC_meta.__index = _RSFC_meta 70 | 71 | function RepeatedScalarFieldContainer(listener, type_checker) 72 | local o = {} 73 | o._listener = listener 74 | o._type_checker = type_checker 75 | return setmetatable(o, _RSFC_meta) 76 | end 77 | 78 | 79 | -------------------------------------------------------------------------------- /protobuf/decoder.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -------------------------------------------------------------------------------- 3 | -- FILE: decoder.lua 4 | -- DESCRIPTION: protoc-gen-lua 5 | -- Google's Protocol Buffers project, ported to lua. 6 | -- https://code.google.com/p/protoc-gen-lua/ 7 | -- 8 | -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com 9 | -- All rights reserved. 10 | -- 11 | -- Use, modification and distribution are subject to the "New BSD License" 12 | -- as listed at . 13 | -- 14 | -- COMPANY: NetEase 15 | -- CREATED: 2010年07月29日 19时30分51秒 CST 16 | -------------------------------------------------------------------------------- 17 | -- 18 | local string = string 19 | local table = table 20 | local assert = assert 21 | local ipairs = ipairs 22 | local error = error 23 | local print = print 24 | 25 | local pb = require "pb" 26 | local encoder = require "protobuf.encoder" 27 | local wire_format = require "protobuf.wire_format" 28 | module "protobuf.decoder" 29 | 30 | local _DecodeVarint = pb.varint_decoder 31 | local _DecodeSignedVarint = pb.signed_varint_decoder 32 | 33 | local _DecodeVarint32 = pb.varint_decoder 34 | local _DecodeSignedVarint32 = pb.signed_varint_decoder 35 | 36 | local _DecodeVarint64 = pb.varint_decoder64 37 | local _DecodeSignedVarint64 = pb.signed_varint_decoder64 38 | 39 | ReadTag = pb.read_tag 40 | 41 | local function _SimpleDecoder(wire_type, decode_value) 42 | return function(field_number, is_repeated, is_packed, key, new_default) 43 | if is_packed then 44 | local DecodeVarint = _DecodeVarint 45 | return function (buffer, pos, pend, message, field_dict) 46 | local value = field_dict[key] 47 | if value == nil then 48 | value = new_default(message) 49 | field_dict[key] = value 50 | end 51 | local endpoint 52 | endpoint, pos = DecodeVarint(buffer, pos) 53 | endpoint = endpoint + pos 54 | if endpoint > pend then 55 | error('Truncated message.') 56 | end 57 | local element 58 | while pos < endpoint do 59 | element, pos = decode_value(buffer, pos) 60 | value[#value + 1] = element 61 | end 62 | if pos > endpoint then 63 | value:remove(#value) 64 | error('Packed element was truncated.') 65 | end 66 | return pos 67 | end 68 | elseif is_repeated then 69 | local tag_bytes = encoder.TagBytes(field_number, wire_type) 70 | local tag_len = #tag_bytes 71 | local sub = string.sub 72 | return function(buffer, pos, pend, message, field_dict) 73 | local value = field_dict[key] 74 | if value == nil then 75 | value = new_default(message) 76 | field_dict[key] = value 77 | end 78 | while 1 do 79 | local element, new_pos = decode_value(buffer, pos) 80 | value:append(element) 81 | pos = new_pos + tag_len 82 | if sub(buffer, new_pos+1, pos) ~= tag_bytes or new_pos >= pend then 83 | if new_pos > pend then 84 | error('Truncated message.') 85 | end 86 | return new_pos 87 | end 88 | end 89 | end 90 | else 91 | return function (buffer, pos, pend, message, field_dict) 92 | field_dict[key], pos = decode_value(buffer, pos) 93 | if pos > pend then 94 | field_dict[key] = nil 95 | error('Truncated message.') 96 | end 97 | return pos 98 | end 99 | end 100 | end 101 | end 102 | 103 | local function _ModifiedDecoder(wire_type, decode_value, modify_value) 104 | local InnerDecode = function (buffer, pos) 105 | local result, new_pos = decode_value(buffer, pos) 106 | return modify_value(result), new_pos 107 | end 108 | return _SimpleDecoder(wire_type, InnerDecode) 109 | end 110 | 111 | local function _StructPackDecoder(wire_type, value_size, format) 112 | local struct_unpack = pb.struct_unpack 113 | 114 | function InnerDecode(buffer, pos) 115 | local new_pos = pos + value_size 116 | local result = struct_unpack(format, buffer, pos) 117 | return result, new_pos 118 | end 119 | return _SimpleDecoder(wire_type, InnerDecode) 120 | end 121 | 122 | local function _Boolean(value) 123 | return value ~= 0 124 | end 125 | 126 | Int32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32) 127 | EnumDecoder = Int32Decoder 128 | 129 | Int64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeSignedVarint64) 130 | 131 | UInt32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32) 132 | UInt64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint64) 133 | 134 | SInt32Decoder = _ModifiedDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32, wire_format.ZigZagDecode32) 135 | SInt64Decoder = _ModifiedDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint64, wire_format.ZigZagDecode64) 136 | 137 | Fixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('I')) 138 | Fixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('Q')) 139 | SFixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('i')) 140 | SFixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('q')) 141 | FloatDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('f')) 142 | DoubleDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('d')) 143 | 144 | 145 | BoolDecoder = _ModifiedDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint, _Boolean) 146 | 147 | 148 | function StringDecoder(field_number, is_repeated, is_packed, key, new_default) 149 | local DecodeVarint = _DecodeVarint 150 | local sub = string.sub 151 | -- local unicode = unicode 152 | assert(not is_packed) 153 | if is_repeated then 154 | local tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 155 | local tag_len = #tag_bytes 156 | return function (buffer, pos, pend, message, field_dict) 157 | local value = field_dict[key] 158 | if value == nil then 159 | value = new_default(message) 160 | field_dict[key] = value 161 | end 162 | while 1 do 163 | local size, new_pos 164 | size, pos = DecodeVarint(buffer, pos) 165 | new_pos = pos + size 166 | if new_pos > pend then 167 | error('Truncated string.') 168 | end 169 | value:append(sub(buffer, pos+1, new_pos)) 170 | pos = new_pos + tag_len 171 | if sub(buffer, new_pos + 1, pos) ~= tag_bytes or new_pos == pend then 172 | return new_pos 173 | end 174 | end 175 | end 176 | else 177 | return function (buffer, pos, pend, message, field_dict) 178 | local size, new_pos 179 | size, pos = DecodeVarint(buffer, pos) 180 | new_pos = pos + size 181 | if new_pos > pend then 182 | error('Truncated string.') 183 | end 184 | field_dict[key] = sub(buffer, pos + 1, new_pos) 185 | return new_pos 186 | end 187 | end 188 | end 189 | 190 | function BytesDecoder(field_number, is_repeated, is_packed, key, new_default) 191 | local DecodeVarint = _DecodeVarint 192 | local sub = string.sub 193 | assert(not is_packed) 194 | if is_repeated then 195 | local tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 196 | local tag_len = #tag_bytes 197 | return function (buffer, pos, pend, message, field_dict) 198 | local value = field_dict[key] 199 | if value == nil then 200 | value = new_default(message) 201 | field_dict[key] = value 202 | end 203 | while 1 do 204 | local size, new_pos 205 | size, pos = DecodeVarint(buffer, pos) 206 | new_pos = pos + size 207 | if new_pos > pend then 208 | error('Truncated string.') 209 | end 210 | value:append(sub(buffer, pos + 1, new_pos)) 211 | pos = new_pos + tag_len 212 | if sub(buffer, new_pos + 1, pos) ~= tag_bytes or new_pos == pend then 213 | return new_pos 214 | end 215 | end 216 | end 217 | else 218 | return function(buffer, pos, pend, message, field_dict) 219 | local size, new_pos 220 | size, pos = DecodeVarint(buffer, pos) 221 | new_pos = pos + size 222 | if new_pos > pend then 223 | error('Truncated string.') 224 | end 225 | field_dict[key] = sub(buffer, pos + 1, new_pos) 226 | return new_pos 227 | end 228 | end 229 | end 230 | 231 | function MessageDecoder(field_number, is_repeated, is_packed, key, new_default) 232 | local DecodeVarint = _DecodeVarint 233 | local sub = string.sub 234 | 235 | assert(not is_packed) 236 | if is_repeated then 237 | local tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 238 | local tag_len = #tag_bytes 239 | return function (buffer, pos, pend, message, field_dict) 240 | local value = field_dict[key] 241 | if value == nil then 242 | value = new_default(message) 243 | field_dict[key] = value 244 | end 245 | while 1 do 246 | local size, new_pos 247 | size, pos = DecodeVarint(buffer, pos) 248 | new_pos = pos + size 249 | if new_pos > pend then 250 | error('Truncated message.') 251 | end 252 | if value:add():_InternalParse(buffer, pos, new_pos) ~= new_pos then 253 | error('Unexpected end-group tag.') 254 | end 255 | pos = new_pos + tag_len 256 | if sub(buffer, new_pos + 1, pos) ~= tag_bytes or new_pos == pend then 257 | return new_pos 258 | end 259 | end 260 | end 261 | else 262 | return function (buffer, pos, pend, message, field_dict) 263 | local value = field_dict[key] 264 | if value == nil then 265 | value = new_default(message) 266 | field_dict[key] = value 267 | end 268 | local size, new_pos 269 | size, pos = DecodeVarint(buffer, pos) 270 | new_pos = pos + size 271 | if new_pos > pend then 272 | error('Truncated message.') 273 | end 274 | if value:_InternalParse(buffer, pos, new_pos) ~= new_pos then 275 | error('Unexpected end-group tag.') 276 | end 277 | return new_pos 278 | end 279 | end 280 | end 281 | 282 | function _SkipVarint(buffer, pos, pend) 283 | local value 284 | value, pos = _DecodeVarint(buffer, pos) 285 | return pos 286 | end 287 | 288 | function _SkipFixed64(buffer, pos, pend) 289 | pos = pos + 8 290 | if pos > pend then 291 | error('Truncated message.') 292 | end 293 | return pos 294 | end 295 | 296 | function _SkipLengthDelimited(buffer, pos, pend) 297 | local size 298 | size, pos = _DecodeVarint(buffer, pos) 299 | pos = pos + size 300 | if pos > pend then 301 | error('Truncated message.') 302 | end 303 | return pos 304 | end 305 | 306 | function _SkipFixed32(buffer, pos, pend) 307 | pos = pos + 4 308 | if pos > pend then 309 | error('Truncated message.') 310 | end 311 | return pos 312 | end 313 | 314 | function _RaiseInvalidWireType(buffer, pos, pend) 315 | error('Tag had invalid wire type.') 316 | end 317 | 318 | function _FieldSkipper() 319 | WIRETYPE_TO_SKIPPER = { 320 | _SkipVarint, 321 | _SkipFixed64, 322 | _SkipLengthDelimited, 323 | _SkipGroup, 324 | _EndGroup, 325 | _SkipFixed32, 326 | _RaiseInvalidWireType, 327 | _RaiseInvalidWireType, 328 | } 329 | 330 | -- wiretype_mask = wire_format.TAG_TYPE_MASK 331 | local ord = string.byte 332 | local sub = string.sub 333 | 334 | return function (buffer, pos, pend, tag_bytes) 335 | local wire_type = ord(sub(tag_bytes, 1, 1)) % 8 + 1 336 | return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, pend) 337 | end 338 | end 339 | 340 | SkipField = _FieldSkipper() 341 | -------------------------------------------------------------------------------- /protobuf/descriptor.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -------------------------------------------------------------------------------- 3 | -- FILE: descriptor.lua 4 | -- DESCRIPTION: protoc-gen-lua 5 | -- Google's Protocol Buffers project, ported to lua. 6 | -- https://code.google.com/p/protoc-gen-lua/ 7 | -- 8 | -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com 9 | -- All rights reserved. 10 | -- 11 | -- Use, modification and distribution are subject to the "New BSD License" 12 | -- as listed at . 13 | -- 14 | -- COMPANY: NetEase 15 | -- CREATED: 2010年08月11日 18时45分43秒 CST 16 | -------------------------------------------------------------------------------- 17 | -- 18 | 19 | module "protobuf.descriptor" 20 | 21 | FieldDescriptor = { 22 | TYPE_DOUBLE = 1, 23 | TYPE_FLOAT = 2, 24 | TYPE_INT64 = 3, 25 | TYPE_UINT64 = 4, 26 | TYPE_INT32 = 5, 27 | TYPE_FIXED64 = 6, 28 | TYPE_FIXED32 = 7, 29 | TYPE_BOOL = 8, 30 | TYPE_STRING = 9, 31 | TYPE_GROUP = 10, 32 | TYPE_MESSAGE = 11, 33 | TYPE_BYTES = 12, 34 | TYPE_UINT32 = 13, 35 | TYPE_ENUM = 14, 36 | TYPE_SFIXED32 = 15, 37 | TYPE_SFIXED64 = 16, 38 | TYPE_SINT32 = 17, 39 | TYPE_SINT64 = 18, 40 | MAX_TYPE = 18, 41 | 42 | -- Must be consistent with C++ FieldDescriptor::CppType enum in 43 | -- descriptor.h. 44 | -- 45 | CPPTYPE_INT32 = 1, 46 | CPPTYPE_INT64 = 2, 47 | CPPTYPE_UINT32 = 3, 48 | CPPTYPE_UINT64 = 4, 49 | CPPTYPE_DOUBLE = 5, 50 | CPPTYPE_FLOAT = 6, 51 | CPPTYPE_BOOL = 7, 52 | CPPTYPE_ENUM = 8, 53 | CPPTYPE_STRING = 9, 54 | CPPTYPE_MESSAGE = 10, 55 | MAX_CPPTYPE = 10, 56 | 57 | -- Must be consistent with C++ FieldDescriptor::Label enum in 58 | -- descriptor.h. 59 | -- 60 | LABEL_OPTIONAL = 1, 61 | LABEL_REQUIRED = 2, 62 | LABEL_REPEATED = 3, 63 | MAX_LABEL = 3 64 | } 65 | -------------------------------------------------------------------------------- /protobuf/encoder.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -------------------------------------------------------------------------------- 3 | -- FILE: encoder.lua 4 | -- DESCRIPTION: protoc-gen-lua 5 | -- Google's Protocol Buffers project, ported to lua. 6 | -- https://code.google.com/p/protoc-gen-lua/ 7 | -- 8 | -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com 9 | -- All rights reserved. 10 | -- 11 | -- Use, modification and distribution are subject to the "New BSD License" 12 | -- as listed at . 13 | -- 14 | -- COMPANY: NetEase 15 | -- CREATED: 2010年07月29日 19时30分46秒 CST 16 | -------------------------------------------------------------------------------- 17 | -- 18 | local string = string 19 | local table = table 20 | local ipairs = ipairs 21 | local assert =assert 22 | 23 | local pb = require "pb" 24 | local wire_format = require "protobuf.wire_format" 25 | module "protobuf.encoder" 26 | 27 | function _VarintSize(value) 28 | if value <= 0x7f then return 1 end 29 | if value <= 0x3fff then return 2 end 30 | if value <= 0x1fffff then return 3 end 31 | if value <= 0xfffffff then return 4 end 32 | if value <= 0x7ffffffff then return 5 end 33 | if value <= 0x3ffffffffff then return 6 end 34 | if value <= 0x1ffffffffffff then return 7 end 35 | if value <= 0xffffffffffffff then return 8 end 36 | if value <= 0x7fffffffffffffff then return 9 end 37 | return 10 38 | end 39 | 40 | function _SignedVarintSize(value) 41 | if value < 0 then return 10 end 42 | if value <= 0x7f then return 1 end 43 | if value <= 0x3fff then return 2 end 44 | if value <= 0x1fffff then return 3 end 45 | if value <= 0xfffffff then return 4 end 46 | if value <= 0x7ffffffff then return 5 end 47 | if value <= 0x3ffffffffff then return 6 end 48 | if value <= 0x1ffffffffffff then return 7 end 49 | if value <= 0xffffffffffffff then return 8 end 50 | if value <= 0x7fffffffffffffff then return 9 end 51 | return 10 52 | end 53 | 54 | function _TagSize(field_number) 55 | return _VarintSize(wire_format.PackTag(field_number, 0)) 56 | end 57 | 58 | function _SimpleSizer(compute_value_size) 59 | return function(field_number, is_repeated, is_packed) 60 | local tag_size = _TagSize(field_number) 61 | if is_packed then 62 | local VarintSize = _VarintSize 63 | return function(value) 64 | local result = 0 65 | for _, element in ipairs(value) do 66 | result = result + compute_value_size(element) 67 | end 68 | return result + VarintSize(result) + tag_size 69 | end 70 | elseif is_repeated then 71 | return function(value) 72 | local result = tag_size * #value 73 | for _, element in ipairs(value) do 74 | result = result + compute_value_size(element) 75 | end 76 | return result 77 | end 78 | else 79 | return function (value) 80 | return tag_size + compute_value_size(value) 81 | end 82 | end 83 | end 84 | end 85 | 86 | function _ModifiedSizer(compute_value_size, modify_value) 87 | return function (field_number, is_repeated, is_packed) 88 | local tag_size = _TagSize(field_number) 89 | if is_packed then 90 | local VarintSize = _VarintSize 91 | return function (value) 92 | local result = 0 93 | for _, element in ipairs(value) do 94 | result = result + compute_value_size(modify_value(element)) 95 | end 96 | return result + VarintSize(result) + tag_size 97 | end 98 | elseif is_repeated then 99 | return function (value) 100 | local result = tag_size * #value 101 | for _, element in ipairs(value) do 102 | result = result + compute_value_size(modify_value(element)) 103 | end 104 | return result 105 | end 106 | else 107 | return function (value) 108 | return tag_size + compute_value_size(modify_value(value)) 109 | end 110 | end 111 | end 112 | end 113 | 114 | function _FixedSizer(value_size) 115 | return function (field_number, is_repeated, is_packed) 116 | local tag_size = _TagSize(field_number) 117 | if is_packed then 118 | local VarintSize = _VarintSize 119 | return function (value) 120 | local result = #value * value_size 121 | return result + VarintSize(result) + tag_size 122 | end 123 | elseif is_repeated then 124 | local element_size = value_size + tag_size 125 | return function(value) 126 | return #value * element_size 127 | end 128 | else 129 | local field_size = value_size + tag_size 130 | return function (value) 131 | return field_size 132 | end 133 | end 134 | end 135 | end 136 | 137 | Int32Sizer = _SimpleSizer(_SignedVarintSize) 138 | Int64Sizer = _SimpleSizer(pb.signed_varint_size) 139 | EnumSizer = Int32Sizer 140 | 141 | UInt32Sizer = _SimpleSizer(_VarintSize) 142 | UInt64Sizer = _SimpleSizer(pb.varint_size) 143 | 144 | SInt32Sizer = _ModifiedSizer(_SignedVarintSize, wire_format.ZigZagEncode32) 145 | SInt64Sizer = SInt32Sizer 146 | 147 | Fixed32Sizer = _FixedSizer(4) 148 | SFixed32Sizer = Fixed32Sizer 149 | FloatSizer = Fixed32Sizer 150 | 151 | Fixed64Sizer = _FixedSizer(8) 152 | SFixed64Sizer = Fixed64Sizer 153 | DoubleSizer = Fixed64Sizer 154 | 155 | BoolSizer = _FixedSizer(1) 156 | 157 | 158 | function StringSizer(field_number, is_repeated, is_packed) 159 | local tag_size = _TagSize(field_number) 160 | local VarintSize = _VarintSize 161 | assert(not is_packed) 162 | if is_repeated then 163 | return function(value) 164 | local result = tag_size * #value 165 | for _, element in ipairs(value) do 166 | local l = #element 167 | result = result + VarintSize(l) + l 168 | end 169 | return result 170 | end 171 | else 172 | return function(value) 173 | local l = #value 174 | return tag_size + VarintSize(l) + l 175 | end 176 | end 177 | end 178 | 179 | function BytesSizer(field_number, is_repeated, is_packed) 180 | local tag_size = _TagSize(field_number) 181 | local VarintSize = _VarintSize 182 | assert(not is_packed) 183 | if is_repeated then 184 | return function (value) 185 | local result = tag_size * #value 186 | for _,element in ipairs(value) do 187 | local l = #element 188 | result = result + VarintSize(l) + l 189 | end 190 | return result 191 | end 192 | else 193 | return function (value) 194 | local l = #value 195 | return tag_size + VarintSize(l) + l 196 | end 197 | end 198 | end 199 | 200 | function MessageSizer(field_number, is_repeated, is_packed) 201 | local tag_size = _TagSize(field_number) 202 | local VarintSize = _VarintSize 203 | assert(not is_packed) 204 | if is_repeated then 205 | return function(value) 206 | local result = tag_size * #value 207 | for _,element in ipairs(value) do 208 | local l = element:ByteSize() 209 | result = result + VarintSize(l) + l 210 | end 211 | return result 212 | end 213 | else 214 | return function (value) 215 | local l = value:ByteSize() 216 | return tag_size + VarintSize(l) + l 217 | end 218 | end 219 | end 220 | 221 | 222 | -- ==================================================================== 223 | -- Encoders! 224 | 225 | local _EncodeVarint = pb.varint_encoder 226 | local _EncodeSignedVarint = pb.signed_varint_encoder 227 | local _EncodeVarint64 = pb.varint_encoder64 228 | local _EncodeSignedVarint64 = pb.signed_varint_encoder64 229 | 230 | 231 | function _VarintBytes(value) 232 | local out = {} 233 | local write = function(value) 234 | out[#out + 1 ] = value 235 | end 236 | _EncodeSignedVarint(write, value) 237 | return table.concat(out) 238 | end 239 | 240 | function TagBytes(field_number, wire_type) 241 | return _VarintBytes(wire_format.PackTag(field_number, wire_type)) 242 | end 243 | 244 | function _SimpleEncoder(wire_type, encode_value, compute_value_size) 245 | return function(field_number, is_repeated, is_packed) 246 | if is_packed then 247 | local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 248 | local EncodeVarint = _EncodeVarint 249 | return function(write, value) 250 | write(tag_bytes) 251 | local size = 0 252 | for _, element in ipairs(value) do 253 | size = size + compute_value_size(element) 254 | end 255 | EncodeVarint(write, size) 256 | for element in value do 257 | encode_value(write, element) 258 | end 259 | end 260 | elseif is_repeated then 261 | local tag_bytes = TagBytes(field_number, wire_type) 262 | return function(write, value) 263 | for _, element in ipairs(value) do 264 | write(tag_bytes) 265 | encode_value(write, element) 266 | end 267 | end 268 | else 269 | local tag_bytes = TagBytes(field_number, wire_type) 270 | return function(write, value) 271 | write(tag_bytes) 272 | encode_value(write, value) 273 | end 274 | end 275 | end 276 | end 277 | 278 | function _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value) 279 | return function (field_number, is_repeated, is_packed) 280 | if is_packed then 281 | local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 282 | local EncodeVarint = _EncodeVarint 283 | return function (write, value) 284 | write(tag_bytes) 285 | local size = 0 286 | for _, element in ipairs(value) do 287 | size = size + compute_value_size(modify_value(element)) 288 | end 289 | EncodeVarint(write, size) 290 | for _, element in ipairs(value) do 291 | encode_value(write, modify_value(element)) 292 | end 293 | end 294 | elseif is_repeated then 295 | local tag_bytes = TagBytes(field_number, wire_type) 296 | return function (write, value) 297 | for _, element in ipairs(value) do 298 | write(tag_bytes) 299 | encode_value(write, modify_value(element)) 300 | end 301 | end 302 | else 303 | local tag_bytes = TagBytes(field_number, wire_type) 304 | return function (write, value) 305 | write(tag_bytes) 306 | encode_value(write, modify_value(value)) 307 | end 308 | end 309 | end 310 | end 311 | 312 | function _StructPackEncoder(wire_type, value_size, format) 313 | return function(field_number, is_repeated, is_packed) 314 | local struct_pack = pb.struct_pack 315 | if is_packed then 316 | local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 317 | local EncodeVarint = _EncodeVarint 318 | return function (write, value) 319 | write(tag_bytes) 320 | EncodeVarint(write, #value * value_size) 321 | for _, element in ipairs(value) do 322 | struct_pack(write, format, element) 323 | end 324 | end 325 | elseif is_repeated then 326 | local tag_bytes = TagBytes(field_number, wire_type) 327 | return function (write, value) 328 | for _, element in ipairs(value) do 329 | write(tag_bytes) 330 | struct_pack(write, format, element) 331 | end 332 | end 333 | else 334 | local tag_bytes = TagBytes(field_number, wire_type) 335 | return function (write, value) 336 | write(tag_bytes) 337 | struct_pack(write, format, value) 338 | end 339 | end 340 | 341 | end 342 | end 343 | 344 | Int32Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize) 345 | Int64Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeSignedVarint64, _SignedVarintSize) 346 | EnumEncoder = Int32Encoder 347 | 348 | UInt32Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize) 349 | UInt64Encoder = _SimpleEncoder(wire_format.WIRETYPE_VARINT, _EncodeVarint64, _VarintSize) 350 | 351 | SInt32Encoder = _ModifiedEncoder( 352 | wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize, 353 | wire_format.ZigZagEncode32) 354 | 355 | SInt64Encoder = _ModifiedEncoder( 356 | wire_format.WIRETYPE_VARINT, _EncodeVarint64, _VarintSize, 357 | wire_format.ZigZagEncode64) 358 | 359 | Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('I')) 360 | Fixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('Q')) 361 | SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('i')) 362 | SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('q')) 363 | FloatEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, 4, string.byte('f')) 364 | DoubleEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, 8, string.byte('d')) 365 | 366 | 367 | function BoolEncoder(field_number, is_repeated, is_packed) 368 | local false_byte = '\0' 369 | local true_byte = '\1' 370 | if is_packed then 371 | local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 372 | local EncodeVarint = _EncodeVarint 373 | return function (write, value) 374 | write(tag_bytes) 375 | EncodeVarint(write, #value) 376 | for _, element in ipairs(value) do 377 | if element then 378 | write(true_byte) 379 | else 380 | write(false_byte) 381 | end 382 | end 383 | end 384 | elseif is_repeated then 385 | local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT) 386 | return function(write, value) 387 | for _, element in ipairs(value) do 388 | write(tag_bytes) 389 | if element then 390 | write(true_byte) 391 | else 392 | write(false_byte) 393 | end 394 | end 395 | end 396 | else 397 | local tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT) 398 | return function (write, value) 399 | write(tag_bytes) 400 | if value then 401 | return write(true_byte) 402 | end 403 | return write(false_byte) 404 | end 405 | end 406 | end 407 | 408 | function StringEncoder(field_number, is_repeated, is_packed) 409 | local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 410 | local EncodeVarint = _EncodeVarint 411 | assert(not is_packed) 412 | if is_repeated then 413 | return function (write, value) 414 | for _, element in ipairs(value) do 415 | -- encoded = element.encode('utf-8') 416 | write(tag) 417 | EncodeVarint(write, #element) 418 | write(element) 419 | end 420 | end 421 | else 422 | return function (write, value) 423 | -- local encoded = value.encode('utf-8') 424 | write(tag) 425 | EncodeVarint(write, #value) 426 | return write(value) 427 | end 428 | end 429 | end 430 | 431 | function BytesEncoder(field_number, is_repeated, is_packed) 432 | local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 433 | local EncodeVarint = _EncodeVarint 434 | assert(not is_packed) 435 | if is_repeated then 436 | return function (write, value) 437 | for _, element in ipairs(value) do 438 | write(tag) 439 | EncodeVarint(write, #element) 440 | write(element) 441 | end 442 | end 443 | else 444 | return function(write, value) 445 | write(tag) 446 | EncodeVarint(write, #value) 447 | return write(value) 448 | end 449 | end 450 | end 451 | 452 | 453 | function MessageEncoder(field_number, is_repeated, is_packed) 454 | local tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 455 | local EncodeVarint = _EncodeVarint 456 | assert(not is_packed) 457 | if is_repeated then 458 | return function(write, value) 459 | for _, element in ipairs(value) do 460 | write(tag) 461 | EncodeVarint(write, element:ByteSize()) 462 | element:_InternalSerialize(write) 463 | end 464 | end 465 | else 466 | return function (write, value) 467 | write(tag) 468 | EncodeVarint(write, value:ByteSize()) 469 | return value:_InternalSerialize(write) 470 | end 471 | end 472 | end 473 | 474 | -------------------------------------------------------------------------------- /protobuf/listener.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -------------------------------------------------------------------------------- 3 | -- FILE: listener.lua 4 | -- DESCRIPTION: protoc-gen-lua 5 | -- Google's Protocol Buffers project, ported to lua. 6 | -- https://code.google.com/p/protoc-gen-lua/ 7 | -- 8 | -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com 9 | -- All rights reserved. 10 | -- 11 | -- Use, modification and distribution are subject to the "New BSD License" 12 | -- as listed at . 13 | -- 14 | -- COMPANY: NetEase 15 | -- CREATED: 2010年08月02日 17时35分25秒 CST 16 | -------------------------------------------------------------------------------- 17 | -- 18 | local setmetatable = setmetatable 19 | 20 | module "protobuf.listener" 21 | 22 | local _null_listener = { 23 | Modified = function() 24 | end 25 | } 26 | 27 | function NullMessageListener() 28 | return _null_listener 29 | end 30 | 31 | local _listener_meta = { 32 | Modified = function(self) 33 | if self.dirty then 34 | return 35 | end 36 | if self._parent_message then 37 | self._parent_message:_Modified() 38 | end 39 | end 40 | } 41 | _listener_meta.__index = _listener_meta 42 | 43 | function Listener(parent_message) 44 | local o = {} 45 | o.__mode = "v" 46 | o._parent_message = parent_message 47 | o.dirty = false 48 | return setmetatable(o, _listener_meta) 49 | end 50 | 51 | -------------------------------------------------------------------------------- /protobuf/pb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * Filename: pb.c 4 | * 5 | * Description: protoc-gen-lua 6 | * Google's Protocol Buffers project, ported to lua. 7 | * https://code.google.com/p/protoc-gen-lua/ 8 | * 9 | * Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com 10 | * All rights reserved. 11 | * 12 | * Use, modification and distribution are subject to the "New BSD License" 13 | * as listed at . 14 | * Created: 2010年08月02日 18时04分21秒 15 | * Company: NetEase 16 | * 17 | 修复ios位对齐问题,安卓浮点数问题,以及int64, uint64等 (topameng) 18 | * ===================================================================================== 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #ifdef _WIN32_WCE 33 | #define PACKED_DECL 34 | #pragma pack(1) 35 | #else 36 | #define PACKED_DECL __attribute__((packed)) 37 | #endif 38 | 39 | struct __una_u64 { uint64_t x PACKED_DECL; }; 40 | struct __una_u32 { uint32_t x PACKED_DECL; }; 41 | struct __una_u16 { uint16_t x PACKED_DECL; }; 42 | struct __una_64 { int64_t x PACKED_DECL; }; 43 | struct __una_32 { int32_t x PACKED_DECL; }; 44 | struct __una_16 { int16_t x PACKED_DECL; }; 45 | struct __una_f { float x PACKED_DECL; }; 46 | struct __una_d { double x PACKED_DECL; }; 47 | 48 | #ifdef _WIN32_WCE 49 | #pragma pack 50 | #endif 51 | 52 | static inline uint64_t __uld64(const void * r11) 53 | { 54 | const struct __una_u64 *ptr = (const struct __una_u64 *) r11; 55 | return ptr->x; 56 | } 57 | 58 | static inline int64_t __ld64(const void * r11) 59 | { 60 | const struct __una_64 *ptr = (const struct __una_64 *) r11; 61 | return ptr->x; 62 | } 63 | 64 | static inline uint32_t __uld32(const void * r11) 65 | { 66 | const struct __una_u32 *ptr = (const struct __una_u32 *) r11; 67 | return ptr->x; 68 | } 69 | 70 | static inline int32_t __ld32(const void * r11) 71 | { 72 | const struct __una_32 *ptr = (const struct __una_32 *) r11; 73 | return ptr->x; 74 | } 75 | 76 | static inline float __ldf(const void * r11) 77 | { 78 | const struct __una_f *ptr = (const struct __una_f *) r11; 79 | return ptr->x; 80 | } 81 | 82 | static inline double __ldd(const void * r11) 83 | { 84 | const struct __una_d *ptr = (const struct __una_d *) r11; 85 | return ptr->x; 86 | } 87 | 88 | 89 | #if __BYTE_ORDER == __LITTLE_ENDIAN 90 | #define IS_LITTLE_ENDIAN 91 | #endif 92 | 93 | 94 | #define IOSTRING_META "protobuf.IOString" 95 | 96 | #define checkiostring(L) \ 97 | (IOString*) luaL_checkudata(L, 1, IOSTRING_META) 98 | 99 | #define IOSTRING_BUF_LEN 65535 100 | 101 | typedef struct 102 | { 103 | size_t size; 104 | char buf[IOSTRING_BUF_LEN]; 105 | } IOString; 106 | 107 | static void pack_varint(luaL_Buffer *b, uint64_t value) 108 | { 109 | if (value >= 0x80) 110 | { 111 | luaL_addchar(b, value | 0x80); 112 | value >>= 7; 113 | if (value >= 0x80) 114 | { 115 | luaL_addchar(b, value | 0x80); 116 | value >>= 7; 117 | if (value >= 0x80) 118 | { 119 | luaL_addchar(b, value | 0x80); 120 | value >>= 7; 121 | if (value >= 0x80) 122 | { 123 | luaL_addchar(b, value | 0x80); 124 | value >>= 7; 125 | if (value >= 0x80) 126 | { 127 | luaL_addchar(b, value | 0x80); 128 | value >>= 7; 129 | if (value >= 0x80) 130 | { 131 | luaL_addchar(b, value | 0x80); 132 | value >>= 7; 133 | if (value >= 0x80) 134 | { 135 | luaL_addchar(b, value | 0x80); 136 | value >>= 7; 137 | if (value >= 0x80) 138 | { 139 | luaL_addchar(b, value | 0x80); 140 | value >>= 7; 141 | if (value >= 0x80) 142 | { 143 | luaL_addchar(b, value | 0x80); 144 | value >>= 7; 145 | } 146 | } 147 | } 148 | } 149 | } 150 | } 151 | } 152 | } 153 | } 154 | luaL_addchar(b, value); 155 | } 156 | 157 | static int64_t _long(lua_State* L, int pos) 158 | { 159 | int64_t n = 0; 160 | int type = lua_type(L, pos); 161 | 162 | if (type == LUA_TNUMBER) 163 | { 164 | n = (int64_t)lua_tonumber(L, pos); 165 | } 166 | else if (type == LUA_TSTRING) 167 | { 168 | int old = errno; 169 | errno = 0; 170 | const char* str = lua_tostring(L, pos); 171 | n = atoll(str); 172 | 173 | if (errno == ERANGE) 174 | { 175 | errno = old; 176 | return luaL_error(L, "integral is too large: %s", str); 177 | } 178 | 179 | errno = old; 180 | } 181 | 182 | return n; 183 | } 184 | 185 | static uint64_t _ulong(lua_State* L, int pos) 186 | { 187 | uint64_t n = 0; 188 | int type = lua_type(L, pos); 189 | 190 | if (type == LUA_TNUMBER) 191 | { 192 | n = (uint64_t)lua_tonumber(L, pos); 193 | } 194 | else if (type == LUA_TSTRING) 195 | { 196 | int old = errno; 197 | errno = 0; 198 | const char* str = lua_tostring(L, pos); 199 | n = strtoull(str, NULL, 10); 200 | 201 | if (errno == ERANGE) 202 | { 203 | errno = old; 204 | return luaL_error(L, "integral is too large: %s", str); 205 | } 206 | 207 | errno = old; 208 | } 209 | 210 | return n; 211 | } 212 | 213 | static int varint_encoder(lua_State *L) 214 | { 215 | lua_Number l_value = luaL_checknumber(L, 2); 216 | uint64_t value = (uint64_t)l_value; 217 | 218 | luaL_Buffer b; 219 | luaL_buffinit(L, &b); 220 | 221 | pack_varint(&b, value); 222 | 223 | lua_settop(L, 1); 224 | luaL_pushresult(&b); 225 | lua_call(L, 1, 0); 226 | return 0; 227 | } 228 | 229 | static int varint_encoder64(lua_State *L) 230 | { 231 | uint64_t value = _ulong(L, 2); 232 | 233 | luaL_Buffer b; 234 | luaL_buffinit(L, &b); 235 | 236 | pack_varint(&b, value); 237 | 238 | lua_settop(L, 1); 239 | luaL_pushresult(&b); 240 | lua_call(L, 1, 0); 241 | return 0; 242 | } 243 | 244 | static int signed_varint_encoder(lua_State *L) 245 | { 246 | lua_Number l_value = luaL_checknumber(L, 2); 247 | int64_t value = (int64_t)l_value; 248 | 249 | luaL_Buffer b; 250 | luaL_buffinit(L, &b); 251 | 252 | if (value < 0) 253 | { 254 | pack_varint(&b, __uld64(&value)); 255 | } 256 | else 257 | { 258 | pack_varint(&b, value); 259 | } 260 | 261 | lua_settop(L, 1); 262 | luaL_pushresult(&b); 263 | lua_call(L, 1, 0); 264 | return 0; 265 | } 266 | 267 | static int signed_varint_encoder64(lua_State *L) 268 | { 269 | int64_t value = _long(L, 2); 270 | 271 | luaL_Buffer b; 272 | luaL_buffinit(L, &b); 273 | 274 | if (value < 0) 275 | { 276 | pack_varint(&b, __uld64(&value)); 277 | } 278 | else 279 | { 280 | pack_varint(&b, value); 281 | } 282 | 283 | lua_settop(L, 1); 284 | luaL_pushresult(&b); 285 | lua_call(L, 1, 0); 286 | return 0; 287 | } 288 | 289 | static int pack_fixed32(lua_State *L, uint8_t* value) 290 | { 291 | #ifdef IS_LITTLE_ENDIAN 292 | lua_pushlstring(L, (char*)value, 4); 293 | #else 294 | uint32_t v = htole32(__uld32(value)); 295 | lua_pushlstring(L, (char*)&v, 4); 296 | #endif 297 | return 0; 298 | } 299 | 300 | static int pack_fixed64(lua_State *L, uint8_t* value) 301 | { 302 | #ifdef IS_LITTLE_ENDIAN 303 | lua_pushlstring(L, (char*)value, 8); 304 | #else 305 | uint64_t v = htole64(__uld64(value)); 306 | lua_pushlstring(L, (char*)&v, 8); 307 | #endif 308 | return 0; 309 | } 310 | 311 | static int struct_pack(lua_State *L) 312 | { 313 | uint8_t format = luaL_checkinteger(L, 2); 314 | 315 | switch(format) 316 | { 317 | case 'i': 318 | { 319 | lua_Number value = luaL_checknumber(L, 3); 320 | lua_settop(L, 1); 321 | int32_t v = (int32_t)value; 322 | pack_fixed32(L, (uint8_t*)&v); 323 | break; 324 | } 325 | case 'q': 326 | { 327 | int64_t v = _long(L, 3); 328 | lua_settop(L, 1); 329 | pack_fixed64(L, (uint8_t*)&v); 330 | break; 331 | } 332 | case 'f': 333 | { 334 | lua_Number value = luaL_checknumber(L, 3); 335 | lua_settop(L, 1); 336 | float v = (float)value; 337 | pack_fixed32(L, (uint8_t*)&v); 338 | break; 339 | } 340 | case 'd': 341 | { 342 | lua_Number value = luaL_checknumber(L, 3); 343 | lua_settop(L, 1); 344 | double v = (double)value; 345 | pack_fixed64(L, (uint8_t*)&v); 346 | break; 347 | } 348 | case 'I': 349 | { 350 | lua_Number value = luaL_checknumber(L, 3); 351 | lua_settop(L, 1); 352 | uint32_t v = (uint32_t)value; 353 | pack_fixed32(L, (uint8_t*)&v); 354 | break; 355 | } 356 | case 'Q': 357 | { 358 | uint64_t v = _ulong(L, 3); 359 | lua_settop(L, 1); 360 | pack_fixed64(L, (uint8_t*)&v); 361 | break; 362 | } 363 | default: 364 | luaL_error(L, "Unknown, format"); 365 | } 366 | lua_call(L, 1, 0); 367 | return 0; 368 | } 369 | 370 | static size_t size_varint(const char* buffer, size_t len) 371 | { 372 | size_t pos = 0; 373 | while(buffer[pos] & 0x80) 374 | { 375 | ++pos; 376 | if(pos > len) 377 | { 378 | return -1; 379 | } 380 | } 381 | return pos+1; 382 | } 383 | 384 | static uint64_t unpack_varint(const char* buffer, size_t len) 385 | { 386 | uint64_t value = buffer[0] & 0x7f; 387 | size_t shift = 7; 388 | size_t pos=0; 389 | for(pos = 1; pos < len; ++pos) 390 | { 391 | value |= ((uint64_t)(buffer[pos] & 0x7f)) << shift; 392 | shift += 7; 393 | } 394 | return value; 395 | } 396 | 397 | static int varint_decoder(lua_State *L) 398 | { 399 | size_t len; 400 | const char* buffer = luaL_checklstring(L, 1, &len); 401 | size_t pos = luaL_checkinteger(L, 2); 402 | 403 | buffer += pos; 404 | len = size_varint(buffer, len); 405 | if(len == -1) 406 | { 407 | luaL_error(L, "error data %s, len:%d", buffer, len); 408 | } 409 | else 410 | { 411 | lua_pushnumber(L, (lua_Number)unpack_varint(buffer, len)); 412 | lua_pushinteger(L, len + pos); 413 | } 414 | return 2; 415 | } 416 | 417 | static int varint_decoder64(lua_State *L) 418 | { 419 | size_t len; 420 | const char* buffer = luaL_checklstring(L, 1, &len); 421 | size_t pos = luaL_checkinteger(L, 2); 422 | 423 | buffer += pos; 424 | len = size_varint(buffer, len); 425 | if(len == -1) 426 | { 427 | luaL_error(L, "error data %s, len:%d", buffer, len); 428 | } 429 | else 430 | { 431 | char buf[64]; 432 | sprintf(buf, "%" PRIu64, unpack_varint(buffer, len)); 433 | lua_pushstring(L, buf); 434 | lua_pushinteger(L, len + pos); 435 | } 436 | return 2; 437 | } 438 | 439 | static int signed_varint_decoder(lua_State *L) 440 | { 441 | size_t len; 442 | const char* buffer = luaL_checklstring(L, 1, &len); 443 | size_t pos = luaL_checkinteger(L, 2); 444 | buffer += pos; 445 | len = size_varint(buffer, len); 446 | 447 | if(len == -1) 448 | { 449 | luaL_error(L, "error data %s, len:%d", buffer, len); 450 | } 451 | else 452 | { 453 | lua_pushnumber(L, (lua_Number)(int64_t)unpack_varint(buffer, len)); 454 | lua_pushinteger(L, len + pos); 455 | } 456 | return 2; 457 | } 458 | 459 | static int signed_varint_decoder64(lua_State *L) 460 | { 461 | size_t len; 462 | const char* buffer = luaL_checklstring(L, 1, &len); 463 | size_t pos = luaL_checkinteger(L, 2); 464 | buffer += pos; 465 | len = size_varint(buffer, len); 466 | 467 | if(len == -1) 468 | { 469 | luaL_error(L, "error data %s, len:%d", buffer, len); 470 | } 471 | else 472 | { 473 | char buf[64]; 474 | sprintf(buf, "%" PRId64, (int64_t)unpack_varint(buffer, len)); 475 | lua_pushstring(L, buf); 476 | lua_pushinteger(L, len + pos); 477 | } 478 | return 2; 479 | } 480 | 481 | static int zig_zag_encode32(lua_State *L) 482 | { 483 | int32_t n = (int)luaL_checkinteger(L, 1); 484 | uint32_t value = (n << 1) ^ (n >> 31); 485 | lua_pushinteger(L, value); 486 | return 1; 487 | } 488 | 489 | static int zig_zag_decode32(lua_State *L) 490 | { 491 | uint32_t n = (uint32_t)luaL_checkinteger(L, 1); 492 | int32_t value = (n >> 1) ^ - (int32_t)(n & 1); 493 | lua_pushinteger(L, value); 494 | return 1; 495 | } 496 | 497 | static uint64_t umaxint = (((uint64_t)1) << (8*sizeof(int32_t))) - 1; 498 | static int64_t maxint = (((int64_t)1) << (8*sizeof(int32_t)-1)) - 1; 499 | 500 | static int zig_zag_encode64(lua_State *L) 501 | { 502 | int64_t n = (int64_t)luaL_checknumber(L, 1); 503 | uint64_t value = (n << 1) ^ (n >> 63); 504 | 505 | if (sizeof(lua_Integer) < 8 && value > umaxint) 506 | { 507 | luaL_error(L, "integer (%llu) out of range", value); 508 | return 0; 509 | } 510 | else 511 | { 512 | char temp[64]; 513 | sprintf(temp, "%" PRIu64, value); 514 | lua_pushstring(L, temp); 515 | return 1; 516 | } 517 | } 518 | 519 | static int zig_zag_decode64(lua_State *L) 520 | { 521 | uint64_t n = (uint64_t)luaL_checknumber(L, 1); 522 | int64_t value = (n >> 1) ^ - (int64_t)(n & 1); 523 | 524 | if (sizeof(lua_Integer) < 8 && (value > maxint || value < (-maxint-1))) 525 | { 526 | luaL_error(L, "integer (%ll) out of range", value); 527 | return 0; 528 | } 529 | else 530 | { 531 | char temp[64]; 532 | sprintf(temp, "%" PRId64, value); 533 | lua_pushstring(L, temp); 534 | return 1; 535 | } 536 | } 537 | 538 | static int read_tag(lua_State *L) 539 | { 540 | size_t len; 541 | const char* buffer = luaL_checklstring(L, 1, &len); 542 | size_t pos = luaL_checkinteger(L, 2); 543 | 544 | buffer += pos; 545 | len = size_varint(buffer, len); 546 | 547 | if(len == -1) 548 | { 549 | luaL_error(L, "error data %s, len:%d", buffer, len); 550 | } 551 | else 552 | { 553 | lua_pushlstring(L, buffer, len); 554 | lua_pushinteger(L, len + pos); 555 | } 556 | return 2; 557 | } 558 | 559 | static const uint8_t* unpack_fixed32(const uint8_t* buffer, uint8_t* cache) 560 | { 561 | #ifdef IS_LITTLE_ENDIAN 562 | return buffer; 563 | #else 564 | *(uint32_t UNALIGNED*)cache = le32toh(*(uint32_t UNALIGNED*)buffer); 565 | return cache; 566 | #endif 567 | } 568 | 569 | static const uint8_t* unpack_fixed64(const uint8_t* buffer, uint8_t* cache) 570 | { 571 | #ifdef IS_LITTLE_ENDIAN 572 | return buffer; 573 | #else 574 | *(uint64_t UNALIGNED*)cache = le64toh(*(uint64_t UNALIGNED*)buffer); 575 | return cache; 576 | #endif 577 | } 578 | 579 | static int struct_unpack(lua_State *L) 580 | { 581 | uint8_t format = luaL_checkinteger(L, 1); 582 | size_t len; 583 | const uint8_t* buffer = (uint8_t*)luaL_checklstring(L, 2, &len); 584 | size_t pos = luaL_checkinteger(L, 3); 585 | uint8_t out[8]; 586 | buffer += pos; 587 | 588 | switch(format) 589 | { 590 | case 'i': 591 | { 592 | lua_pushinteger(L, __ld32(unpack_fixed32(buffer, out))); 593 | break; 594 | } 595 | case 'q': 596 | { 597 | char temp[64]; 598 | int64_t n = __ld64(unpack_fixed64(buffer, out)); 599 | sprintf(temp, "%" PRId64, n); 600 | lua_pushstring(L, temp); 601 | break; 602 | } 603 | case 'f': 604 | { 605 | lua_pushnumber(L, (lua_Number)__ldf(unpack_fixed32(buffer, out))); 606 | break; 607 | } 608 | case 'd': 609 | { 610 | lua_pushnumber(L, (lua_Number)__ldd(unpack_fixed64(buffer, out))); 611 | break; 612 | } 613 | case 'I': 614 | { 615 | lua_pushnumber(L, (lua_Number)__uld32(unpack_fixed32(buffer, out))); 616 | break; 617 | } 618 | case 'Q': 619 | { 620 | char temp[64]; 621 | uint64_t n = __uld64(unpack_fixed64(buffer, out)); 622 | sprintf(temp, "%" PRIu64, n); 623 | lua_pushstring(L, temp); 624 | break; 625 | } 626 | default: 627 | luaL_error(L, "Unknown, format"); 628 | } 629 | return 1; 630 | } 631 | 632 | static int iostring_new(lua_State* L) 633 | { 634 | IOString* io = (IOString*)lua_newuserdata(L, sizeof(IOString)); 635 | io->size = 0; 636 | 637 | luaL_getmetatable(L, IOSTRING_META); 638 | lua_setmetatable(L, -2); 639 | return 1; 640 | } 641 | 642 | static int iostring_str(lua_State* L) 643 | { 644 | IOString *io = checkiostring(L); 645 | lua_pushlstring(L, io->buf, io->size); 646 | return 1; 647 | } 648 | 649 | static int iostring_len(lua_State* L) 650 | { 651 | IOString *io = checkiostring(L); 652 | lua_pushinteger(L, io->size); 653 | return 1; 654 | } 655 | 656 | static int iostring_write(lua_State* L) 657 | { 658 | IOString *io = checkiostring(L); 659 | size_t size; 660 | const char* str = luaL_checklstring(L, 2, &size); 661 | 662 | if(io->size + size > IOSTRING_BUF_LEN) 663 | { 664 | luaL_error(L, "Out of range"); 665 | } 666 | 667 | memcpy(io->buf + io->size, str, size); 668 | io->size += size; 669 | return 0; 670 | } 671 | 672 | static int iostring_sub(lua_State* L) 673 | { 674 | IOString *io = checkiostring(L); 675 | size_t begin = luaL_checkinteger(L, 2); 676 | size_t end = luaL_checkinteger(L, 3); 677 | 678 | if(begin > end || end > io->size) 679 | { 680 | luaL_error(L, "Out of range"); 681 | } 682 | 683 | lua_pushlstring(L, io->buf + begin - 1, end - begin + 1); 684 | return 1; 685 | } 686 | 687 | static int iostring_clear(lua_State* L) 688 | { 689 | IOString *io = checkiostring(L); 690 | io->size = 0; 691 | return 0; 692 | } 693 | 694 | static int varint_size(lua_State* L) 695 | { 696 | uint64_t value = _ulong(L, 1); 697 | 698 | if (value <= 0x7f) lua_pushnumber(L, 1); 699 | else if (value <= 0x3fff) lua_pushnumber(L, 2); 700 | else if (value <= 0x1fffff) lua_pushnumber(L, 3); 701 | else if (value <= 0xfffffff) lua_pushnumber(L, 4); 702 | else if (value <= 0x7ffffffff) lua_pushnumber(L, 5); 703 | else if (value <= 0x3ffffffffff) lua_pushnumber(L, 6); 704 | else if (value <= 0x1ffffffffffff) lua_pushnumber(L, 7); 705 | else if (value <= 0xffffffffffffff) lua_pushnumber(L, 8); 706 | else if (value <= 0x7fffffffffffffff) lua_pushnumber(L, 9); 707 | else lua_pushnumber(L, 10); 708 | 709 | return 1; 710 | } 711 | 712 | static int signed_varint_size(lua_State* L) 713 | { 714 | int64_t value = _long(L, 1); 715 | 716 | if (value < 0) lua_pushnumber(L, 10); 717 | else if (value <= 0x7f) lua_pushnumber(L, 1); 718 | else if (value <= 0x3fff) lua_pushnumber(L, 2); 719 | else if (value <= 0x1fffff) lua_pushnumber(L, 3); 720 | else if (value <= 0xfffffff) lua_pushnumber(L, 4); 721 | else if (value <= 0x7ffffffff) lua_pushnumber(L, 5); 722 | else if (value <= 0x3ffffffffff) lua_pushnumber(L, 6); 723 | else if (value <= 0x1ffffffffffff) lua_pushnumber(L, 7); 724 | else if (value <= 0xffffffffffffff) lua_pushnumber(L, 8); 725 | else if (value <= 0x7fffffffffffffff) lua_pushnumber(L, 9); 726 | else lua_pushnumber(L, 10); 727 | 728 | return 1; 729 | } 730 | 731 | static const struct luaL_Reg _pb [] = 732 | { 733 | {"varint_encoder", varint_encoder}, 734 | {"varint_encoder64", varint_encoder64}, 735 | {"signed_varint_encoder", signed_varint_encoder}, 736 | {"signed_varint_encoder64", signed_varint_encoder64}, 737 | {"read_tag", read_tag}, 738 | {"struct_pack", struct_pack}, 739 | {"struct_unpack", struct_unpack}, 740 | {"varint_decoder", varint_decoder}, 741 | {"varint_decoder64", varint_decoder64}, 742 | {"signed_varint_decoder", signed_varint_decoder}, 743 | {"signed_varint_decoder64", signed_varint_decoder64}, 744 | {"zig_zag_decode32", zig_zag_decode32}, 745 | {"zig_zag_encode32", zig_zag_encode32}, 746 | {"zig_zag_decode64", zig_zag_decode64}, 747 | {"zig_zag_encode64", zig_zag_encode64}, 748 | {"new_iostring", iostring_new}, 749 | {"varint_size", varint_size}, 750 | {"signed_varint_size", signed_varint_size}, 751 | {NULL, NULL} 752 | }; 753 | 754 | static const struct luaL_Reg _c_iostring_m [] = 755 | { 756 | {"__tostring", iostring_str}, 757 | {"__len", iostring_len}, 758 | {"write", iostring_write}, 759 | {"sub", iostring_sub}, 760 | {"clear", iostring_clear}, 761 | {NULL, NULL} 762 | }; 763 | 764 | LUALIB_API int luaopen_pb (lua_State *L) 765 | { 766 | luaL_newmetatable(L, IOSTRING_META); 767 | lua_pushvalue(L, -1); 768 | lua_setfield(L, -2, "__index"); 769 | luaL_register(L, NULL, _c_iostring_m); 770 | 771 | luaL_register(L, "pb", _pb); 772 | return 1; 773 | } 774 | -------------------------------------------------------------------------------- /protobuf/protobuf.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -------------------------------------------------------------------------------- 3 | -- FILE: protobuf.lua 4 | -- DESCRIPTION: protoc-gen-lua 5 | -- Google's Protocol Buffers project, ported to lua. 6 | -- https://code.google.com/p/protoc-gen-lua/ 7 | -- 8 | -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com 9 | -- All rights reserved. 10 | -- 11 | -- Use, modification and distribution are subject to the "New BSD License" 12 | -- as listed at . 13 | -- 14 | -- COMPANY: NetEase 15 | -- CREATED: 2010年07月29日 14时30分02秒 CST 16 | -------------------------------------------------------------------------------- 17 | -- 18 | 19 | local setmetatable = setmetatable 20 | local rawset = rawset 21 | local rawget = rawget 22 | local error = error 23 | local ipairs = ipairs 24 | local pairs = pairs 25 | local print = print 26 | local table = table 27 | local string = string 28 | local tostring = tostring 29 | local type = type 30 | 31 | local pb = require "pb" 32 | local wire_format = require "protobuf.wire_format" 33 | local type_checkers = require "protobuf.type_checkers" 34 | local encoder = require "protobuf.encoder" 35 | local decoder = require "protobuf.decoder" 36 | local listener_mod = require "protobuf.listener" 37 | local containers = require "protobuf.containers" 38 | local descriptor = require "protobuf.descriptor" 39 | local FieldDescriptor = descriptor.FieldDescriptor 40 | local text_format = require "protobuf.text_format" 41 | 42 | module("protobuf.protobuf") 43 | 44 | local function make_descriptor(name, descriptor, usable_key) 45 | local meta = { 46 | __newindex = function(self, key, value) 47 | if usable_key[key] then 48 | rawset(self, key, value) 49 | else 50 | error("error key: "..key) 51 | end 52 | end 53 | }; 54 | meta.__index = meta 55 | meta.__call = function() 56 | return setmetatable({}, meta) 57 | end 58 | 59 | _M[name] = setmetatable(descriptor, meta); 60 | end 61 | 62 | 63 | make_descriptor("Descriptor", {}, { 64 | name = true, 65 | full_name = true, 66 | filename = true, 67 | containing_type = true, 68 | fields = true, 69 | nested_types = true, 70 | enum_types = true, 71 | extensions = true, 72 | options = true, 73 | is_extendable = true, 74 | extension_ranges = true, 75 | }) 76 | 77 | make_descriptor("FieldDescriptor", FieldDescriptor, { 78 | name = true, 79 | full_name = true, 80 | index = true, 81 | number = true, 82 | type = true, 83 | cpp_type = true, 84 | label = true, 85 | has_default_value = true, 86 | default_value = true, 87 | containing_type = true, 88 | message_type = true, 89 | enum_type = true, 90 | is_extension = true, 91 | extension_scope = true, 92 | }) 93 | 94 | make_descriptor("EnumDescriptor", {}, { 95 | name = true, 96 | full_name = true, 97 | values = true, 98 | containing_type = true, 99 | options = true 100 | }) 101 | 102 | make_descriptor("EnumValueDescriptor", {}, { 103 | name = true, 104 | index = true, 105 | number = true, 106 | type = true, 107 | options = true 108 | }) 109 | 110 | -- Maps from field type to expected wiretype. 111 | local FIELD_TYPE_TO_WIRE_TYPE = { 112 | [FieldDescriptor.TYPE_DOUBLE] = wire_format.WIRETYPE_FIXED64, 113 | [FieldDescriptor.TYPE_FLOAT] = wire_format.WIRETYPE_FIXED32, 114 | [FieldDescriptor.TYPE_INT64] = wire_format.WIRETYPE_VARINT, 115 | [FieldDescriptor.TYPE_UINT64] = wire_format.WIRETYPE_VARINT, 116 | [FieldDescriptor.TYPE_INT32] = wire_format.WIRETYPE_VARINT, 117 | [FieldDescriptor.TYPE_FIXED64] = wire_format.WIRETYPE_FIXED64, 118 | [FieldDescriptor.TYPE_FIXED32] = wire_format.WIRETYPE_FIXED32, 119 | [FieldDescriptor.TYPE_BOOL] = wire_format.WIRETYPE_VARINT, 120 | [FieldDescriptor.TYPE_STRING] = wire_format.WIRETYPE_LENGTH_DELIMITED, 121 | [FieldDescriptor.TYPE_GROUP] = wire_format.WIRETYPE_START_GROUP, 122 | [FieldDescriptor.TYPE_MESSAGE] = wire_format.WIRETYPE_LENGTH_DELIMITED, 123 | [FieldDescriptor.TYPE_BYTES] = wire_format.WIRETYPE_LENGTH_DELIMITED, 124 | [FieldDescriptor.TYPE_UINT32] = wire_format.WIRETYPE_VARINT, 125 | [FieldDescriptor.TYPE_ENUM] = wire_format.WIRETYPE_VARINT, 126 | [FieldDescriptor.TYPE_SFIXED32] = wire_format.WIRETYPE_FIXED32, 127 | [FieldDescriptor.TYPE_SFIXED64] = wire_format.WIRETYPE_FIXED64, 128 | [FieldDescriptor.TYPE_SINT32] = wire_format.WIRETYPE_VARINT, 129 | [FieldDescriptor.TYPE_SINT64] = wire_format.WIRETYPE_VARINT 130 | } 131 | 132 | local NON_PACKABLE_TYPES = { 133 | [FieldDescriptor.TYPE_STRING] = true, 134 | [FieldDescriptor.TYPE_GROUP] = true, 135 | [FieldDescriptor.TYPE_MESSAGE] = true, 136 | [FieldDescriptor.TYPE_BYTES] = true 137 | } 138 | 139 | local _VALUE_CHECKERS = { 140 | [FieldDescriptor.CPPTYPE_INT32] = type_checkers.Int32ValueChecker(), 141 | [FieldDescriptor.CPPTYPE_INT64] = type_checkers.TypeChecker({string = true, number = true}), 142 | [FieldDescriptor.CPPTYPE_UINT32] = type_checkers.Uint32ValueChecker(), 143 | [FieldDescriptor.CPPTYPE_UINT64] = type_checkers.TypeChecker({string = true, number = true}), 144 | [FieldDescriptor.CPPTYPE_DOUBLE] = type_checkers.TypeChecker({number = true}), 145 | [FieldDescriptor.CPPTYPE_FLOAT] = type_checkers.TypeChecker({number = true}), 146 | [FieldDescriptor.CPPTYPE_BOOL] = type_checkers.TypeChecker({boolean = true, bool = true, int=true}), 147 | [FieldDescriptor.CPPTYPE_ENUM] = type_checkers.Int32ValueChecker(), 148 | [FieldDescriptor.CPPTYPE_STRING] = type_checkers.TypeChecker({string = true}) 149 | } 150 | 151 | 152 | local TYPE_TO_BYTE_SIZE_FN = { 153 | [FieldDescriptor.TYPE_DOUBLE] = wire_format.DoubleByteSize, 154 | [FieldDescriptor.TYPE_FLOAT] = wire_format.FloatByteSize, 155 | [FieldDescriptor.TYPE_INT64] = wire_format.Int64ByteSize, 156 | [FieldDescriptor.TYPE_UINT64] = wire_format.UInt64ByteSize, 157 | [FieldDescriptor.TYPE_INT32] = wire_format.Int32ByteSize, 158 | [FieldDescriptor.TYPE_FIXED64] = wire_format.Fixed64ByteSize, 159 | [FieldDescriptor.TYPE_FIXED32] = wire_format.Fixed32ByteSize, 160 | [FieldDescriptor.TYPE_BOOL] = wire_format.BoolByteSize, 161 | [FieldDescriptor.TYPE_STRING] = wire_format.StringByteSize, 162 | [FieldDescriptor.TYPE_GROUP] = wire_format.GroupByteSize, 163 | [FieldDescriptor.TYPE_MESSAGE] = wire_format.MessageByteSize, 164 | [FieldDescriptor.TYPE_BYTES] = wire_format.BytesByteSize, 165 | [FieldDescriptor.TYPE_UINT32] = wire_format.UInt32ByteSize, 166 | [FieldDescriptor.TYPE_ENUM] = wire_format.EnumByteSize, 167 | [FieldDescriptor.TYPE_SFIXED32] = wire_format.SFixed32ByteSize, 168 | [FieldDescriptor.TYPE_SFIXED64] = wire_format.SFixed64ByteSize, 169 | [FieldDescriptor.TYPE_SINT32] = wire_format.SInt32ByteSize, 170 | [FieldDescriptor.TYPE_SINT64] = wire_format.SInt64ByteSize 171 | } 172 | 173 | local TYPE_TO_ENCODER = { 174 | [FieldDescriptor.TYPE_DOUBLE] = encoder.DoubleEncoder, 175 | [FieldDescriptor.TYPE_FLOAT] = encoder.FloatEncoder, 176 | [FieldDescriptor.TYPE_INT64] = encoder.Int64Encoder, 177 | [FieldDescriptor.TYPE_UINT64] = encoder.UInt64Encoder, 178 | [FieldDescriptor.TYPE_INT32] = encoder.Int32Encoder, 179 | [FieldDescriptor.TYPE_FIXED64] = encoder.Fixed64Encoder, 180 | [FieldDescriptor.TYPE_FIXED32] = encoder.Fixed32Encoder, 181 | [FieldDescriptor.TYPE_BOOL] = encoder.BoolEncoder, 182 | [FieldDescriptor.TYPE_STRING] = encoder.StringEncoder, 183 | [FieldDescriptor.TYPE_GROUP] = encoder.GroupEncoder, 184 | [FieldDescriptor.TYPE_MESSAGE] = encoder.MessageEncoder, 185 | [FieldDescriptor.TYPE_BYTES] = encoder.BytesEncoder, 186 | [FieldDescriptor.TYPE_UINT32] = encoder.UInt32Encoder, 187 | [FieldDescriptor.TYPE_ENUM] = encoder.EnumEncoder, 188 | [FieldDescriptor.TYPE_SFIXED32] = encoder.SFixed32Encoder, 189 | [FieldDescriptor.TYPE_SFIXED64] = encoder.SFixed64Encoder, 190 | [FieldDescriptor.TYPE_SINT32] = encoder.SInt32Encoder, 191 | [FieldDescriptor.TYPE_SINT64] = encoder.SInt64Encoder 192 | } 193 | 194 | local TYPE_TO_SIZER = { 195 | [FieldDescriptor.TYPE_DOUBLE] = encoder.DoubleSizer, 196 | [FieldDescriptor.TYPE_FLOAT] = encoder.FloatSizer, 197 | [FieldDescriptor.TYPE_INT64] = encoder.Int64Sizer, 198 | [FieldDescriptor.TYPE_UINT64] = encoder.UInt64Sizer, 199 | [FieldDescriptor.TYPE_INT32] = encoder.Int32Sizer, 200 | [FieldDescriptor.TYPE_FIXED64] = encoder.Fixed64Sizer, 201 | [FieldDescriptor.TYPE_FIXED32] = encoder.Fixed32Sizer, 202 | [FieldDescriptor.TYPE_BOOL] = encoder.BoolSizer, 203 | [FieldDescriptor.TYPE_STRING] = encoder.StringSizer, 204 | [FieldDescriptor.TYPE_GROUP] = encoder.GroupSizer, 205 | [FieldDescriptor.TYPE_MESSAGE] = encoder.MessageSizer, 206 | [FieldDescriptor.TYPE_BYTES] = encoder.BytesSizer, 207 | [FieldDescriptor.TYPE_UINT32] = encoder.UInt32Sizer, 208 | [FieldDescriptor.TYPE_ENUM] = encoder.EnumSizer, 209 | [FieldDescriptor.TYPE_SFIXED32] = encoder.SFixed32Sizer, 210 | [FieldDescriptor.TYPE_SFIXED64] = encoder.SFixed64Sizer, 211 | [FieldDescriptor.TYPE_SINT32] = encoder.SInt32Sizer, 212 | [FieldDescriptor.TYPE_SINT64] = encoder.SInt64Sizer 213 | } 214 | 215 | local TYPE_TO_DECODER = { 216 | [FieldDescriptor.TYPE_DOUBLE] = decoder.DoubleDecoder, 217 | [FieldDescriptor.TYPE_FLOAT] = decoder.FloatDecoder, 218 | [FieldDescriptor.TYPE_INT64] = decoder.Int64Decoder, 219 | [FieldDescriptor.TYPE_UINT64] = decoder.UInt64Decoder, 220 | [FieldDescriptor.TYPE_INT32] = decoder.Int32Decoder, 221 | [FieldDescriptor.TYPE_FIXED64] = decoder.Fixed64Decoder, 222 | [FieldDescriptor.TYPE_FIXED32] = decoder.Fixed32Decoder, 223 | [FieldDescriptor.TYPE_BOOL] = decoder.BoolDecoder, 224 | [FieldDescriptor.TYPE_STRING] = decoder.StringDecoder, 225 | [FieldDescriptor.TYPE_GROUP] = decoder.GroupDecoder, 226 | [FieldDescriptor.TYPE_MESSAGE] = decoder.MessageDecoder, 227 | [FieldDescriptor.TYPE_BYTES] = decoder.BytesDecoder, 228 | [FieldDescriptor.TYPE_UINT32] = decoder.UInt32Decoder, 229 | [FieldDescriptor.TYPE_ENUM] = decoder.EnumDecoder, 230 | [FieldDescriptor.TYPE_SFIXED32] = decoder.SFixed32Decoder, 231 | [FieldDescriptor.TYPE_SFIXED64] = decoder.SFixed64Decoder, 232 | [FieldDescriptor.TYPE_SINT32] = decoder.SInt32Decoder, 233 | [FieldDescriptor.TYPE_SINT64] = decoder.SInt64Decoder 234 | } 235 | 236 | local FIELD_TYPE_TO_WIRE_TYPE = { 237 | [FieldDescriptor.TYPE_DOUBLE] = wire_format.WIRETYPE_FIXED64, 238 | [FieldDescriptor.TYPE_FLOAT] = wire_format.WIRETYPE_FIXED32, 239 | [FieldDescriptor.TYPE_INT64] = wire_format.WIRETYPE_VARINT, 240 | [FieldDescriptor.TYPE_UINT64] = wire_format.WIRETYPE_VARINT, 241 | [FieldDescriptor.TYPE_INT32] = wire_format.WIRETYPE_VARINT, 242 | [FieldDescriptor.TYPE_FIXED64] = wire_format.WIRETYPE_FIXED64, 243 | [FieldDescriptor.TYPE_FIXED32] = wire_format.WIRETYPE_FIXED32, 244 | [FieldDescriptor.TYPE_BOOL] = wire_format.WIRETYPE_VARINT, 245 | [FieldDescriptor.TYPE_STRING] = wire_format.WIRETYPE_LENGTH_DELIMITED, 246 | [FieldDescriptor.TYPE_GROUP] = wire_format.WIRETYPE_START_GROUP, 247 | [FieldDescriptor.TYPE_MESSAGE] = wire_format.WIRETYPE_LENGTH_DELIMITED, 248 | [FieldDescriptor.TYPE_BYTES] = wire_format.WIRETYPE_LENGTH_DELIMITED, 249 | [FieldDescriptor.TYPE_UINT32] = wire_format.WIRETYPE_VARINT, 250 | [FieldDescriptor.TYPE_ENUM] = wire_format.WIRETYPE_VARINT, 251 | [FieldDescriptor.TYPE_SFIXED32] = wire_format.WIRETYPE_FIXED32, 252 | [FieldDescriptor.TYPE_SFIXED64] = wire_format.WIRETYPE_FIXED64, 253 | [FieldDescriptor.TYPE_SINT32] = wire_format.WIRETYPE_VARINT, 254 | [FieldDescriptor.TYPE_SINT64] = wire_format.WIRETYPE_VARINT 255 | } 256 | 257 | local function IsTypePackable(field_type) 258 | return NON_PACKABLE_TYPES[field_type] == nil 259 | end 260 | 261 | local function GetTypeChecker(cpp_type, field_type) 262 | if (cpp_type == FieldDescriptor.CPPTYPE_STRING and field_type == FieldDescriptor.TYPE_STRING) then 263 | return type_checkers.UnicodeValueChecker() 264 | end 265 | return _VALUE_CHECKERS[cpp_type] 266 | end 267 | 268 | local function _DefaultValueConstructorForField(field) 269 | if field.label == FieldDescriptor.LABEL_REPEATED then 270 | if type(field.default_value) ~= "table" or #(field.default_value) ~= 0 then 271 | error('Repeated field default value not empty list:' .. tostring(field.default_value)) 272 | end 273 | if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then 274 | local message_type = field.message_type 275 | return function (message) 276 | return containers.RepeatedCompositeFieldContainer(message._listener_for_children, message_type) 277 | end 278 | else 279 | local type_checker = GetTypeChecker(field.cpp_type, field.type) 280 | return function (message) 281 | return containers.RepeatedScalarFieldContainer(message._listener_for_children, type_checker) 282 | end 283 | end 284 | end 285 | if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then 286 | local message_type = field.message_type 287 | return function (message) 288 | result = message_type._concrete_class() 289 | result._SetListener(message._listener_for_children) 290 | return result 291 | end 292 | end 293 | return function (message) 294 | return field.default_value 295 | end 296 | end 297 | 298 | local function _AttachFieldHelpers(message_meta, field_descriptor) 299 | local is_repeated = (field_descriptor.label == FieldDescriptor.LABEL_REPEATED) 300 | local is_packed = (field_descriptor.has_options and field_descriptor.GetOptions().packed) 301 | 302 | rawset(field_descriptor, "_encoder", TYPE_TO_ENCODER[field_descriptor.type](field_descriptor.number, is_repeated, is_packed)) 303 | rawset(field_descriptor, "_sizer", TYPE_TO_SIZER[field_descriptor.type](field_descriptor.number, is_repeated, is_packed)) 304 | rawset(field_descriptor, "_default_constructor", _DefaultValueConstructorForField(field_descriptor)) 305 | 306 | local AddDecoder = function(wiretype, is_packed) 307 | local tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype) 308 | message_meta._decoders_by_tag[tag_bytes] = TYPE_TO_DECODER[field_descriptor.type](field_descriptor.number, is_repeated, is_packed, field_descriptor, field_descriptor._default_constructor) 309 | end 310 | 311 | AddDecoder(FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], False) 312 | if is_repeated and IsTypePackable(field_descriptor.type) then 313 | AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True) 314 | end 315 | end 316 | 317 | local function _AddEnumValues(descriptor, message_meta) 318 | for _, enum_type in ipairs(descriptor.enum_types) do 319 | for _, enum_value in ipairs(enum_type.values) do 320 | message_meta._member[enum_value.name] = enum_value.number 321 | end 322 | end 323 | end 324 | 325 | local function _InitMethod(message_meta) 326 | return function() 327 | local self = {} 328 | self._cached_byte_size = 0 329 | self._cached_byte_size_dirty = false 330 | self._fields = {} 331 | self._is_present_in_parent = false 332 | self._listener = listener_mod.NullMessageListener() 333 | self._listener_for_children = listener_mod.Listener(self) 334 | return setmetatable(self, message_meta) 335 | end 336 | end 337 | 338 | local function _AddPropertiesForRepeatedField(field, message_meta) 339 | local property_name = field.name 340 | 341 | message_meta._getter[property_name] = function(self) 342 | local field_value = self._fields[field] 343 | if field_value == nil then 344 | field_value = field._default_constructor(self) 345 | self._fields[field] = field_value 346 | 347 | if not self._cached_byte_size_dirty then 348 | message_meta._member._Modified(self) 349 | end 350 | end 351 | return field_value 352 | end 353 | 354 | message_meta._setter[property_name] = function(self) 355 | error('Assignment not allowed to repeated field "' .. property_name .. '" in protocol message object.') 356 | end 357 | end 358 | 359 | local function _AddPropertiesForNonRepeatedCompositeField(field, message_meta) 360 | local property_name = field.name 361 | local message_type = field.message_type 362 | 363 | message_meta._getter[property_name] = function(self) 364 | local field_value = self._fields[field] 365 | if field_value == nil then 366 | field_value = message_type._concrete_class() 367 | field_value:_SetListener(self._listener_for_children) 368 | self._fields[field] = field_value 369 | 370 | if not self._cached_byte_size_dirty then 371 | message_meta._member._Modified(self) 372 | end 373 | end 374 | return field_value 375 | end 376 | message_meta._setter[property_name] = function(self, new_value) 377 | error('Assignment not allowed to composite field' .. property_name .. 'in protocol message object.' ) 378 | end 379 | end 380 | 381 | local function _AddPropertiesForNonRepeatedScalarField(field, message) 382 | local property_name = field.name 383 | local type_checker = GetTypeChecker(field.cpp_type, field.type) 384 | local default_value = field.default_value 385 | 386 | message._getter[property_name] = function(self) 387 | local value = self._fields[field] 388 | if value ~= nil then 389 | return self._fields[field] 390 | else 391 | return default_value 392 | end 393 | end 394 | 395 | message._setter[property_name] = function(self, new_value) 396 | type_checker(new_value) 397 | self._fields[field] = new_value 398 | if not self._cached_byte_size_dirty then 399 | message._member._Modified(self) 400 | end 401 | end 402 | end 403 | 404 | local function _AddPropertiesForField(field, message_meta) 405 | constant_name = field.name:upper() .. "_FIELD_NUMBER" 406 | message_meta._member[constant_name] = field.number 407 | 408 | if field.label == FieldDescriptor.LABEL_REPEATED then 409 | _AddPropertiesForRepeatedField(field, message_meta) 410 | elseif field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then 411 | _AddPropertiesForNonRepeatedCompositeField(field, message_meta) 412 | else 413 | _AddPropertiesForNonRepeatedScalarField(field, message_meta) 414 | end 415 | end 416 | 417 | local _ED_meta = { 418 | __index = function(self, extension_handle) 419 | local _extended_message = rawget(self, "_extended_message") 420 | local value = _extended_message._fields[extension_handle] 421 | if value ~= nil then 422 | return value 423 | end 424 | if extension_handle.label == FieldDescriptor.LABEL_REPEATED then 425 | value = extension_handle._default_constructor(self._extended_message) 426 | elseif extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then 427 | value = extension_handle.message_type._concrete_class() 428 | value:_SetListener(_extended_message._listener_for_children) 429 | else 430 | return extension_handle.default_value 431 | end 432 | _extended_message._fields[extension_handle] = value 433 | return value 434 | end, 435 | __newindex = function(self, extension_handle, value) 436 | local _extended_message = rawget(self, "_extended_message") 437 | if (extension_handle.label == FieldDescriptor.LABEL_REPEATED or 438 | extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE) then 439 | error('Cannot assign to extension "'.. extension_handle.full_name .. '" because it is a repeated or composite type.') 440 | end 441 | 442 | local type_checker = GetTypeChecker(extension_handle.cpp_type, extension_handle.type) 443 | type_checker.CheckValue(value) 444 | _extended_message._fields[extension_handle] = value 445 | _extended_message._Modified() 446 | end 447 | } 448 | 449 | local function _ExtensionDict(message) 450 | local o = {} 451 | o._extended_message = message 452 | return setmetatable(o, _ED_meta) 453 | end 454 | 455 | local function _AddPropertiesForFields(descriptor, message_meta) 456 | for _, field in ipairs(descriptor.fields) do 457 | _AddPropertiesForField(field, message_meta) 458 | end 459 | if descriptor.is_extendable then 460 | message_meta._getter.Extensions = function(self) return _ExtensionDict(self) end 461 | end 462 | end 463 | 464 | local function _AddPropertiesForExtensions(descriptor, message_meta) 465 | local extension_dict = descriptor._extensions_by_name 466 | for extension_name, extension_field in pairs(extension_dict) do 467 | local constant_name = string.upper(extension_name) .. "_FIELD_NUMBER" 468 | message_meta._member[constant_name] = extension_field.number 469 | end 470 | end 471 | 472 | local function _AddStaticMethods(message_meta) 473 | message_meta._member.RegisterExtension = function(extension_handle) 474 | extension_handle.containing_type = message_meta._descriptor 475 | _AttachFieldHelpers(message_meta, extension_handle) 476 | 477 | if message_meta._extensions_by_number[extension_handle.number] == nil then 478 | message_meta._extensions_by_number[extension_handle.number] = extension_handle 479 | else 480 | error( 481 | string.format('Extensions "%s" and "%s" both try to extend message type "%s" with field number %d.', 482 | extension_handle.full_name, actual_handle.full_name, 483 | message_meta._descriptor.full_name, extension_handle.number)) 484 | end 485 | message_meta._extensions_by_name[extension_handle.full_name] = extension_handle 486 | end 487 | 488 | message_meta._member.FromString = function(s) 489 | local message = message_meta._member.__call() 490 | message.MergeFromString(s) 491 | return message 492 | end 493 | end 494 | 495 | local function _IsPresent(descriptor, value) 496 | if descriptor.label == FieldDescriptor.LABEL_REPEATED then 497 | return value 498 | elseif descriptor.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then 499 | return value._is_present_in_parent 500 | else 501 | return true 502 | end 503 | end 504 | 505 | function sortFunc(a, b) 506 | return a.index < b.index 507 | end 508 | function pairsByKeys (t, f) 509 | local a = {} 510 | for n in pairs(t) do table.insert(a, n) end 511 | table.sort(a, f) 512 | local i = 0 -- iterator variable 513 | local iter = function () -- iterator function 514 | i = i + 1 515 | if a[i] == nil then return nil 516 | else return a[i], t[a[i]] 517 | end 518 | end 519 | return iter 520 | end 521 | 522 | local function _AddListFieldsMethod(message_descriptor, message_meta) 523 | message_meta._member.ListFields = function (self) 524 | local list_field = function(fields) 525 | --local f, s, v = pairs(self._fields) 526 | local f,s,v = pairsByKeys(self._fields, sortFunc) 527 | local iter = function(a, i) 528 | while true do 529 | local descriptor, value = f(a, i) 530 | if descriptor == nil then 531 | return 532 | elseif _IsPresent(descriptor, value) then 533 | return descriptor, value 534 | end 535 | end 536 | end 537 | return iter, s, v 538 | end 539 | return list_field(self._fields) 540 | end 541 | end 542 | 543 | local function _AddHasFieldMethod(message_descriptor, message_meta) 544 | local singular_fields = {} 545 | for _, field in ipairs(message_descriptor.fields) do 546 | if field.label ~= FieldDescriptor.LABEL_REPEATED then 547 | singular_fields[field.name] = field 548 | end 549 | end 550 | message_meta._member.HasField = function (self, field_name) 551 | field = singular_fields[field_name] 552 | if field == nil then 553 | error('Protocol message has no singular "'.. field_name.. '" field.') 554 | end 555 | if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then 556 | value = self._fields[field] 557 | return value ~= nil and value._is_present_in_parent 558 | else 559 | local valueTmp = self._fields[field] 560 | return valueTmp ~= nil 561 | end 562 | end 563 | end 564 | 565 | local function _AddClearFieldMethod(message_descriptor, message_meta) 566 | local singular_fields = {} 567 | for _, field in ipairs(message_descriptor.fields) do 568 | if field.label ~= FieldDescriptor.LABEL_REPEATED then 569 | singular_fields[field.name] = field 570 | end 571 | end 572 | 573 | message_meta._member.ClearField = function(self, field_name) 574 | field = singular_fields[field_name] 575 | if field == nil then 576 | error('Protocol message has no singular "'.. field_name.. '" field.') 577 | end 578 | 579 | if self._fields[field] then 580 | self._fields[field] = nil 581 | end 582 | message_meta._member._Modified(self) 583 | end 584 | end 585 | 586 | local function _AddClearExtensionMethod(message_meta) 587 | message_meta._member.ClearExtension = function(self, extension_handle) 588 | if self._fields[extension_handle] == nil then 589 | self._fields[extension_handle] = nil 590 | end 591 | message_meta._member._Modified(self) 592 | end 593 | end 594 | 595 | local function _AddClearMethod(message_descriptor, message_meta) 596 | message_meta._member.Clear = function(self) 597 | self._fields = {} 598 | message_meta._member._Modified(self) 599 | end 600 | end 601 | 602 | local function _AddStrMethod(message_meta) 603 | local format = text_format.msg_format 604 | message_meta.__tostring = function(self) 605 | return format(self) 606 | end 607 | end 608 | 609 | local function _AddHasExtensionMethod(message_meta) 610 | message_meta._member.HasExtension = function(self, extension_handle) 611 | if extension_handle.label == FieldDescriptor.LABEL_REPEATED then 612 | error(extension_handle.full_name .. ' is repeated.') 613 | end 614 | if extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then 615 | value = self._fields[extension_handle] 616 | return value ~= nil and value._is_present_in_parent 617 | else 618 | return self._fields[extension_handle] 619 | end 620 | end 621 | end 622 | 623 | local function _AddSetListenerMethod(message_meta) 624 | message_meta._member._SetListener = function(self, listener) 625 | if listener ~= nil then 626 | self._listener = listener_mod.NullMessageListener() 627 | else 628 | self._listener = listener 629 | end 630 | end 631 | end 632 | 633 | local function _AddByteSizeMethod(message_descriptor, message_meta) 634 | message_meta._member.ByteSize = function(self) 635 | --kaiser 636 | --bug:这里在Repeat字段的结构体如果第一个字段不是int变量会产生_cached_byte_size_dirty为false而导致byte size为0 637 | --如果bytesize为0让它强制计算byte size 638 | if not self._cached_byte_size_dirty and self._cached_byte_size > 0 then 639 | return self._cached_byte_size 640 | end 641 | local size = 0 642 | for field_descriptor, field_value in message_meta._member.ListFields(self) do 643 | size = field_descriptor._sizer(field_value) + size 644 | end 645 | self._cached_byte_size = size 646 | self._cached_byte_size_dirty = false 647 | self._listener_for_children.dirty = false 648 | return size 649 | end 650 | end 651 | 652 | local function _AddSerializeToStringMethod(message_descriptor, message_meta) 653 | message_meta._member.SerializeToString = function(self) 654 | if not message_meta._member.IsInitialized(self) then 655 | error('Message is missing required fields: ' .. 656 | table.concat(message_meta._member.FindInitializationErrors(self), ',')) 657 | end 658 | return message_meta._member.SerializePartialToString(self) 659 | end 660 | message_meta._member.SerializeToIOString = function(self, iostring) 661 | if not message_meta._member.IsInitialized(self) then 662 | error('Message is missing required fields: ' .. 663 | table.concat(message_meta._member.FindInitializationErrors(self), ',')) 664 | end 665 | return message_meta._member.SerializePartialToIOString(self, iostring) 666 | end 667 | end 668 | 669 | local function _AddSerializePartialToStringMethod(message_descriptor, message_meta) 670 | local concat = table.concat 671 | local _internal_serialize = function(self, write_bytes) 672 | for field_descriptor, field_value in message_meta._member.ListFields(self) do 673 | field_descriptor._encoder(write_bytes, field_value) 674 | end 675 | end 676 | 677 | local _serialize_partial_to_iostring = function(self, iostring) 678 | local w = iostring.write 679 | local write = function(value) 680 | w(iostring, value) 681 | end 682 | _internal_serialize(self, write) 683 | return 684 | end 685 | 686 | local _serialize_partial_to_string = function(self) 687 | local out = {} 688 | local write = function(value) 689 | out[#out + 1] = value 690 | end 691 | _internal_serialize(self, write) 692 | return concat(out) 693 | end 694 | 695 | message_meta._member._InternalSerialize = _internal_serialize 696 | message_meta._member.SerializePartialToIOString = _serialize_partial_to_iostring 697 | message_meta._member.SerializePartialToString = _serialize_partial_to_string 698 | end 699 | 700 | 701 | 702 | local function _AddMergeFromStringMethod(message_descriptor, message_meta) 703 | local ReadTag = decoder.ReadTag 704 | local SkipField = decoder.SkipField 705 | local decoders_by_tag = message_meta._decoders_by_tag 706 | 707 | local _internal_parse = function(self, buffer, pos, pend) 708 | message_meta._member._Modified(self) 709 | local field_dict = self._fields 710 | local tag_bytes, new_pos 711 | local field_decoder 712 | while pos ~= pend do 713 | tag_bytes, new_pos = ReadTag(buffer, pos) 714 | field_decoder = decoders_by_tag[tag_bytes] 715 | if field_decoder == nil then 716 | new_pos = SkipField(buffer, new_pos, pend, tag_bytes) 717 | if new_pos == -1 then 718 | return pos 719 | end 720 | pos = new_pos 721 | else 722 | pos = field_decoder(buffer, new_pos, pend, self, field_dict) 723 | end 724 | end 725 | return pos 726 | end 727 | message_meta._member._InternalParse = _internal_parse 728 | 729 | local merge_from_string = function(self, serialized) 730 | local length = #serialized 731 | if _internal_parse(self, serialized, 0, length) ~= length then 732 | error('Unexpected end-group tag.') 733 | end 734 | return length 735 | end 736 | message_meta._member.MergeFromString = merge_from_string 737 | 738 | message_meta._member.ParseFromString = function(self, serialized) 739 | message_meta._member.Clear(self) 740 | merge_from_string(self, serialized) 741 | end 742 | end 743 | 744 | local function _AddIsInitializedMethod(message_descriptor, message_meta) 745 | local required_fields = {} 746 | for _, field in ipairs(message_descriptor.fields) do 747 | if field.label == FieldDescriptor.LABEL_REQUIRED then 748 | required_fields[#required_fields + 1] = field 749 | end 750 | end 751 | 752 | message_meta._member.IsInitialized = function(self, errors) 753 | for _, field in ipairs(required_fields) do 754 | if self._fields[field] == nil or 755 | (field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE and not self._fields[field]._is_present_in_parent) then 756 | if errors ~= nil then 757 | errors[#errors + 1] = message_meta._member.FindInitializationErrors(self) 758 | end 759 | return false 760 | end 761 | end 762 | 763 | for field, value in pairs(self._fields) do 764 | if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then 765 | if field.label == FieldDescriptor.LABEL_REPEATED then 766 | for _, element in ipairs(value) do 767 | if not element:IsInitialized() then 768 | if errors ~= nil then 769 | errors[#errors + 1] = message_meta._member.FindInitializationErrors(self) 770 | end 771 | return false 772 | end 773 | end 774 | elseif value._is_present_in_parent and not value:IsInitialized() then 775 | if errors ~= nil then 776 | errors[#errors + 1] = message_meta._member.FindInitializationErrors(self) 777 | end 778 | return false 779 | end 780 | end 781 | end 782 | return true 783 | end 784 | 785 | message_meta._member.FindInitializationErrors = function(self) 786 | local errors = {} 787 | 788 | for _,field in ipairs(required_fields) do 789 | if not message_meta._member.HasField(self, field.name) then 790 | errors[#errors + 1] = field.name 791 | end 792 | end 793 | 794 | for field, value in message_meta._member.ListFields(self) do 795 | if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then 796 | if field.is_extension then 797 | name = string.format("(%s)", field.full_name) 798 | else 799 | name = field.name 800 | end 801 | if field.label == FieldDescriptor.LABEL_REPEATED then 802 | for i, element in ipairs(value) do 803 | prefix = string.format("%s[%d].", name, i) 804 | sub_errors = element:FindInitializationErrors() 805 | for _, e in ipairs(sub_errors) do 806 | errors[#errors + 1] = prefix .. e 807 | end 808 | end 809 | else 810 | prefix = name .. "." 811 | sub_errors = value:FindInitializationErrors() 812 | for _, e in ipairs(sub_errors) do 813 | errors[#errors + 1] = prefix .. e 814 | end 815 | end 816 | end 817 | end 818 | return errors 819 | end 820 | end 821 | 822 | local function _AddMergeFromMethod(message_meta) 823 | local LABEL_REPEATED = FieldDescriptor.LABEL_REPEATED 824 | local CPPTYPE_MESSAGE = FieldDescriptor.CPPTYPE_MESSAGE 825 | 826 | message_meta._member.MergeFrom = function (self, msg) 827 | assert(msg ~= self) 828 | message_meta._member._Modified(self) 829 | 830 | local fields = self._fields 831 | 832 | for field, value in pairs(msg._fields) do 833 | if field.label == LABEL_REPEATED or field.cpp_type == CPPTYPE_MESSAGE then 834 | field_value = fields[field] 835 | if field_value == nil then 836 | field_value = field._default_constructor(self) 837 | fields[field] = field_value 838 | end 839 | field_value:MergeFrom(value) 840 | else 841 | self._fields[field] = value 842 | end 843 | end 844 | end 845 | end 846 | 847 | local function _AddMessageMethods(message_descriptor, message_meta) 848 | _AddListFieldsMethod(message_descriptor, message_meta) 849 | _AddHasFieldMethod(message_descriptor, message_meta) 850 | _AddClearFieldMethod(message_descriptor, message_meta) 851 | if message_descriptor.is_extendable then 852 | _AddClearExtensionMethod(message_meta) 853 | _AddHasExtensionMethod(message_meta) 854 | end 855 | _AddClearMethod(message_descriptor, message_meta) 856 | -- _AddEqualsMethod(message_descriptor, message_meta) 857 | _AddStrMethod(message_meta) 858 | _AddSetListenerMethod(message_meta) 859 | _AddByteSizeMethod(message_descriptor, message_meta) 860 | _AddSerializeToStringMethod(message_descriptor, message_meta) 861 | _AddSerializePartialToStringMethod(message_descriptor, message_meta) 862 | _AddMergeFromStringMethod(message_descriptor, message_meta) 863 | _AddIsInitializedMethod(message_descriptor, message_meta) 864 | _AddMergeFromMethod(message_meta) 865 | end 866 | 867 | local function _AddPrivateHelperMethods(message_meta) 868 | local Modified = function (self) 869 | if not self._cached_byte_size_dirty then 870 | self._cached_byte_size_dirty = true 871 | self._listener_for_children.dirty = true 872 | self._is_present_in_parent = true 873 | self._listener:Modified() 874 | end 875 | end 876 | message_meta._member._Modified = Modified 877 | message_meta._member.SetInParent = Modified 878 | end 879 | 880 | local function property_getter(message_meta) 881 | local getter = message_meta._getter 882 | local member = message_meta._member 883 | 884 | return function (self, property) 885 | local g = getter[property] 886 | if g then 887 | return g(self) 888 | else 889 | return member[property] 890 | end 891 | end 892 | end 893 | 894 | local function property_setter(message_meta) 895 | local setter = message_meta._setter 896 | 897 | return function (self, property, value) 898 | local s = setter[property] 899 | if s then 900 | s(self, value) 901 | else 902 | error(property .. " not found") 903 | end 904 | end 905 | end 906 | 907 | function _AddClassAttributesForNestedExtensions(descriptor, message_meta) 908 | local extension_dict = descriptor._extensions_by_name 909 | for extension_name, extension_field in pairs(extension_dict) do 910 | message_meta._member[extension_name] = extension_field 911 | end 912 | end 913 | 914 | local function Message(descriptor) 915 | local message_meta = {} 916 | message_meta._decoders_by_tag = {} 917 | rawset(descriptor, "_extensions_by_name", {}) 918 | for _, k in ipairs(descriptor.extensions) do 919 | descriptor._extensions_by_name[k.name] = k 920 | end 921 | rawset(descriptor, "_extensions_by_number", {}) 922 | for _, k in ipairs(descriptor.extensions) do 923 | descriptor._extensions_by_number[k.number] = k 924 | end 925 | message_meta._descriptor = descriptor 926 | message_meta._extensions_by_name = {} 927 | message_meta._extensions_by_number = {} 928 | 929 | message_meta._getter = {} 930 | message_meta._setter = {} 931 | message_meta._member = {} 932 | -- message_meta._name = descriptor.full_name 933 | 934 | local ns = setmetatable({}, message_meta._member) 935 | message_meta._member.__call = _InitMethod(message_meta) 936 | message_meta._member.__index = message_meta._member 937 | message_meta._member.type = ns 938 | 939 | if rawget(descriptor, "_concrete_class") == nil then 940 | rawset(descriptor, "_concrete_class", ns) 941 | for k, field in ipairs(descriptor.fields) do 942 | _AttachFieldHelpers(message_meta, field) 943 | end 944 | end 945 | _AddEnumValues(descriptor, message_meta) 946 | _AddClassAttributesForNestedExtensions(descriptor, message_meta) 947 | _AddPropertiesForFields(descriptor, message_meta) 948 | _AddPropertiesForExtensions(descriptor, message_meta) 949 | _AddStaticMethods(message_meta) 950 | _AddMessageMethods(descriptor, message_meta) 951 | _AddPrivateHelperMethods(message_meta) 952 | 953 | message_meta.__index = property_getter(message_meta) 954 | message_meta.__newindex = property_setter(message_meta) 955 | 956 | return ns 957 | end 958 | 959 | _M.Message = Message 960 | 961 | -------------------------------------------------------------------------------- /protobuf/text_format.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -------------------------------------------------------------------------------- 3 | -- FILE: text_format.lua 4 | -- DESCRIPTION: protoc-gen-lua 5 | -- Google's Protocol Buffers project, ported to lua. 6 | -- https://code.google.com/p/protoc-gen-lua/ 7 | -- 8 | -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com 9 | -- All rights reserved. 10 | -- 11 | -- Use, modification and distribution are subject to the "New BSD License" 12 | -- as listed at . 13 | -- COMPANY: NetEase 14 | -- CREATED: 2010年08月05日 15时14分13秒 CST 15 | -------------------------------------------------------------------------------- 16 | -- 17 | local string = string 18 | local math = math 19 | local print = print 20 | local getmetatable = getmetatable 21 | local table = table 22 | local ipairs = ipairs 23 | local tostring = tostring 24 | 25 | local descriptor = require "protobuf.descriptor" 26 | 27 | module "protobuf.text_format" 28 | 29 | function format(buffer) 30 | local len = string.len( buffer ) 31 | for i = 1, len, 16 do 32 | local text = "" 33 | for j = i, math.min( i + 16 - 1, len ) do 34 | text = string.format( "%s %02x", text, string.byte( buffer, j ) ) 35 | end 36 | print( text ) 37 | end 38 | end 39 | 40 | local FieldDescriptor = descriptor.FieldDescriptor 41 | 42 | msg_format_indent = function(write, msg, indent) 43 | for field, value in msg:ListFields() do 44 | local print_field = function(field_value) 45 | local name = field.name 46 | write(string.rep(" ", indent)) 47 | if field.type == FieldDescriptor.TYPE_MESSAGE then 48 | local extensions = getmetatable(msg)._extensions_by_name 49 | if extensions[field.full_name] then 50 | write("[" .. name .. "] {\n") 51 | else 52 | write(name .. " {\n") 53 | end 54 | msg_format_indent(write, field_value, indent + 4) 55 | write(string.rep(" ", indent)) 56 | write("}\n") 57 | else 58 | write(string.format("%s: %s\n", name, tostring(field_value))) 59 | end 60 | end 61 | if field.label == FieldDescriptor.LABEL_REPEATED then 62 | for _, k in ipairs(value) do 63 | print_field(k) 64 | end 65 | else 66 | print_field(value) 67 | end 68 | end 69 | end 70 | 71 | function msg_format(msg) 72 | local out = {} 73 | local write = function(value) 74 | out[#out + 1] = value 75 | end 76 | msg_format_indent(write, msg, 0) 77 | return table.concat(out) 78 | end 79 | 80 | -------------------------------------------------------------------------------- /protobuf/type_checkers.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -------------------------------------------------------------------------------- 3 | -- FILE: type_checkers.lua 4 | -- DESCRIPTION: protoc-gen-lua 5 | -- Google's Protocol Buffers project, ported to lua. 6 | -- https://code.google.com/p/protoc-gen-lua/ 7 | -- 8 | -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com 9 | -- All rights reserved. 10 | -- 11 | -- Use, modification and distribution are subject to the "New BSD License" 12 | -- as listed at . 13 | -- 14 | -- COMPANY: NetEase 15 | -- CREATED: 2010年07月29日 19时30分37秒 CST 16 | -------------------------------------------------------------------------------- 17 | -- 18 | 19 | local type = type 20 | local error = error 21 | local string = string 22 | 23 | module "protobuf.type_checkers" 24 | 25 | function TypeChecker(acceptable_types) 26 | local acceptable_types = acceptable_types 27 | 28 | return function(proposed_value) 29 | local t = type(proposed_value) 30 | if acceptable_types[type(proposed_value)] == nil then 31 | error(string.format('%s has type %s, but expected one of: %s', 32 | proposed_value, type(proposed_value), acceptable_types)) 33 | end 34 | end 35 | end 36 | 37 | function Int32ValueChecker() 38 | local _MIN = -2147483648 39 | local _MAX = 2147483647 40 | return function(proposed_value) 41 | if type(proposed_value) ~= 'number' then 42 | error(string.format('%s has type %s, but expected one of: number', 43 | proposed_value, type(proposed_value))) 44 | end 45 | if _MIN > proposed_value or proposed_value > _MAX then 46 | error('Value out of range: ' .. proposed_value) 47 | end 48 | end 49 | end 50 | 51 | function Uint32ValueChecker(IntValueChecker) 52 | local _MIN = 0 53 | local _MAX = 0xffffffff 54 | 55 | return function(proposed_value) 56 | if type(proposed_value) ~= 'number' then 57 | error(string.format('%s has type %s, but expected one of: number', 58 | proposed_value, type(proposed_value))) 59 | end 60 | if _MIN > proposed_value or proposed_value > _MAX then 61 | error('Value out of range: ' .. proposed_value) 62 | end 63 | end 64 | end 65 | 66 | function UnicodeValueChecker() 67 | return function (proposed_value) 68 | if type(proposed_value) ~= 'string' then 69 | error(string.format('%s has type %s, but expected one of: string', proposed_value, type(proposed_value))) 70 | end 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /protobuf/wire_format.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -------------------------------------------------------------------------------- 3 | -- FILE: wire_format.lua 4 | -- DESCRIPTION: protoc-gen-lua 5 | -- Google's Protocol Buffers project, ported to lua. 6 | -- https://code.google.com/p/protoc-gen-lua/ 7 | -- 8 | -- Copyright (c) 2010 , 林卓毅 (Zhuoyi Lin) netsnail@gmail.com 9 | -- All rights reserved. 10 | -- 11 | -- Use, modification and distribution are subject to the "New BSD License" 12 | -- as listed at . 13 | -- COMPANY: NetEase 14 | -- CREATED: 2010年07月30日 15时59分53秒 CST 15 | -------------------------------------------------------------------------------- 16 | -- 17 | 18 | local pb = require "pb" 19 | module "protobuf.wire_format" 20 | 21 | WIRETYPE_VARINT = 0 22 | WIRETYPE_FIXED64 = 1 23 | WIRETYPE_LENGTH_DELIMITED = 2 24 | WIRETYPE_START_GROUP = 3 25 | WIRETYPE_END_GROUP = 4 26 | WIRETYPE_FIXED32 = 5 27 | _WIRETYPE_MAX = 5 28 | 29 | 30 | -- yeah, we don't need uint64 31 | local function _VarUInt64ByteSizeNoTag(uint64) 32 | if uint64 <= 0x7f then return 1 end 33 | if uint64 <= 0x3fff then return 2 end 34 | if uint64 <= 0x1fffff then return 3 end 35 | if uint64 <= 0xfffffff then return 4 end 36 | return 5 37 | end 38 | 39 | function PackTag(field_number, wire_type) 40 | return field_number * 8 + wire_type 41 | end 42 | 43 | function UnpackTag(tag) 44 | local wire_type = tag % 8 45 | return (tag - wire_type) / 8, wire_type 46 | end 47 | 48 | ZigZagEncode32 = pb.zig_zag_encode32 49 | ZigZagDecode32 = pb.zig_zag_decode32 50 | ZigZagEncode64 = pb.zig_zag_encode64 51 | ZigZagDecode64 = pb.zig_zag_decode64 52 | 53 | function Int32ByteSize(field_number, int32) 54 | return Int64ByteSize(field_number, int32) 55 | end 56 | 57 | function Int32ByteSizeNoTag(int32) 58 | return _VarUInt64ByteSizeNoTag(int32) 59 | end 60 | 61 | function Int64ByteSize(field_number, int64) 62 | return UInt64ByteSize(field_number, int64) 63 | end 64 | 65 | function UInt32ByteSize(field_number, uint32) 66 | return UInt64ByteSize(field_number, uint32) 67 | end 68 | 69 | function UInt64ByteSize(field_number, uint64) 70 | return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64) 71 | end 72 | 73 | function SInt32ByteSize(field_number, int32) 74 | return UInt32ByteSize(field_number, ZigZagEncode(int32)) 75 | end 76 | 77 | function SInt64ByteSize(field_number, int64) 78 | return UInt64ByteSize(field_number, ZigZagEncode(int64)) 79 | end 80 | 81 | function Fixed32ByteSize(field_number, fixed32) 82 | return TagByteSize(field_number) + 4 83 | end 84 | 85 | function Fixed64ByteSize(field_number, fixed64) 86 | return TagByteSize(field_number) + 8 87 | end 88 | 89 | function SFixed32ByteSize(field_number, sfixed32) 90 | return TagByteSize(field_number) + 4 91 | end 92 | 93 | function SFixed64ByteSize(field_number, sfixed64) 94 | return TagByteSize(field_number) + 8 95 | end 96 | 97 | function FloatByteSize(field_number, flt) 98 | return TagByteSize(field_number) + 4 99 | end 100 | 101 | function DoubleByteSize(field_number, double) 102 | return TagByteSize(field_number) + 8 103 | end 104 | 105 | function BoolByteSize(field_number, b) 106 | return TagByteSize(field_number) + 1 107 | end 108 | 109 | function EnumByteSize(field_number, enum) 110 | return UInt32ByteSize(field_number, enum) 111 | end 112 | 113 | function StringByteSize(field_number, string) 114 | return BytesByteSize(field_number, string) 115 | end 116 | 117 | function BytesByteSize(field_number, b) 118 | return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(#b) + #b 119 | end 120 | 121 | function MessageByteSize(field_number, message) 122 | return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(message.ByteSize()) + message.ByteSize() 123 | end 124 | 125 | function MessageSetItemByteSize(field_number, msg) 126 | local total_size = 2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3) 127 | total_size = total_size + _VarUInt64ByteSizeNoTag(field_number) 128 | local message_size = msg.ByteSize() 129 | total_size = total_size + _VarUInt64ByteSizeNoTag(message_size) 130 | total_size = total_size + message_size 131 | return total_size 132 | end 133 | 134 | function TagByteSize(field_number) 135 | return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0)) 136 | end 137 | 138 | --------------------------------------------------------------------------------