protoc.lua.txt 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  1. local function meta(name, t)
  2. t = t or {}
  3. t.__name = name
  4. t.__index = t
  5. return t
  6. end
  7. local function default(t, k, def)
  8. local v = t[k]
  9. if not v then
  10. v = def or {}
  11. t[k] = v
  12. end
  13. return v
  14. end
  15. local Lexer = meta "Lexer" do
  16. local escape = {
  17. a = "\a", b = "\b", f = "\f", n = "\n",
  18. r = "\r", t = "\t", v = "\v"
  19. }
  20. local function tohex(x) return string.byte(tonumber(x, 16)) end
  21. local function todec(x) return string.byte(tonumber(x, 10)) end
  22. local function toesc(x) return escape[x] or x end
  23. function Lexer.new(name, src)
  24. local self = {
  25. name = name,
  26. src = src,
  27. pos = 1
  28. }
  29. return setmetatable(self, Lexer)
  30. end
  31. function Lexer:__call(patt, pos)
  32. return self.src:match(patt, pos or self.pos)
  33. end
  34. function Lexer:test(patt)
  35. self:whitespace()
  36. local pos = self('^'..patt..'%s*()')
  37. if not pos then return false end
  38. self.pos = pos
  39. return true
  40. end
  41. function Lexer:expected(patt, name)
  42. if not self:test(patt) then
  43. return self:error((name or "'"..patt.."'").." expected")
  44. end
  45. return self
  46. end
  47. function Lexer:pos2loc(pos)
  48. local linenr = 1
  49. pos = pos or self.pos
  50. for start, stop in self.src:gmatch "()[^\n]*()\n?" do
  51. if start <= pos and pos <= stop then
  52. return linenr, pos - start + 1
  53. end
  54. linenr = linenr + 1
  55. end
  56. end
  57. function Lexer:error(fmt, ...)
  58. local ln, co = self:pos2loc()
  59. return error(("%s:%d:%d: "..fmt):format(self.name, ln, co, ...))
  60. end
  61. function Lexer:opterror(opt, msg)
  62. if not opt then return self:error(msg) end
  63. return nil
  64. end
  65. function Lexer:whitespace()
  66. local pos, c = self "^%s*()(%/?)"
  67. self.pos = pos
  68. if c == '' then return self end
  69. return self:comment()
  70. end
  71. function Lexer:comment()
  72. local pos = self "^%/%/[^\n]*\n?()"
  73. if pos then
  74. if self "^%/%*" then
  75. pos = self "^%/%*.-%*%/()"
  76. if not pos then
  77. self:error "unfinished comment"
  78. end
  79. end
  80. end
  81. if not pos then return self end
  82. self.pos = pos
  83. return self:whitespace()
  84. end
  85. function Lexer:line_end(opt)
  86. self:whitespace()
  87. local pos = self '^[%s;]*%s*()'
  88. if not pos then
  89. return self:opterror(opt, "';' expected")
  90. end
  91. self.pos = pos
  92. return pos
  93. end
  94. function Lexer:eof()
  95. self:whitespace()
  96. return self.pos > #self.src
  97. end
  98. function Lexer:keyword(kw, opt)
  99. self:whitespace()
  100. local ident, pos = self "^([%a_][%w_]*)%s*()"
  101. if not ident or ident ~= kw then
  102. return self:opterror(opt, "''"..kw..'" expected')
  103. end
  104. self.pos = pos
  105. return kw
  106. end
  107. function Lexer:ident(name, opt)
  108. self:whitespace()
  109. local b, ident, pos = self "^()([%a_][%w_]*)%s*()"
  110. if not ident then
  111. return self:opterror(opt, (name or 'name')..' expected')
  112. end
  113. self.pos = pos
  114. return ident, b
  115. end
  116. function Lexer:full_ident(name, opt)
  117. self:whitespace()
  118. local b, ident, pos = self "^()([%a_][%w_.]*)%s*()"
  119. if not ident or ident:match "%.%.+" then
  120. return self:opterror(opt, (name or 'name')..' expected')
  121. end
  122. self.pos = pos
  123. return ident, b
  124. end
  125. function Lexer:integer(opt)
  126. self:whitespace()
  127. local ns, oct, hex, s, pos =
  128. self "^([+-]?)(0?)([xX]?)([0-9a-fA-F]+)%s*()"
  129. local n
  130. if oct == '0' and hex == '' then
  131. n = tonumber(s, 8)
  132. elseif oct == '' and hex == '' then
  133. n = tonumber(s, 10)
  134. elseif oct == '0' and hex ~= '' then
  135. n = tonumber(s, 16)
  136. end
  137. if not n then
  138. return self:opterror(opt, 'integer expected')
  139. end
  140. self.pos = pos
  141. return ns == '-' and -n or n
  142. end
  143. function Lexer:number(opt)
  144. self:whitespace()
  145. if self:test "nan%f[%A]" then
  146. return 0.0/0.0
  147. elseif self:test "inf%f[%A]" then
  148. return 1.0/0.0
  149. end
  150. local ns, d1, s, d2, s2, pos = self "^([+-]?)(%.?)([0-9]+)(%.?)([0-9]*)()"
  151. if not ns then
  152. return self:opterror(opt, 'floating-point number expected')
  153. end
  154. local es, pos2 = self("([eE][+-]?[0-9]+)%s*()", pos)
  155. if d1 == "." and d2 == "." then
  156. return self:error "malformed floating-point number"
  157. end
  158. self.pos = pos2 or pos
  159. local n = tonumber(d1..s..d2..s2..(es or ""))
  160. return ns == '-' and -n or n
  161. end
  162. function Lexer:quote(opt)
  163. self:whitespace()
  164. local q, start = self '^(["\'])()'
  165. if not start then
  166. return self:opterror(opt, 'string expected')
  167. end
  168. self.pos = start
  169. local patt = '()(\\?'..q..')%s*()'
  170. while true do
  171. local stop, s, pos = self(patt)
  172. if not stop then
  173. self.pos = start-1
  174. return self:error "unfinished string"
  175. end
  176. self.pos = pos
  177. if s == q then
  178. return self.src:sub(start, stop-1)
  179. :gsub("\\x(%x+)", tohex)
  180. :gsub("\\(%d+)", todec)
  181. :gsub("\\(.)", toesc)
  182. end
  183. end
  184. end
  185. function Lexer:constant(opt)
  186. local c = self:full_ident('constant', 'opt') or
  187. self:number('opt') or
  188. self:quote('opt')
  189. if not c and not opt then
  190. return self:error "constant expected"
  191. end
  192. return c
  193. end
  194. function Lexer:option_name()
  195. local ident
  196. if self:test "%(" then
  197. ident = self:full_ident "option name"
  198. self:expected "%)"
  199. else
  200. ident = self:ident "option name"
  201. end
  202. while self:test "%." do
  203. ident = ident .. "." .. self:ident()
  204. end
  205. return ident
  206. end
  207. function Lexer:type_name()
  208. if self:test "%." then
  209. local id, pos = self:full_ident "type name"
  210. return "."..id, pos
  211. else
  212. return self:full_ident "type name"
  213. end
  214. end
  215. end
  216. local Parser = meta "Parser" do
  217. Parser.typemap = {}
  218. Parser.loaded = {}
  219. Parser.paths = { "." }
  220. function Parser.new()
  221. local self = {}
  222. self.typemap = {}
  223. self.loaded = {}
  224. self.paths = { "." }
  225. return setmetatable(self, Parser)
  226. end
  227. function Parser:error(msg)
  228. return self.lex:error(msg)
  229. end
  230. function Parser:addpath(path)
  231. self.paths[#self.paths+1] = path
  232. end
  233. function Parser:parsefile(name)
  234. local info = self.loaded[name]
  235. if info then return info end
  236. local errors = {}
  237. for _, path in ipairs(self.paths) do
  238. local fn = path.."/"..name
  239. local fh, err = io.open(fn)
  240. if fh then
  241. local content = fh:read "*a"
  242. info = self:parse(content, name)
  243. fh:close()
  244. return info
  245. end
  246. errors[#errors + 1] = err or fn..": ".."unknown error"
  247. end
  248. if self.import_fallback then
  249. info = self.import_fallback(name)
  250. end
  251. if not info then
  252. error("module load error: "..name.."\n\t"..table.concat(errors, "\n\t"))
  253. end
  254. return info
  255. end
  256. -- parser
  257. local labels = { optional = 1; required = 2; repeated = 3 }
  258. local key_types = {
  259. int32 = 5; int64 = 3; uint32 = 13;
  260. uint64 = 4; sint32 = 17; sint64 = 18;
  261. fixed32 = 7; fixed64 = 6; sfixed32 = 15;
  262. sfixed64 = 16; bool = 8; string = 9;
  263. }
  264. local com_types = {
  265. group = 10; message = 11; enum = 14;
  266. }
  267. local types = {
  268. double = 1; float = 2; int32 = 5;
  269. int64 = 3; uint32 = 13; uint64 = 4;
  270. sint32 = 17; sint64 = 18; fixed32 = 7;
  271. fixed64 = 6; sfixed32 = 15; sfixed64 = 16;
  272. bool = 8; string = 9; bytes = 12;
  273. group = 10; message = 11; enum = 14;
  274. }
  275. local function register_type(self, lex, tname, type)
  276. if not tname:match "%."then
  277. tname = self.prefix..tname
  278. end
  279. if self.typemap[tname] then
  280. return lex:error("type %s already defined", tname)
  281. end
  282. self.typemap[tname] = type
  283. end
  284. local function type_info(lex, tname)
  285. local tenum = types[tname]
  286. if com_types[tname] then
  287. return lex:error("invalid type name: "..tname)
  288. elseif tenum then
  289. tname = nil
  290. end
  291. return tenum, tname
  292. end
  293. local function map_info(lex)
  294. local keyt = lex:ident "key type"
  295. if not key_types[keyt] then
  296. return lex:error("invalid key type: "..keyt)
  297. end
  298. local valt = lex:expected "," :type_name()
  299. local name = lex:expected ">" :ident()
  300. local ident = name:gsub("^%a", string.upper)
  301. :gsub("_(%a)", string.upper).."Entry"
  302. local kt, ktn = type_info(lex, keyt)
  303. local vt, vtn = type_info(lex, valt)
  304. return name, types.message, ident, {
  305. name = ident,
  306. field = {
  307. {
  308. name = "key",
  309. number = 1;
  310. label = labels.optional,
  311. type = kt,
  312. type_name = ktn
  313. },
  314. {
  315. name = "value",
  316. number = 2;
  317. label = labels.optional,
  318. type = vt,
  319. type_name = vtn
  320. },
  321. },
  322. options = { map_entry = true }
  323. }
  324. end
  325. local function inline_option(lex, info)
  326. if lex:test "%[" then
  327. info = info or {}
  328. while true do
  329. local name = lex:option_name()
  330. local value = lex:expected '=' :constant()
  331. info[name] = value
  332. if lex:test "%]" then
  333. return info
  334. end
  335. lex:expected ','
  336. end
  337. end
  338. end
  339. local function field(self, lex, ident)
  340. local name, type, type_name, map_entry
  341. if ident == "map" and lex:test "%<" then
  342. name, type, type_name, map_entry = map_info(lex)
  343. register_type(self, lex, type_name, types.message)
  344. else
  345. type, type_name = type_info(lex, ident)
  346. name = lex:ident()
  347. end
  348. local info = {
  349. name = name;
  350. number = lex:expected "=":integer();
  351. label = labels.optional;
  352. type = type;
  353. type_name = type_name;
  354. }
  355. local options = inline_option(lex)
  356. if options then
  357. info.default_value, options.default = tostring(options.default), nil
  358. info.json_name, options.json_name = options.json_name, nil
  359. end
  360. info.options = options
  361. if info.number <= 0 then
  362. lex:error("invalid tag number: "..info.number)
  363. end
  364. return info, map_entry
  365. end
  366. local function label_field(self, lex, ident)
  367. local label = labels[ident]
  368. local info, map_entry
  369. if not label then
  370. if self.syntax == "proto2" and ident ~= "map" then
  371. return lex:error("proto2 disallow missing label")
  372. end
  373. return field(self, lex, ident)
  374. end
  375. if label == labels.optional and self.syntax == "proto3" then
  376. return lex:error("proto3 disallow 'optional' label")
  377. end
  378. info, map_entry = field(self, lex, lex:type_name())
  379. info.label = label
  380. return info, map_entry
  381. end
  382. local function make_subparser(self, lex)
  383. local sub = {
  384. syntax = "proto2";
  385. locmap = {};
  386. prefix = ".";
  387. lex = lex;
  388. parent = self;
  389. }
  390. sub.loaded = self.loaded
  391. sub.typemap = self.typemap
  392. sub.paths = self.paths
  393. function sub.import_fallback(import_name)
  394. if self.unknown_import == true then
  395. return true
  396. elseif type(self.unknown_import) == 'string' then
  397. return import_name:match(self.unknown_import) and true or nil
  398. elseif self.unknown_import then
  399. return self:unknown_import(import_name)
  400. end
  401. end
  402. function sub.type_fallback(type_name)
  403. if self.unknown_type == true then
  404. return true
  405. elseif type(self.unknown_type) == 'string' then
  406. return type_name:match(self.unknown_type) and true
  407. elseif self.unknown_type then
  408. return self:unknown_type(type_name)
  409. end
  410. end
  411. function sub.on_import(info)
  412. if self.on_import then
  413. return self.on_import(info)
  414. end
  415. end
  416. return setmetatable(sub, Parser)
  417. end
  418. local toplevel = {} do
  419. function toplevel:package(lex, info)
  420. local package = lex:full_ident 'package name'
  421. lex:line_end()
  422. info.package = package
  423. self.prefix = "."..package.."."
  424. return self
  425. end
  426. function toplevel:import(lex, info)
  427. local mode = lex:ident('"weak" or "public"', 'opt') or "public"
  428. if mode ~= 'weak' and mode ~= 'public' then
  429. return lex:error '"weak or "public" expected'
  430. end
  431. local name = lex:quote()
  432. lex:line_end()
  433. local result = self:parsefile(name)
  434. if self.on_import then
  435. self.on_import(result)
  436. end
  437. local dep = default(info, 'dependency')
  438. local index = #dep
  439. dep[index+1] = name
  440. if mode == "public" then
  441. local it = default(info, 'public_dependency')
  442. it[#it+1] = index
  443. else
  444. local it = default(info, 'weak_dependency')
  445. it[#it+1] = index
  446. end
  447. end
  448. local msg_body = {} do
  449. function msg_body:message(lex, info)
  450. local nested_type = default(info, 'nested_type')
  451. nested_type[#nested_type+1] = toplevel.message(self, lex)
  452. return self
  453. end
  454. function msg_body:enum(lex, info)
  455. local nested_type = default(info, 'enum_type')
  456. nested_type[#nested_type+1] = toplevel.enum(self, lex)
  457. return self
  458. end
  459. function msg_body:extend(lex, info)
  460. local extension = default(info, 'extension')
  461. local nested_type = default(info, 'nested_type')
  462. local ft, mt = toplevel.extend(self, lex, {})
  463. for _, v in ipairs(ft) do
  464. extension[#extension+1] = v
  465. end
  466. for _, v in ipairs(mt) do
  467. nested_type[#nested_type+1] = v
  468. end
  469. return self
  470. end
  471. function msg_body:extensions(lex, info)
  472. local rt = default(info, 'extension_range')
  473. repeat
  474. local start = lex:integer "field number range"
  475. local stop = math.floor(2^29)
  476. lex:keyword 'to'
  477. if not lex:keyword('max', 'opt') then
  478. stop = lex:integer "field number range end or 'max'"
  479. end
  480. rt[#rt+1] = { start = start, ['end'] = stop }
  481. until not lex:test ','
  482. lex:line_end()
  483. return self
  484. end
  485. function msg_body:reserved(lex, info)
  486. if lex:test '%a' then
  487. local rt = default(info, 'reserved_name')
  488. repeat
  489. rt[#rt+1] = lex:ident 'field name'
  490. until not lex:test ','
  491. else
  492. local rt = default(info, 'reserved_range')
  493. local first = true
  494. repeat
  495. local start = lex:integer(first and 'field name or number range'
  496. or 'field number range')
  497. if lex:keyword('to', 'opt') then
  498. local stop = lex:integer 'field number range end'
  499. rt[#rt+1] = { start = start, ['end'] = stop }
  500. else
  501. rt[#rt+1] = { start = start, ['end'] = start }
  502. end
  503. first = false
  504. until not lex:test ','
  505. end
  506. lex:line_end()
  507. return self
  508. end
  509. function msg_body:oneof(lex, info)
  510. local fs = default(info, "field")
  511. local ts = default(info, "nested_type")
  512. local ot = default(info, "oneof_decl")
  513. local index = #ot + 1
  514. local oneof = { name = lex:ident() }
  515. lex:expected "{"
  516. while not lex:test "}" do
  517. local ident = lex:type_name()
  518. if ident == "option" then
  519. toplevel.option(self, lex, oneof)
  520. else
  521. local f, t = field(self, lex, ident, "no_label")
  522. if t then ts[#ts+1] = t end
  523. f.oneof_index = index - 1
  524. fs[#fs+1] = f
  525. end
  526. lex:line_end 'opt'
  527. end
  528. ot[index] = oneof
  529. end
  530. end
  531. function toplevel:message(lex, info)
  532. local name = lex:ident 'message name'
  533. local type = { name = name }
  534. register_type(self, lex, name, types.message)
  535. local prefix = self.prefix
  536. self.prefix = prefix..name.."."
  537. lex:expected "{"
  538. while not lex:test "}" do
  539. local ident, pos = lex:type_name()
  540. local body_parser = msg_body[ident]
  541. if body_parser then
  542. body_parser(self, lex, type)
  543. else
  544. local fs = default(type, 'field')
  545. local f, t = label_field(self, lex, ident)
  546. self.locmap[f] = pos
  547. fs[#fs+1] = f
  548. if t then
  549. local ts = default(type, 'nested_type')
  550. ts[#ts+1] = t
  551. end
  552. end
  553. lex:line_end 'opt'
  554. end
  555. lex:line_end 'opt'
  556. if info then
  557. info = default(info, 'message_type')
  558. info[#info+1] = type
  559. end
  560. self.prefix = prefix
  561. return type
  562. end
  563. function toplevel:enum(lex, info)
  564. local name = lex:ident 'enum name'
  565. local enum = { name = name }
  566. register_type(self, lex, name, types.enum)
  567. lex:expected "{"
  568. while not lex:test "}" do
  569. local ident = lex:ident 'enum constant name'
  570. if ident == 'option' then
  571. toplevel.option(self, lex, default(enum, 'options'))
  572. else
  573. local values = default(enum, 'value')
  574. local number = lex:expected '=' :integer()
  575. lex:line_end()
  576. values[#values+1] = {
  577. name = ident,
  578. number = number,
  579. options = inline_option(lex)
  580. }
  581. end
  582. lex:line_end 'opt'
  583. end
  584. lex:line_end 'opt'
  585. if info then
  586. info = default(info, 'enum_type')
  587. info[#info+1] = enum
  588. end
  589. return enum
  590. end
  591. function toplevel:option(lex, info)
  592. local ident = lex:option_name()
  593. lex:expected "="
  594. local value = lex:constant()
  595. lex:line_end()
  596. local options = info and default(info, 'options') or {}
  597. options[ident] = value
  598. return options, self
  599. end
  600. function toplevel:extend(lex, info)
  601. local name = lex:type_name()
  602. local ft = info and default(info, 'extension') or {}
  603. local mt = info and default(info, 'message_type') or {}
  604. lex:expected "{"
  605. while not lex:test "}" do
  606. local ident, pos = lex:type_name()
  607. local f, t = label_field(self, lex, ident)
  608. self.locmap[f] = pos
  609. f.extendee = name
  610. ft[#ft+1] = f
  611. mt[#mt+1] = t
  612. lex:line_end 'opt'
  613. end
  614. return ft, mt
  615. end
  616. local svr_body = {} do
  617. function svr_body:rpc(lex, info)
  618. local name, pos = lex:ident "rpc name"
  619. local rpc = { name = name }
  620. self.locmap[rpc] = pos
  621. local _, tn
  622. lex:expected "%("
  623. rpc.client_stream = lex:keyword("stream", "opt")
  624. _, tn = type_info(lex, lex:type_name())
  625. if not tn then return lex:error "rpc input type must by message" end
  626. rpc.input_type = tn
  627. lex:expected "%)" :expected "returns" :expected "%("
  628. rpc.server_stream = lex:keyword("stream", "opt")
  629. _, tn = type_info(lex, lex:type_name())
  630. if not tn then return lex:error "rpc output type must by message" end
  631. rpc.output_type = tn
  632. lex:expected "%)"
  633. if lex:test "{" then
  634. while not lex:test "}" do
  635. lex:line_end "opt"
  636. lex:keyword "option"
  637. toplevel.option(self, lex, default(rpc, 'options'))
  638. end
  639. end
  640. lex:line_end "opt"
  641. local t = default(info, "method")
  642. t[#t+1] = rpc
  643. end
  644. function svr_body.stream(_, lex)
  645. lex:error "stream not implement yet"
  646. end
  647. end
  648. function toplevel:service(lex, info)
  649. local name = lex:ident 'service name'
  650. local svr = { name = name }
  651. lex:expected "{"
  652. while not lex:test "}" do
  653. local ident = lex:type_name()
  654. local body_parser = svr_body[ident]
  655. if body_parser then
  656. body_parser(self, lex, svr)
  657. else
  658. return lex:error "expected 'rpc' or 'option' in service body"
  659. end
  660. lex:line_end 'opt'
  661. end
  662. lex:line_end 'opt'
  663. if info then
  664. info = default(info, 'service')
  665. info[#info+1] = svr
  666. end
  667. return svr
  668. end
  669. end
  670. function Parser:parse(src, name)
  671. name = name or "<input>"
  672. local loaded = self.loaded[name]
  673. if loaded then
  674. if loaded == true then
  675. error("loop loaded: "..name)
  676. end
  677. return loaded
  678. end
  679. local lex = Lexer.new(name or "<input>", src)
  680. local info = { name = lex.name }
  681. if name then self.loaded[name] = true end
  682. local ctx = make_subparser(self, lex)
  683. local syntax = lex:keyword('syntax', 'opt')
  684. if syntax then
  685. info.syntax = lex:expected '=' :quote()
  686. ctx.syntax = info.syntax
  687. lex:line_end()
  688. end
  689. while not lex:eof() do
  690. local ident = lex:ident()
  691. local top_parser = toplevel[ident]
  692. if top_parser then
  693. top_parser(ctx, lex, info)
  694. else
  695. lex:error("unknown keyword '"..ident.."'")
  696. end
  697. lex:line_end "opt"
  698. end
  699. if name then self.loaded[name] = info end
  700. return ctx:resolve(lex, info)
  701. end
  702. -- resolver
  703. local function empty() end
  704. local function iter(t, k)
  705. local v = t[k]
  706. if v then return ipairs(v) end
  707. return empty
  708. end
  709. local function check_dup(self, lex, type, map, k, v)
  710. local old = map[v[k]]
  711. if old then
  712. local ln, co = lex:pos2loc(self.locmap[old])
  713. lex:error("%s '%s' exists, previous at %d:%d",
  714. type, v[k], ln, co)
  715. end
  716. map[v[k]] = v
  717. end
  718. local function check_type(self, lex, tname)
  719. if tname:match "^%." then
  720. local t = self.typemap[tname]
  721. if not t then
  722. return lex:error("unknown type '%s'", tname)
  723. end
  724. return t, tname
  725. end
  726. local prefix = self.prefix
  727. for i = #prefix+1, 1, -1 do
  728. local op = prefix[i]
  729. prefix[i] = tname
  730. local tn = table.concat(prefix, ".", 1, i)
  731. prefix[i] = op
  732. local t = self.typemap[tn]
  733. if t then return t, tn end
  734. end
  735. local tn, t
  736. if self.type_fallback then
  737. tn, t = self.type_fallback(tname)
  738. end
  739. if tn then
  740. t = types[t or "message"]
  741. if tn == true then tn = "."..tname end
  742. return t, tn
  743. end
  744. return lex:error("unknown type '%s'", tname)
  745. end
  746. local function check_field(self, lex, info)
  747. if info.extendee then
  748. local t, tn = check_type(self, lex, info.extendee)
  749. if t ~= types.message then
  750. lex:error("message type expected in extension")
  751. end
  752. info.extendee = tn
  753. end
  754. if info.type_name then
  755. local t, tn = check_type(self, lex, info.type_name)
  756. info.type = t
  757. info.type_name = tn
  758. end
  759. end
  760. local function check_enum(self, lex, info)
  761. local names, numbers = {}, {}
  762. for _, v in iter(info, 'value') do
  763. lex.pos = self.locmap[v]
  764. check_dup(self, lex, 'enum name', names, 'name', v)
  765. if info.options and info.options.options and info.options.options.allow_alias then
  766. --nothing todo for allow_alias skip the enum value check
  767. else
  768. check_dup(self, lex, 'enum number', numbers, 'number', v)
  769. end
  770. end
  771. end
  772. local function check_message(self, lex, info)
  773. self.prefix[#self.prefix+1] = info.name
  774. local names, numbers = {}, {}
  775. for _, v in iter(info, 'field') do
  776. lex.pos = self.locmap[v]
  777. check_dup(self, lex, 'field name', names, 'name', v)
  778. check_dup(self, lex, 'field number', numbers, 'number', v)
  779. check_field(self, lex, v)
  780. end
  781. for _, v in iter(info, 'extension') do
  782. lex.pos = self.locmap[v]
  783. check_field(self, lex, v)
  784. end
  785. self.prefix[#self.prefix] = nil
  786. end
  787. local function check_service(self, lex, info)
  788. local names = {}
  789. for _, v in iter(info, 'method') do
  790. lex.pos = self.locmap[v]
  791. check_dup(self, lex, 'rpc name', names, 'name', v)
  792. local t, tn = check_type(self, lex, v.input_type)
  793. v.input_type = tn
  794. if t ~= types.message then
  795. lex:error "message type expected in parameter"
  796. end
  797. t, tn = check_type(self, lex, v.output_type)
  798. v.output_type = tn
  799. if t ~= types.message then
  800. lex:error "message type expected in return"
  801. end
  802. end
  803. end
  804. function Parser:resolve(lex, info)
  805. self.prefix = { "", info.package }
  806. for _, v in iter(info, 'message_type') do
  807. check_message(self, lex, v)
  808. end
  809. for _, v in iter(info, 'enum_type') do
  810. check_enum(self, lex, v)
  811. end
  812. for _, v in iter(info, 'service') do
  813. check_service(self, lex, v)
  814. end
  815. for _, v in iter(info, 'extension') do
  816. lex.pos = self.locmap[v]
  817. check_field(self, lex, v)
  818. end
  819. self.prefix = nil
  820. return info
  821. end
  822. end
  823. local has_pb, pb = pcall(require, "pb") do
  824. if has_pb then
  825. local descriptor_pb =
  826. "\10\249#\10\16descriptor.proto\18\15google.protobuf\"G\10\17FileDescript"..
  827. "orSet\0182\10\4file\24\1 \3(\0112$.google.protobuf.FileDescriptorProto\""..
  828. "\219\3\10\19FileDescriptorProto\18\12\10\4name\24\1 \1(\9\18\15\10\7pack"..
  829. "age\24\2 \1(\9\18\18\10\10dependency\24\3 \3(\9\18\25\10\17public_depend"..
  830. "ency\24\10 \3(\5\18\23\10\15weak_dependency\24\11 \3(\5\0186\10\12messag"..
  831. "e_type\24\4 \3(\0112 .google.protobuf.DescriptorProto\0187\10\9enum_type"..
  832. "\24\5 \3(\0112$.google.protobuf.EnumDescriptorProto\0188\10\7service\24"..
  833. "\6 \3(\0112'.google.protobuf.ServiceDescriptorProto\0188\10\9extension"..
  834. "\24\7 \3(\0112%.google.protobuf.FieldDescriptorProto\18-\10\7options\24"..
  835. "\8 \1(\0112\28.google.protobuf.FileOptions\0189\10\16source_code_info\24"..
  836. "\9 \1(\0112\31.google.protobuf.SourceCodeInfo\18\14\10\6syntax\24\12 \1("..
  837. "\9\"\228\3\10\15DescriptorProto\18\12\10\4name\24\1 \1(\9\0184\10\5field"..
  838. "\24\2 \3(\0112%.google.protobuf.FieldDescriptorProto\0188\10\9extension"..
  839. "\24\6 \3(\0112%.google.protobuf.FieldDescriptorProto\0185\10\11nested_ty"..
  840. "pe\24\3 \3(\0112 .google.protobuf.DescriptorProto\0187\10\9enum_type\24"..
  841. "\4 \3(\0112$.google.protobuf.EnumDescriptorProto\18H\10\15extension_rang"..
  842. "e\24\5 \3(\0112/.google.protobuf.DescriptorProto.ExtensionRange\0189\10"..
  843. "\10oneof_decl\24\8 \3(\0112%.google.protobuf.OneofDescriptorProto\0180"..
  844. "\10\7options\24\7 \1(\0112\31.google.protobuf.MessageOptions\26,\10\14Ex"..
  845. "tensionRange\18\13\10\5start\24\1 \1(\5\18\11\10\3end\24\2 \1(\5\"\169\5"..
  846. "\10\20FieldDescriptorProto\18\12\10\4name\24\1 \1(\9\18\14\10\6number\24"..
  847. "\3 \1(\5\18:\10\5label\24\4 \1(\0142+.google.protobuf.FieldDescriptorPro"..
  848. "to.Label\0188\10\4type\24\5 \1(\0142*.google.protobuf.FieldDescriptorPro"..
  849. "to.Type\18\17\10\9type_name\24\6 \1(\9\18\16\10\8extendee\24\2 \1(\9\18"..
  850. "\21\10\13default_value\24\7 \1(\9\18\19\10\11oneof_index\24\9 \1(\5\18."..
  851. "\10\7options\24\8 \1(\0112\29.google.protobuf.FieldOptions\"\182\2\10\4T"..
  852. "ype\18\15\10\11TYPE_DOUBLE\16\1\18\14\10\10TYPE_FLOAT\16\2\18\14\10\10TY"..
  853. "PE_INT64\16\3\18\15\10\11TYPE_UINT64\16\4\18\14\10\10TYPE_INT32\16\5\18"..
  854. "\16\10\12TYPE_FIXED64\16\6\18\16\10\12TYPE_FIXED32\16\7\18\13\10\9TYPE_B"..
  855. "OOL\16\8\18\15\10\11TYPE_STRING\16\9\18\14\10\10TYPE_GROUP\16\10\18\16"..
  856. "\10\12TYPE_MESSAGE\16\11\18\14\10\10TYPE_BYTES\16\12\18\15\10\11TYPE_UIN"..
  857. "T32\16\13\18\13\10\9TYPE_ENUM\16\14\18\17\10\13TYPE_SFIXED32\16\15\18\17"..
  858. "\10\13TYPE_SFIXED64\16\16\18\15\10\11TYPE_SINT32\16\17\18\15\10\11TYPE_S"..
  859. "INT64\16\18\"C\10\5Label\18\18\10\14LABEL_OPTIONAL\16\1\18\18\10\14LABEL"..
  860. "_REQUIRED\16\2\18\18\10\14LABEL_REPEATED\16\3\"$\10\20OneofDescriptorPro"..
  861. "to\18\12\10\4name\24\1 \1(\9\"\140\1\10\19EnumDescriptorProto\18\12\10\4"..
  862. "name\24\1 \1(\9\0188\10\5value\24\2 \3(\0112).google.protobuf.EnumValueD"..
  863. "escriptorProto\18-\10\7options\24\3 \1(\0112\28.google.protobuf.EnumOpti"..
  864. "ons\"l\10\24EnumValueDescriptorProto\18\12\10\4name\24\1 \1(\9\18\14\10"..
  865. "\6number\24\2 \1(\5\0182\10\7options\24\3 \1(\0112!.google.protobuf.Enum"..
  866. "ValueOptions\"\144\1\10\22ServiceDescriptorProto\18\12\10\4name\24\1 \1("..
  867. "\9\0186\10\6method\24\2 \3(\0112&.google.protobuf.MethodDescriptorProto"..
  868. "\0180\10\7options\24\3 \1(\0112\31.google.protobuf.ServiceOptions\"\193"..
  869. "\1\10\21MethodDescriptorProto\18\12\10\4name\24\1 \1(\9\18\18\10\10input"..
  870. "_type\24\2 \1(\9\18\19\10\11output_type\24\3 \1(\9\18/\10\7options\24\4 "..
  871. "\1(\0112\30.google.protobuf.MethodOptions\18\31\10\16client_streaming\24"..
  872. "\5 \1(\8:\5false\18\31\10\16server_streaming\24\6 \1(\8:\5false\"\231\4"..
  873. "\10\11FileOptions\18\20\10\12java_package\24\1 \1(\9\18\28\10\20java_out"..
  874. "er_classname\24\8 \1(\9\18\"\10\19java_multiple_files\24\10 \1(\8:\5fals"..
  875. "e\18,\10\29java_generate_equals_and_hash\24\20 \1(\8:\5false\18%\10\22ja"..
  876. "va_string_check_utf8\24\27 \1(\8:\5false\18F\10\12optimize_for\24\9 \1("..
  877. "\0142).google.protobuf.FileOptions.OptimizeMode:\5SPEED\18\18\10\10go_pa"..
  878. "ckage\24\11 \1(\9\18\"\10\19cc_generic_services\24\16 \1(\8:\5false\18$"..
  879. "\10\21java_generic_services\24\17 \1(\8:\5false\18\"\10\19py_generic_ser"..
  880. "vices\24\18 \1(\8:\5false\18\25\10\10deprecated\24\23 \1(\8:\5false\18"..
  881. "\31\10\16cc_enable_arenas\24\31 \1(\8:\5false\18\25\10\17objc_class_pref"..
  882. "ix\24$ \1(\9\18C\10\20uninterpreted_option\24\231\7 \3(\0112$.google.pro"..
  883. "tobuf.UninterpretedOption\":\10\12OptimizeMode\18\9\10\5SPEED\16\1\18\13"..
  884. "\10\9CODE_SIZE\16\2\18\16\10\12LITE_RUNTIME\16\3*\9\8\232\7\16\128\128"..
  885. "\128\128\2\"\230\1\10\14MessageOptions\18&\10\23message_set_wire_format"..
  886. "\24\1 \1(\8:\5false\18.\10\31no_standard_descriptor_accessor\24\2 \1(\8:"..
  887. "\5false\18\25\10\10deprecated\24\3 \1(\8:\5false\18\17\10\9map_entry\24"..
  888. "\7 \1(\8\18C\10\20uninterpreted_option\24\231\7 \3(\0112$.google.protobu"..
  889. "f.UninterpretedOption*\9\8\232\7\16\128\128\128\128\2\"\160\2\10\12Field"..
  890. "Options\18:\10\5ctype\24\1 \1(\0142#.google.protobuf.FieldOptions.CType:"..
  891. "\6STRING\18\14\10\6packed\24\2 \1(\8\18\19\10\4lazy\24\5 \1(\8:\5false"..
  892. "\18\25\10\10deprecated\24\3 \1(\8:\5false\18\19\10\4weak\24\10 \1(\8:\5f"..
  893. "alse\18C\10\20uninterpreted_option\24\231\7 \3(\0112$.google.protobuf.Un"..
  894. "interpretedOption\"/\10\5CType\18\10\10\6STRING\16\0\18\8\10\4CORD\16\1"..
  895. "\18\16\10\12STRING_PIECE\16\2*\9\8\232\7\16\128\128\128\128\2\"\141\1\10"..
  896. "\11EnumOptions\18\19\10\11allow_alias\24\2 \1(\8\18\25\10\10deprecated"..
  897. "\24\3 \1(\8:\5false\18C\10\20uninterpreted_option\24\231\7 \3(\0112$.goo"..
  898. "gle.protobuf.UninterpretedOption*\9\8\232\7\16\128\128\128\128\2\"}\10"..
  899. "\16EnumValueOptions\18\25\10\10deprecated\24\1 \1(\8:\5false\18C\10\20un"..
  900. "interpreted_option\24\231\7 \3(\0112$.google.protobuf.UninterpretedOptio"..
  901. "n*\9\8\232\7\16\128\128\128\128\2\"{\10\14ServiceOptions\18\25\10\10depr"..
  902. "ecated\24! \1(\8:\5false\18C\10\20uninterpreted_option\24\231\7 \3(\0112"..
  903. "$.google.protobuf.UninterpretedOption*\9\8\232\7\16\128\128\128\128\2\"z"..
  904. "\10\13MethodOptions\18\25\10\10deprecated\24! \1(\8:\5false\18C\10\20uni"..
  905. "nterpreted_option\24\231\7 \3(\0112$.google.protobuf.UninterpretedOption"..
  906. "*\9\8\232\7\16\128\128\128\128\2\"\158\2\10\19UninterpretedOption\18;\10"..
  907. "\4name\24\2 \3(\0112-.google.protobuf.UninterpretedOption.NamePart\18\24"..
  908. "\10\16identifier_value\24\3 \1(\9\18\26\10\18positive_int_value\24\4 \1("..
  909. "\4\18\26\10\18negative_int_value\24\5 \1(\3\18\20\10\12double_value\24\6"..
  910. "\32\1(\1\18\20\10\12string_value\24\7 \1(\12\18\23\10\15aggregate_value"..
  911. "\24\8 \1(\9\0263\10\8NamePart\18\17\10\9name_part\24\1 \2(\9\18\20\10\12"..
  912. "is_extension\24\2 \2(\8\"\213\1\10\14SourceCodeInfo\18:\10\8location\24"..
  913. "\1 \3(\0112(.google.protobuf.SourceCodeInfo.Location\26\134\1\10\8Locati"..
  914. "on\18\16\10\4path\24\1 \3(\5B\2\16\1\18\16\10\4span\24\2 \3(\5B\2\16\1"..
  915. "\18\24\10\16leading_comments\24\3 \1(\9\18\25\10\17trailing_comments\24"..
  916. "\4 \1(\9\18!\10\25leading_detached_comments\24\6 \3(\9B)\10\19com.google"..
  917. ".protobufB\16DescriptorProtosH\1"
  918. function Parser.reload()
  919. assert(pb.load(descriptor_pb))
  920. end
  921. local function do_compile(self, f, ...)
  922. if self.include_imports then
  923. local old = self.on_import
  924. local infos = {}
  925. function self.on_import(info)
  926. infos[#infos+1] = info
  927. end
  928. local r = f(...)
  929. infos[#infos+1] = r
  930. self.on_import = old
  931. return { file = infos }
  932. end
  933. return { file = { f(...) } }
  934. end
  935. function Parser:compile(s, name)
  936. local set = do_compile(self, self.parse, self, s, name)
  937. return assert(pb.encode('.google.protobuf.FileDescriptorSet', set))
  938. end
  939. function Parser:compilefile(fn)
  940. local set = do_compile(self, self.parsefile, self, fn)
  941. return assert(pb.encode('.google.protobuf.FileDescriptorSet', set))
  942. end
  943. function Parser:load(s, name)
  944. local ret, pos = pb.load(self:compile(s, name))
  945. if ret then return ret, pos end
  946. error("load failed at offset "..pos)
  947. end
  948. function Parser:loadfile(fn)
  949. local ret, pos = pb.load(self:compilefile(fn))
  950. if ret then return ret, pos end
  951. error("load failed at offset "..pos)
  952. end
  953. Parser.reload()
  954. end
  955. end
  956. return Parser