PageRenderTime 54ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/protobuf/protobuf.lua

https://code.google.com/p/protoc-gen-lua/
Lua | 922 lines | 809 code | 93 blank | 20 comment | 114 complexity | 9f718ac50e0a66d1b33fb26ccc94640c MD5 | raw file
  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 <url: http://www.opensource.org/licenses/bsd-license.php >.
  13. --
  14. -- COMPANY: NetEase
  15. -- CREATED: 2010?07?29? 14?30?02? CST
  16. --------------------------------------------------------------------------------
  17. --
  18. local setmetatable = setmetatable
  19. local rawset = rawset
  20. local rawget = rawget
  21. local error = error
  22. local ipairs = ipairs
  23. local pairs = pairs
  24. local print = print
  25. local table = table
  26. local string = string
  27. local tostring = tostring
  28. local type = type
  29. local pb = require "pb"
  30. local wire_format = require "wire_format"
  31. local type_checkers = require "type_checkers"
  32. local encoder = require "encoder"
  33. local decoder = require "decoder"
  34. local listener_mod = require "listener"
  35. local containers = require "containers"
  36. local descriptor = require "descriptor"
  37. local FieldDescriptor = descriptor.FieldDescriptor
  38. local text_format = require "text_format"
  39. module("protobuf")
  40. local function make_descriptor(name, descriptor, usable_key)
  41. local meta = {
  42. __newindex = function(self, key, value)
  43. if usable_key[key] then
  44. rawset(self, key, value)
  45. else
  46. error("error key: "..key)
  47. end
  48. end
  49. };
  50. meta.__index = meta
  51. meta.__call = function()
  52. return setmetatable({}, meta)
  53. end
  54. _M[name] = setmetatable(descriptor, meta);
  55. end
  56. make_descriptor("Descriptor", {}, {
  57. name = true,
  58. full_name = true,
  59. filename = true,
  60. containing_type = true,
  61. fields = true,
  62. nested_types = true,
  63. enum_types = true,
  64. extensions = true,
  65. options = true,
  66. is_extendable = true,
  67. extension_ranges = true,
  68. })
  69. make_descriptor("FieldDescriptor", FieldDescriptor, {
  70. name = true,
  71. full_name = true,
  72. index = true,
  73. number = true,
  74. type = true,
  75. cpp_type = true,
  76. label = true,
  77. has_default_value = true,
  78. default_value = true,
  79. containing_type = true,
  80. message_type = true,
  81. enum_type = true,
  82. is_extension = true,
  83. extension_scope = true,
  84. })
  85. make_descriptor("EnumDescriptor", {}, {
  86. name = true,
  87. full_name = true,
  88. values = true,
  89. containing_type = true,
  90. options = true
  91. })
  92. make_descriptor("EnumValueDescriptor", {}, {
  93. name = true,
  94. index = true,
  95. number = true,
  96. type = true,
  97. options = true
  98. })
  99. -- Maps from field type to expected wiretype.
  100. local FIELD_TYPE_TO_WIRE_TYPE = {
  101. [FieldDescriptor.TYPE_DOUBLE] = wire_format.WIRETYPE_FIXED64,
  102. [FieldDescriptor.TYPE_FLOAT] = wire_format.WIRETYPE_FIXED32,
  103. [FieldDescriptor.TYPE_INT64] = wire_format.WIRETYPE_VARINT,
  104. [FieldDescriptor.TYPE_UINT64] = wire_format.WIRETYPE_VARINT,
  105. [FieldDescriptor.TYPE_INT32] = wire_format.WIRETYPE_VARINT,
  106. [FieldDescriptor.TYPE_FIXED64] = wire_format.WIRETYPE_FIXED64,
  107. [FieldDescriptor.TYPE_FIXED32] = wire_format.WIRETYPE_FIXED32,
  108. [FieldDescriptor.TYPE_BOOL] = wire_format.WIRETYPE_VARINT,
  109. [FieldDescriptor.TYPE_STRING] = wire_format.WIRETYPE_LENGTH_DELIMITED,
  110. [FieldDescriptor.TYPE_GROUP] = wire_format.WIRETYPE_START_GROUP,
  111. [FieldDescriptor.TYPE_MESSAGE] = wire_format.WIRETYPE_LENGTH_DELIMITED,
  112. [FieldDescriptor.TYPE_BYTES] = wire_format.WIRETYPE_LENGTH_DELIMITED,
  113. [FieldDescriptor.TYPE_UINT32] = wire_format.WIRETYPE_VARINT,
  114. [FieldDescriptor.TYPE_ENUM] = wire_format.WIRETYPE_VARINT,
  115. [FieldDescriptor.TYPE_SFIXED32] = wire_format.WIRETYPE_FIXED32,
  116. [FieldDescriptor.TYPE_SFIXED64] = wire_format.WIRETYPE_FIXED64,
  117. [FieldDescriptor.TYPE_SINT32] = wire_format.WIRETYPE_VARINT,
  118. [FieldDescriptor.TYPE_SINT64] = wire_format.WIRETYPE_VARINT
  119. }
  120. local NON_PACKABLE_TYPES = {
  121. [FieldDescriptor.TYPE_STRING] = true,
  122. [FieldDescriptor.TYPE_GROUP] = true,
  123. [FieldDescriptor.TYPE_MESSAGE] = true,
  124. [FieldDescriptor.TYPE_BYTES] = true
  125. }
  126. local _VALUE_CHECKERS = {
  127. [FieldDescriptor.CPPTYPE_INT32] = type_checkers.Int32ValueChecker(),
  128. [FieldDescriptor.CPPTYPE_INT64] = type_checkers.Int32ValueChecker(),
  129. [FieldDescriptor.CPPTYPE_UINT32] = type_checkers.Uint32ValueChecker(),
  130. [FieldDescriptor.CPPTYPE_UINT64] = type_checkers.Uint32ValueChecker(),
  131. [FieldDescriptor.CPPTYPE_DOUBLE] = type_checkers.TypeChecker({number = true}),
  132. [FieldDescriptor.CPPTYPE_FLOAT] = type_checkers.TypeChecker({number = true}),
  133. [FieldDescriptor.CPPTYPE_BOOL] = type_checkers.TypeChecker({boolean = true, bool = true, int=true}),
  134. [FieldDescriptor.CPPTYPE_ENUM] = type_checkers.Int32ValueChecker(),
  135. [FieldDescriptor.CPPTYPE_STRING] = type_checkers.TypeChecker({string = true})
  136. }
  137. local TYPE_TO_BYTE_SIZE_FN = {
  138. [FieldDescriptor.TYPE_DOUBLE] = wire_format.DoubleByteSize,
  139. [FieldDescriptor.TYPE_FLOAT] = wire_format.FloatByteSize,
  140. [FieldDescriptor.TYPE_INT64] = wire_format.Int64ByteSize,
  141. [FieldDescriptor.TYPE_UINT64] = wire_format.UInt64ByteSize,
  142. [FieldDescriptor.TYPE_INT32] = wire_format.Int32ByteSize,
  143. [FieldDescriptor.TYPE_FIXED64] = wire_format.Fixed64ByteSize,
  144. [FieldDescriptor.TYPE_FIXED32] = wire_format.Fixed32ByteSize,
  145. [FieldDescriptor.TYPE_BOOL] = wire_format.BoolByteSize,
  146. [FieldDescriptor.TYPE_STRING] = wire_format.StringByteSize,
  147. [FieldDescriptor.TYPE_GROUP] = wire_format.GroupByteSize,
  148. [FieldDescriptor.TYPE_MESSAGE] = wire_format.MessageByteSize,
  149. [FieldDescriptor.TYPE_BYTES] = wire_format.BytesByteSize,
  150. [FieldDescriptor.TYPE_UINT32] = wire_format.UInt32ByteSize,
  151. [FieldDescriptor.TYPE_ENUM] = wire_format.EnumByteSize,
  152. [FieldDescriptor.TYPE_SFIXED32] = wire_format.SFixed32ByteSize,
  153. [FieldDescriptor.TYPE_SFIXED64] = wire_format.SFixed64ByteSize,
  154. [FieldDescriptor.TYPE_SINT32] = wire_format.SInt32ByteSize,
  155. [FieldDescriptor.TYPE_SINT64] = wire_format.SInt64ByteSize
  156. }
  157. local TYPE_TO_ENCODER = {
  158. [FieldDescriptor.TYPE_DOUBLE] = encoder.DoubleEncoder,
  159. [FieldDescriptor.TYPE_FLOAT] = encoder.FloatEncoder,
  160. [FieldDescriptor.TYPE_INT64] = encoder.Int64Encoder,
  161. [FieldDescriptor.TYPE_UINT64] = encoder.UInt64Encoder,
  162. [FieldDescriptor.TYPE_INT32] = encoder.Int32Encoder,
  163. [FieldDescriptor.TYPE_FIXED64] = encoder.Fixed64Encoder,
  164. [FieldDescriptor.TYPE_FIXED32] = encoder.Fixed32Encoder,
  165. [FieldDescriptor.TYPE_BOOL] = encoder.BoolEncoder,
  166. [FieldDescriptor.TYPE_STRING] = encoder.StringEncoder,
  167. [FieldDescriptor.TYPE_GROUP] = encoder.GroupEncoder,
  168. [FieldDescriptor.TYPE_MESSAGE] = encoder.MessageEncoder,
  169. [FieldDescriptor.TYPE_BYTES] = encoder.BytesEncoder,
  170. [FieldDescriptor.TYPE_UINT32] = encoder.UInt32Encoder,
  171. [FieldDescriptor.TYPE_ENUM] = encoder.EnumEncoder,
  172. [FieldDescriptor.TYPE_SFIXED32] = encoder.SFixed32Encoder,
  173. [FieldDescriptor.TYPE_SFIXED64] = encoder.SFixed64Encoder,
  174. [FieldDescriptor.TYPE_SINT32] = encoder.SInt32Encoder,
  175. [FieldDescriptor.TYPE_SINT64] = encoder.SInt64Encoder
  176. }
  177. local TYPE_TO_SIZER = {
  178. [FieldDescriptor.TYPE_DOUBLE] = encoder.DoubleSizer,
  179. [FieldDescriptor.TYPE_FLOAT] = encoder.FloatSizer,
  180. [FieldDescriptor.TYPE_INT64] = encoder.Int64Sizer,
  181. [FieldDescriptor.TYPE_UINT64] = encoder.UInt64Sizer,
  182. [FieldDescriptor.TYPE_INT32] = encoder.Int32Sizer,
  183. [FieldDescriptor.TYPE_FIXED64] = encoder.Fixed64Sizer,
  184. [FieldDescriptor.TYPE_FIXED32] = encoder.Fixed32Sizer,
  185. [FieldDescriptor.TYPE_BOOL] = encoder.BoolSizer,
  186. [FieldDescriptor.TYPE_STRING] = encoder.StringSizer,
  187. [FieldDescriptor.TYPE_GROUP] = encoder.GroupSizer,
  188. [FieldDescriptor.TYPE_MESSAGE] = encoder.MessageSizer,
  189. [FieldDescriptor.TYPE_BYTES] = encoder.BytesSizer,
  190. [FieldDescriptor.TYPE_UINT32] = encoder.UInt32Sizer,
  191. [FieldDescriptor.TYPE_ENUM] = encoder.EnumSizer,
  192. [FieldDescriptor.TYPE_SFIXED32] = encoder.SFixed32Sizer,
  193. [FieldDescriptor.TYPE_SFIXED64] = encoder.SFixed64Sizer,
  194. [FieldDescriptor.TYPE_SINT32] = encoder.SInt32Sizer,
  195. [FieldDescriptor.TYPE_SINT64] = encoder.SInt64Sizer
  196. }
  197. local TYPE_TO_DECODER = {
  198. [FieldDescriptor.TYPE_DOUBLE] = decoder.DoubleDecoder,
  199. [FieldDescriptor.TYPE_FLOAT] = decoder.FloatDecoder,
  200. [FieldDescriptor.TYPE_INT64] = decoder.Int64Decoder,
  201. [FieldDescriptor.TYPE_UINT64] = decoder.UInt64Decoder,
  202. [FieldDescriptor.TYPE_INT32] = decoder.Int32Decoder,
  203. [FieldDescriptor.TYPE_FIXED64] = decoder.Fixed64Decoder,
  204. [FieldDescriptor.TYPE_FIXED32] = decoder.Fixed32Decoder,
  205. [FieldDescriptor.TYPE_BOOL] = decoder.BoolDecoder,
  206. [FieldDescriptor.TYPE_STRING] = decoder.StringDecoder,
  207. [FieldDescriptor.TYPE_GROUP] = decoder.GroupDecoder,
  208. [FieldDescriptor.TYPE_MESSAGE] = decoder.MessageDecoder,
  209. [FieldDescriptor.TYPE_BYTES] = decoder.BytesDecoder,
  210. [FieldDescriptor.TYPE_UINT32] = decoder.UInt32Decoder,
  211. [FieldDescriptor.TYPE_ENUM] = decoder.EnumDecoder,
  212. [FieldDescriptor.TYPE_SFIXED32] = decoder.SFixed32Decoder,
  213. [FieldDescriptor.TYPE_SFIXED64] = decoder.SFixed64Decoder,
  214. [FieldDescriptor.TYPE_SINT32] = decoder.SInt32Decoder,
  215. [FieldDescriptor.TYPE_SINT64] = decoder.SInt64Decoder
  216. }
  217. local FIELD_TYPE_TO_WIRE_TYPE = {
  218. [FieldDescriptor.TYPE_DOUBLE] = wire_format.WIRETYPE_FIXED64,
  219. [FieldDescriptor.TYPE_FLOAT] = wire_format.WIRETYPE_FIXED32,
  220. [FieldDescriptor.TYPE_INT64] = wire_format.WIRETYPE_VARINT,
  221. [FieldDescriptor.TYPE_UINT64] = wire_format.WIRETYPE_VARINT,
  222. [FieldDescriptor.TYPE_INT32] = wire_format.WIRETYPE_VARINT,
  223. [FieldDescriptor.TYPE_FIXED64] = wire_format.WIRETYPE_FIXED64,
  224. [FieldDescriptor.TYPE_FIXED32] = wire_format.WIRETYPE_FIXED32,
  225. [FieldDescriptor.TYPE_BOOL] = wire_format.WIRETYPE_VARINT,
  226. [FieldDescriptor.TYPE_STRING] = wire_format.WIRETYPE_LENGTH_DELIMITED,
  227. [FieldDescriptor.TYPE_GROUP] = wire_format.WIRETYPE_START_GROUP,
  228. [FieldDescriptor.TYPE_MESSAGE] = wire_format.WIRETYPE_LENGTH_DELIMITED,
  229. [FieldDescriptor.TYPE_BYTES] = wire_format.WIRETYPE_LENGTH_DELIMITED,
  230. [FieldDescriptor.TYPE_UINT32] = wire_format.WIRETYPE_VARINT,
  231. [FieldDescriptor.TYPE_ENUM] = wire_format.WIRETYPE_VARINT,
  232. [FieldDescriptor.TYPE_SFIXED32] = wire_format.WIRETYPE_FIXED32,
  233. [FieldDescriptor.TYPE_SFIXED64] = wire_format.WIRETYPE_FIXED64,
  234. [FieldDescriptor.TYPE_SINT32] = wire_format.WIRETYPE_VARINT,
  235. [FieldDescriptor.TYPE_SINT64] = wire_format.WIRETYPE_VARINT
  236. }
  237. local function IsTypePackable(field_type)
  238. return NON_PACKABLE_TYPES[field_type] == nil
  239. end
  240. local function GetTypeChecker(cpp_type, field_type)
  241. if (cpp_type == FieldDescriptor.CPPTYPE_STRING and field_type == FieldDescriptor.TYPE_STRING) then
  242. return type_checkers.UnicodeValueChecker()
  243. end
  244. return _VALUE_CHECKERS[cpp_type]
  245. end
  246. local function _DefaultValueConstructorForField(field)
  247. if field.label == FieldDescriptor.LABEL_REPEATED then
  248. if type(field.default_value) ~= "table" or #(field.default_value) ~= 0 then
  249. error('Repeated field default value not empty list:' .. tostring(field.default_value))
  250. end
  251. if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then
  252. local message_type = field.message_type
  253. return function (message)
  254. return containers.RepeatedCompositeFieldContainer(message._listener_for_children, message_type)
  255. end
  256. else
  257. local type_checker = GetTypeChecker(field.cpp_type, field.type)
  258. return function (message)
  259. return containers.RepeatedScalarFieldContainer(message._listener_for_children, type_checker)
  260. end
  261. end
  262. end
  263. if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then
  264. local message_type = field.message_type
  265. return function (message)
  266. result = message_type._concrete_class()
  267. result._SetListener(message._listener_for_children)
  268. return result
  269. end
  270. end
  271. return function (message)
  272. return field.default_value
  273. end
  274. end
  275. local function _AttachFieldHelpers(message_meta, field_descriptor)
  276. local is_repeated = (field_descriptor.label == FieldDescriptor.LABEL_REPEATED)
  277. local is_packed = (field_descriptor.has_options and field_descriptor.GetOptions().packed)
  278. rawset(field_descriptor, "_encoder", TYPE_TO_ENCODER[field_descriptor.type](field_descriptor.number, is_repeated, is_packed))
  279. rawset(field_descriptor, "_sizer", TYPE_TO_SIZER[field_descriptor.type](field_descriptor.number, is_repeated, is_packed))
  280. rawset(field_descriptor, "_default_constructor", _DefaultValueConstructorForField(field_descriptor))
  281. local AddDecoder = function(wiretype, is_packed)
  282. local tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
  283. 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)
  284. end
  285. AddDecoder(FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], False)
  286. if is_repeated and IsTypePackable(field_descriptor.type) then
  287. AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True)
  288. end
  289. end
  290. local function _AddEnumValues(descriptor, message_meta)
  291. for _, enum_type in ipairs(descriptor.enum_types) do
  292. for _, enum_value in ipairs(enum_type.values) do
  293. message_meta._member[enum_value.name] = enum_value.number
  294. end
  295. end
  296. end
  297. local function _InitMethod(message_meta)
  298. return function()
  299. local self = {}
  300. self._cached_byte_size = 0
  301. self._cached_byte_size_dirty = false
  302. self._fields = {}
  303. self._is_present_in_parent = false
  304. self._listener = listener_mod.NullMessageListener()
  305. self._listener_for_children = listener_mod.Listener(self)
  306. return setmetatable(self, message_meta)
  307. end
  308. end
  309. local function _AddPropertiesForRepeatedField(field, message_meta)
  310. local property_name = field.name
  311. message_meta._getter[property_name] = function(self)
  312. local field_value = self._fields[field]
  313. if field_value == nil then
  314. field_value = field._default_constructor(self)
  315. self._fields[field] = field_value
  316. end
  317. return field_value
  318. end
  319. message_meta._setter[property_name] = function(self)
  320. error('Assignment not allowed to repeated field "' .. property_name .. '" in protocol message object.')
  321. end
  322. end
  323. local function _AddPropertiesForNonRepeatedCompositeField(field, message_meta)
  324. local property_name = field.name
  325. local message_type = field.message_type
  326. message_meta._getter[property_name] = function(self)
  327. local field_value = self._fields[field]
  328. if field_value == nil then
  329. field_value = message_type._concrete_class()
  330. field_value:_SetListener(self._listener_for_children)
  331. self._fields[field] = field_value
  332. end
  333. return field_value
  334. end
  335. message_meta._setter[property_name] = function(self, new_value)
  336. error('Assignment not allowed to composite field' .. property_name .. 'in protocol message object.' )
  337. end
  338. end
  339. local function _AddPropertiesForNonRepeatedScalarField(field, message)
  340. local property_name = field.name
  341. local type_checker = GetTypeChecker(field.cpp_type, field.type)
  342. local default_value = field.default_value
  343. message._getter[property_name] = function(self)
  344. local value = self._fields[field]
  345. if value ~= nil then
  346. return self._fields[field]
  347. else
  348. return default_value
  349. end
  350. end
  351. message._setter[property_name] = function(self, new_value)
  352. type_checker(new_value)
  353. self._fields[field] = new_value
  354. if not self._cached_byte_size_dirty then
  355. message._member._Modified(self)
  356. end
  357. end
  358. end
  359. local function _AddPropertiesForField(field, message_meta)
  360. constant_name = field.name:upper() .. "_FIELD_NUMBER"
  361. message_meta._member[constant_name] = field.number
  362. if field.label == FieldDescriptor.LABEL_REPEATED then
  363. _AddPropertiesForRepeatedField(field, message_meta)
  364. elseif field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then
  365. _AddPropertiesForNonRepeatedCompositeField(field, message_meta)
  366. else
  367. _AddPropertiesForNonRepeatedScalarField(field, message_meta)
  368. end
  369. end
  370. local _ED_meta = {
  371. __index = function(self, extension_handle)
  372. local _extended_message = rawget(self, "_extended_message")
  373. local value = _extended_message._fields[extension_handle]
  374. if value ~= nil then
  375. return value
  376. end
  377. if extension_handle.label == FieldDescriptor.LABEL_REPEATED then
  378. value = extension_handle._default_constructor(self._extended_message)
  379. elseif extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then
  380. value = extension_handle.message_type._concrete_class()
  381. value:_SetListener(_extended_message._listener_for_children)
  382. else
  383. return extension_handle.default_value
  384. end
  385. _extended_message._fields[extension_handle] = value
  386. return value
  387. end,
  388. __newindex = function(self, extension_handle, value)
  389. local _extended_message = rawget(self, "_extended_message")
  390. if (extension_handle.label == FieldDescriptor.LABEL_REPEATED or
  391. extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE) then
  392. error('Cannot assign to extension "'.. extension_handle.full_name .. '" because it is a repeated or composite type.')
  393. end
  394. local type_checker = GetTypeChecker(extension_handle.cpp_type, extension_handle.type)
  395. type_checker.CheckValue(value)
  396. _extended_message._fields[extension_handle] = value
  397. _extended_message._Modified()
  398. end
  399. }
  400. local function _ExtensionDict(message)
  401. local o = {}
  402. o._extended_message = message
  403. return setmetatable(o, _ED_meta)
  404. end
  405. local function _AddPropertiesForFields(descriptor, message_meta)
  406. for _, field in ipairs(descriptor.fields) do
  407. _AddPropertiesForField(field, message_meta)
  408. end
  409. if descriptor.is_extendable then
  410. message_meta._getter.Extensions = function(self) return _ExtensionDict(self) end
  411. end
  412. end
  413. local function _AddPropertiesForExtensions(descriptor, message_meta)
  414. local extension_dict = descriptor._extensions_by_name
  415. for extension_name, extension_field in pairs(extension_dict) do
  416. local constant_name = string.upper(extension_name) .. "_FIELD_NUMBER"
  417. message_meta._member[constant_name] = extension_field.number
  418. end
  419. end
  420. local function _AddStaticMethods(message_meta)
  421. message_meta._member.RegisterExtension = function(extension_handle)
  422. extension_handle.containing_type = message_meta._descriptor
  423. _AttachFieldHelpers(message_meta, extension_handle)
  424. if message_meta._extensions_by_number[extension_handle.number] == nil then
  425. message_meta._extensions_by_number[extension_handle.number] = extension_handle
  426. else
  427. error(
  428. string.format('Extensions "%s" and "%s" both try to extend message type "%s" with field number %d.',
  429. extension_handle.full_name, actual_handle.full_name,
  430. message_meta._descriptor.full_name, extension_handle.number))
  431. end
  432. message_meta._extensions_by_name[extension_handle.full_name] = extension_handle
  433. end
  434. message_meta._member.FromString = function(s)
  435. local message = message_meta._member.__call()
  436. message.MergeFromString(s)
  437. return message
  438. end
  439. end
  440. local function _IsPresent(descriptor, value)
  441. if descriptor.label == FieldDescriptor.LABEL_REPEATED then
  442. return value
  443. elseif descriptor.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then
  444. return value._is_present_in_parent
  445. else
  446. return true
  447. end
  448. end
  449. local function _AddListFieldsMethod(message_descriptor, message_meta)
  450. message_meta._member.ListFields = function (self)
  451. local list_field = function(fields)
  452. local f, s, v = pairs(self._fields)
  453. local iter = function(a, i)
  454. while true do
  455. local descriptor, value = f(a, i)
  456. if descriptor == nil then
  457. return
  458. elseif _IsPresent(descriptor, value) then
  459. return descriptor, value
  460. end
  461. end
  462. end
  463. return iter, s, v
  464. end
  465. return list_field(self._fields)
  466. end
  467. end
  468. local function _AddHasFieldMethod(message_descriptor, message_meta)
  469. local singular_fields = {}
  470. for _, field in ipairs(message_descriptor.fields) do
  471. if field.label ~= FieldDescriptor.LABEL_REPEATED then
  472. singular_fields[field.name] = field
  473. end
  474. end
  475. message_meta._member.HasField = function (self, field_name)
  476. field = singular_fields[field_name]
  477. if feild == nil then
  478. error('Protocol message has no singular "'.. field_name.. '" field.')
  479. end
  480. if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then
  481. value = self._fields[field]
  482. return value ~= nil and value._is_present_in_parent
  483. else
  484. return self._fields[field]
  485. end
  486. end
  487. end
  488. local function _AddClearFieldMethod(message_descriptor, message_meta)
  489. message_meta._member.ClearField = function(self, field_name)
  490. if message_descriptor.fields_by_name[field_name] == nil then
  491. error('Protocol message has no "' .. field_name .. '" field.')
  492. end
  493. if self._fields[field] then
  494. self._fields[field] = nil
  495. end
  496. message_meta._member._Modified(self)
  497. end
  498. end
  499. local function _AddClearExtensionMethod(message_meta)
  500. message_meta._member.ClearExtension = function(self, extension_handle)
  501. if self._fields[extension_handle] == nil then
  502. self._fields[extension_handle] = nil
  503. end
  504. message_meta._member._Modified(self)
  505. end
  506. end
  507. local function _AddClearMethod(message_descriptor, message_meta)
  508. message_meta._member.Clear = function(self)
  509. self._fields = {}
  510. message_meta._member._Modified(self)
  511. end
  512. end
  513. local function _AddStrMethod(message_meta)
  514. local format = text_format.msg_format
  515. message_meta.__tostring = function(self)
  516. return format(self)
  517. end
  518. end
  519. local function _AddHasExtensionMethod(message_meta)
  520. message_meta._member.HasExtension = function(self, extension_handle)
  521. if extension_handle.label == FieldDescriptor.LABEL_REPEATED then
  522. error(extension_handle.full_name .. ' is repeated.')
  523. end
  524. if extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then
  525. value = self._fields[extension_handle]
  526. return value ~= nil and value._is_present_in_parent
  527. else
  528. return self._fields[extension_handle]
  529. end
  530. end
  531. end
  532. local function _AddSetListenerMethod(message_meta)
  533. message_meta._member._SetListener = function(self, listener)
  534. if listener ~= nil then
  535. self._listener = listener_mod.NullMessageListener()
  536. else
  537. self._listener = listener
  538. end
  539. end
  540. end
  541. local function _AddByteSizeMethod(message_descriptor, message_meta)
  542. message_meta._member.ByteSize = function(self)
  543. if not self._cached_byte_size_dirty then
  544. return self._cached_byte_size
  545. end
  546. local size = 0
  547. for field_descriptor, field_value in message_meta._member.ListFields(self) do
  548. size = field_descriptor._sizer(field_value) + size
  549. end
  550. self._cached_byte_size = size
  551. self._cached_byte_size_dirty = false
  552. self._listener_for_children.dirty = false
  553. return size
  554. end
  555. end
  556. local function _AddSerializeToStringMethod(message_descriptor, message_meta)
  557. message_meta._member.SerializeToString = function(self)
  558. if not message_meta._member.IsInitialized(self) then
  559. error('Message is missing required fields: ' ..
  560. table.concat(message_meta._member.FindInitializationErrors(self), ','))
  561. end
  562. return message_meta._member.SerializePartialToString(self)
  563. end
  564. message_meta._member.SerializeToIOString = function(self, iostring)
  565. if not message_meta._member.IsInitialized(self) then
  566. error('Message is missing required fields: ' ..
  567. table.concat(message_meta._member.FindInitializationErrors(self), ','))
  568. end
  569. return message_meta._member.SerializePartialToIOString(self, iostring)
  570. end
  571. end
  572. local function _AddSerializePartialToStringMethod(message_descriptor, message_meta)
  573. local concat = table.concat
  574. local _internal_serialize = function(self, write_bytes)
  575. for field_descriptor, field_value in message_meta._member.ListFields(self) do
  576. field_descriptor._encoder(write_bytes, field_value)
  577. end
  578. end
  579. local _serialize_partial_to_iostring = function(self, iostring)
  580. local w = iostring.write
  581. local write = function(value)
  582. w(iostring, value)
  583. end
  584. _internal_serialize(self, write)
  585. return
  586. end
  587. local _serialize_partial_to_string = function(self)
  588. local out = {}
  589. local write = function(value)
  590. out[#out + 1] = value
  591. end
  592. _internal_serialize(self, write)
  593. return concat(out)
  594. end
  595. message_meta._member._InternalSerialize = _internal_serialize
  596. message_meta._member.SerializePartialToIOString = _serialize_partial_to_iostring
  597. message_meta._member.SerializePartialToString = _serialize_partial_to_string
  598. end
  599. local function _AddMergeFromStringMethod(message_descriptor, message_meta)
  600. local ReadTag = decoder.ReadTag
  601. local SkipField = decoder.SkipField
  602. local decoders_by_tag = message_meta._decoders_by_tag
  603. local _internal_parse = function(self, buffer, pos, pend)
  604. message_meta._member._Modified(self)
  605. local field_dict = self._fields
  606. local tag_bytes, new_pos
  607. local field_decoder
  608. while pos ~= pend do
  609. tag_bytes, new_pos = ReadTag(buffer, pos)
  610. field_decoder = decoders_by_tag[tag_bytes]
  611. if field_decoder == nil then
  612. new_pos = SkipField(buffer, new_pos, pend, tag_bytes)
  613. if new_pos == -1 then
  614. return pos
  615. end
  616. pos = new_pos
  617. else
  618. pos = field_decoder(buffer, new_pos, pend, self, field_dict)
  619. end
  620. end
  621. return pos
  622. end
  623. message_meta._member._InternalParse = _internal_parse
  624. local merge_from_string = function(self, serialized)
  625. local length = #serialized
  626. if _internal_parse(self, serialized, 0, length) ~= length then
  627. error('Unexpected end-group tag.')
  628. end
  629. return length
  630. end
  631. message_meta._member.MergeFromString = merge_from_string
  632. message_meta._member.ParseFromString = function(self, serialized)
  633. message_meta._member.Clear(self)
  634. merge_from_string(self, serialized)
  635. end
  636. end
  637. local function _AddIsInitializedMethod(message_descriptor, message_meta)
  638. local required_fields = {}
  639. for _, field in ipairs(message_descriptor.fields) do
  640. if field.label == FieldDescriptor.LABEL_REQUIRED then
  641. required_fields[#required_fields + 1] = field
  642. end
  643. end
  644. message_meta._member.IsInitialized = function(self, errors)
  645. for _, field in ipairs(required_fields) do
  646. if self._fields[field] == nil or
  647. (field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE and not self._fields[field]._is_present_in_parent) then
  648. if errors ~= nil then
  649. errors[#errors + 1] = message_meta._member.FindInitializationErrors(self)
  650. end
  651. return false
  652. end
  653. end
  654. for field, value in pairs(self._fields) do
  655. if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then
  656. if field.label == FieldDescriptor.LABEL_REPEATED then
  657. for _, element in ipairs(value) do
  658. if not element:IsInitialized() then
  659. if errors ~= nil then
  660. errors[#errors + 1] = message_meta._member.FindInitializationErrors(self)
  661. end
  662. return false
  663. end
  664. end
  665. elseif value._is_present_in_parent and not value:IsInitialized() then
  666. if errors ~= nil then
  667. errors[#errors + 1] = message_meta._member.FindInitializationErrors(self)
  668. end
  669. return false
  670. end
  671. end
  672. end
  673. return true
  674. end
  675. message_meta._member.FindInitializationErrors = function(self)
  676. local errors = {}
  677. for _,field in ipairs(required_fields) do
  678. if not message_meta._member.HasField(self, field.name) then
  679. errors.append(field.name)
  680. end
  681. end
  682. for field, value in message_meta._member.ListFields(self) do
  683. if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE then
  684. if field.is_extension then
  685. name = io:format("(%s)", field.full_name)
  686. else
  687. name = field.name
  688. end
  689. if field.label == FieldDescriptor.LABEL_REPEATED then
  690. for i, element in ipairs(value) do
  691. prefix = io:format("%s[%d].", name, i)
  692. sub_errors = element:FindInitializationErrors()
  693. for _, e in ipairs(sub_errors) do
  694. errors[#errors + 1] = prefix .. e
  695. end
  696. end
  697. else
  698. prefix = name .. "."
  699. sub_errors = value:FindInitializationErrors()
  700. for _, e in ipairs(sub_errors) do
  701. errors[#errors + 1] = prefix .. e
  702. end
  703. end
  704. end
  705. end
  706. return errors
  707. end
  708. end
  709. local function _AddMergeFromMethod(message_meta)
  710. local LABEL_REPEATED = FieldDescriptor.LABEL_REPEATED
  711. local CPPTYPE_MESSAGE = FieldDescriptor.CPPTYPE_MESSAGE
  712. message_meta._member.MergeFrom = function (self, msg)
  713. assert(msg ~= self)
  714. message_meta._member._Modified(self)
  715. local fields = self._fields
  716. for field, value in pairs(msg._fields) do
  717. if field.label == LABEL_REPEATED or field.cpp_type == CPPTYPE_MESSAGE then
  718. field_value = fields[field]
  719. if field_value == nil then
  720. field_value = field._default_constructor(self)
  721. fields[field] = field_value
  722. end
  723. field_value:MergeFrom(value)
  724. else
  725. self._fields[field] = value
  726. end
  727. end
  728. end
  729. end
  730. local function _AddMessageMethods(message_descriptor, message_meta)
  731. _AddListFieldsMethod(message_descriptor, message_meta)
  732. _AddHasFieldMethod(message_descriptor, message_meta)
  733. _AddClearFieldMethod(message_descriptor, message_meta)
  734. if message_descriptor.is_extendable then
  735. _AddClearExtensionMethod(message_meta)
  736. _AddHasExtensionMethod(message_meta)
  737. end
  738. _AddClearMethod(message_descriptor, message_meta)
  739. -- _AddEqualsMethod(message_descriptor, message_meta)
  740. _AddStrMethod(message_meta)
  741. _AddSetListenerMethod(message_meta)
  742. _AddByteSizeMethod(message_descriptor, message_meta)
  743. _AddSerializeToStringMethod(message_descriptor, message_meta)
  744. _AddSerializePartialToStringMethod(message_descriptor, message_meta)
  745. _AddMergeFromStringMethod(message_descriptor, message_meta)
  746. _AddIsInitializedMethod(message_descriptor, message_meta)
  747. _AddMergeFromMethod(message_meta)
  748. end
  749. local function _AddPrivateHelperMethods(message_meta)
  750. local Modified = function (self)
  751. if not self._cached_byte_size_dirty then
  752. self._cached_byte_size_dirty = true
  753. self._listener_for_children.dirty = true
  754. self._is_present_in_parent = true
  755. self._listener:Modified()
  756. end
  757. end
  758. message_meta._member._Modified = Modified
  759. message_meta._member.SetInParent = Modified
  760. end
  761. local function property_getter(message_meta)
  762. local getter = message_meta._getter
  763. local member = message_meta._member
  764. return function (self, property)
  765. local g = getter[property]
  766. if g then
  767. return g(self)
  768. else
  769. return member[property]
  770. end
  771. end
  772. end
  773. local function property_setter(message_meta)
  774. local setter = message_meta._setter
  775. return function (self, property, value)
  776. local s = setter[property]
  777. if s then
  778. s(self, value)
  779. else
  780. error(property .. " not found")
  781. end
  782. end
  783. end
  784. function _AddClassAttributesForNestedExtensions(descriptor, message_meta)
  785. local extension_dict = descriptor._extensions_by_name
  786. for extension_name, extension_field in pairs(extension_dict) do
  787. message_meta._member[extension_name] = extension_field
  788. end
  789. end
  790. local function Message(descriptor)
  791. local message_meta = {}
  792. message_meta._decoders_by_tag = {}
  793. rawset(descriptor, "_extensions_by_name", {})
  794. for _, k in ipairs(descriptor.extensions) do
  795. descriptor._extensions_by_name[k.name] = k
  796. end
  797. rawset(descriptor, "_extensions_by_number", {})
  798. for _, k in ipairs(descriptor.extensions) do
  799. descriptor._extensions_by_number[k.number] = k
  800. end
  801. message_meta._descriptor = descriptor
  802. message_meta._extensions_by_name = {}
  803. message_meta._extensions_by_number = {}
  804. message_meta._getter = {}
  805. message_meta._setter = {}
  806. message_meta._member = {}
  807. -- message_meta._name = descriptor.full_name
  808. local ns = setmetatable({}, message_meta._member)
  809. message_meta._member.__call = _InitMethod(message_meta)
  810. message_meta._member.__index = message_meta._member
  811. message_meta._member.type = ns
  812. if rawget(descriptor, "_concrete_class") == nil then
  813. rawset(descriptor, "_concrete_class", ns)
  814. for k, field in ipairs(descriptor.fields) do
  815. _AttachFieldHelpers(message_meta, field)
  816. end
  817. end
  818. _AddEnumValues(descriptor, message_meta)
  819. _AddClassAttributesForNestedExtensions(descriptor, message_meta)
  820. _AddPropertiesForFields(descriptor, message_meta)
  821. _AddPropertiesForExtensions(descriptor, message_meta)
  822. _AddStaticMethods(message_meta)
  823. _AddMessageMethods(descriptor, message_meta)
  824. _AddPrivateHelperMethods(message_meta)
  825. message_meta.__index = property_getter(message_meta)
  826. message_meta.__newindex = property_setter(message_meta)
  827. return ns
  828. end
  829. _M.Message = Message