├── .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 |
--------------------------------------------------------------------------------