PageRenderTime 53ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/protobuf/compile/parse.scm

http://r6rs-protobuf.googlecode.com/
Scheme | 799 lines | 709 code | 78 blank | 12 comment | 1 complexity | 8c410f38a5b318de52e3644dd49c92ab MD5 | raw file
Possible License(s): GPL-3.0
  1. ;; parse.scm: .proto format parsing routines for r6rs-protobuf
  2. ;; Copyright (C) 2011 Julian Graham
  3. ;; r6rs-protobuf is free software: you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation, either version 3 of the License, or
  6. ;; (at your option) any later version.
  7. ;; This program is distributed in the hope that it will be useful,
  8. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. ;; GNU General Public License for more details.
  11. ;; You should have received a copy of the GNU General Public License
  12. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. #!r6rs
  14. (library (protobuf compile parse)
  15. (export protoc:make-parser
  16. protoc:proto?
  17. protoc:make-proto
  18. protoc:proto-root-package
  19. protoc:proto-options
  20. protoc:make-option-declaration
  21. protoc:option-declaration?
  22. protoc:option-declaration-name
  23. protoc:option-declaration-value
  24. protoc:make-package
  25. protoc:package
  26. protoc:package?
  27. protoc:package-name
  28. protoc:package-definitions
  29. protoc:package-options
  30. protoc:package-required-packages
  31. protoc:package-subpackages
  32. protoc:set-package-definitions!
  33. protoc:set-package-subpackages!
  34. protoc:make-message-definition
  35. protoc:message-definition?
  36. protoc:message-definition-name
  37. protoc:message-definition-definitions
  38. protoc:message-definition-extension-ranges
  39. protoc:message-definition-fields
  40. protoc:message-definition-options
  41. protoc:message-definition-parent
  42. protoc:set-message-definition-extension-ranges!
  43. protoc:set-message-definition-fields!
  44. protoc:make-extension-range-definition
  45. protoc:extension-range-definition?
  46. protoc:extension-range-definition-from
  47. protoc:extension-range-definition-to
  48. protoc:make-extension-definition
  49. protoc:extension-definition?
  50. protoc:extension-definition-fields
  51. protoc:extension-definition-parent
  52. protoc:extension-definition-target
  53. protoc:make-enum-definition
  54. protoc:enum-definition?
  55. protoc:enum-definition-name
  56. protoc:enum-definition-values
  57. protoc:enum-definition-options
  58. protoc:enum-definition-parent
  59. protoc:set-enum-definition-values!
  60. protoc:make-enum-value-definition
  61. protoc:enum-value-definition?
  62. protoc:enum-value-definition-name
  63. protoc:enum-value-definition-ordinal
  64. protoc:make-type-reference
  65. protoc:type-reference?
  66. protoc:type-reference-name
  67. protoc:type-reference-descriptor
  68. protoc:type-reference-location
  69. protoc:set-type-reference-location!
  70. protoc:make-field-definition
  71. protoc:field-definition?
  72. protoc:field-definition-rule
  73. protoc:field-definition-type
  74. protoc:field-definition-name
  75. protoc:field-definition-ordinal
  76. protoc:field-definition-options)
  77. (import (rnrs)
  78. (protobuf private)
  79. (protobuf compile tokenize)
  80. (srfi :13)
  81. (srfi :14))
  82. (define (string-split str chr)
  83. (string-tokenize str (char-set-complement (char-set chr))))
  84. (define-record-type (protoc:proto protoc:make-proto protoc:proto?)
  85. (fields root-package
  86. (mutable imports
  87. protoc:proto-imports
  88. protoc:set-proto-imports!)
  89. (mutable options
  90. protoc:proto-options
  91. protoc:set-proto-options!))
  92. (protocol
  93. (lambda (p)
  94. (lambda (root-package . rest)
  95. (case (length rest)
  96. ((0) (p root-package '() '()))
  97. ((1) (p root-package (car rest) '()))
  98. ((2) (p root-package (car rest) (cadr rest)))
  99. (else (raise (make-assertion-violation))))))))
  100. (define-record-type (protoc:package protoc:make-package protoc:package?)
  101. (fields name
  102. parent
  103. (mutable required-packages
  104. protoc:package-required-packages
  105. protoc:set-package-required-packages!)
  106. (mutable definitions
  107. protoc:package-definitions
  108. protoc:set-package-definitions!)
  109. (mutable subpackages
  110. protoc:package-subpackages
  111. protoc:set-package-subpackages!)
  112. (mutable options
  113. protoc:package-options
  114. protoc:set-package-options!))
  115. (protocol
  116. (lambda (p)
  117. (lambda (name parent . rest)
  118. (case (length rest)
  119. ((0) (p name parent '() '() '() '()))
  120. ((1) (p name parent (car rest) '() '() '()))
  121. ((2) (p name parent (car rest) (cadr rest) '() '()))
  122. ((3) (p name parent (car rest) (cadr rest) (caddr rest) '()))
  123. ((4) (apply p (cons name (cons parent rest))))
  124. (else (raise (make-assertion-violation))))))))
  125. (define-record-type (protoc:extension-range-definition
  126. protoc:make-extension-range-definition
  127. protoc:extension-range-definition?)
  128. (fields from to))
  129. (define-record-type (protoc:extension-definition
  130. protoc:make-extension-definition
  131. protoc:extension-definition?)
  132. (fields target
  133. parent
  134. package
  135. (mutable fields
  136. protoc:extension-definition-fields
  137. protoc:set-extension-definition-fields!))
  138. (protocol
  139. (lambda (p)
  140. (lambda (target parent . rest)
  141. (p target parent (and (not (null? rest)) (car rest)) '())))))
  142. (define-record-type (protoc:option-declaration
  143. protoc:make-option-declaration
  144. protoc:option-declaration?)
  145. (fields name value))
  146. (define-record-type (protoc:message-definition
  147. protoc:make-message-definition
  148. protoc:message-definition?)
  149. (fields name
  150. parent
  151. package
  152. (mutable extension-ranges
  153. protoc:message-definition-extension-ranges
  154. protoc:set-message-definition-extension-ranges!)
  155. (mutable options
  156. protoc:message-definition-options
  157. protoc:set-message-definition-options!)
  158. (mutable fields
  159. protoc:message-definition-fields
  160. protoc:set-message-definition-fields!)
  161. (mutable definitions
  162. protoc:message-definition-definitions
  163. protoc:set-message-definition-definitions!))
  164. (protocol
  165. (lambda (p)
  166. (lambda (name package . parent)
  167. (p name (and (not (null? parent)) (car parent))
  168. package '() '() '() '())))))
  169. (define-record-type (protoc:type-reference
  170. protoc:make-type-reference
  171. protoc:type-reference?)
  172. (fields name
  173. (mutable descriptor
  174. protoc:type-reference-descriptor
  175. protoc:set-type-reference-descriptor!)
  176. (mutable location
  177. protoc:type-reference-location
  178. protoc:set-type-reference-location!))
  179. (protocol
  180. (lambda (p)
  181. (lambda (name . descriptor)
  182. (p name (and (not (null? descriptor)) (car descriptor)) #f)))))
  183. (define-record-type (protoc:field-definition
  184. protoc:make-field-definition
  185. protoc:field-definition?)
  186. (fields parent
  187. rule
  188. type
  189. name
  190. ordinal
  191. (mutable options
  192. protoc:field-definition-options
  193. protoc:set-field-definition-options!))
  194. (protocol (lambda (p)
  195. (lambda (message rule type name ordinal . options)
  196. (p message rule type name ordinal
  197. (if (null? options) options (car options)))))))
  198. (define-record-type (protoc:enum-value-definition
  199. protoc:make-enum-value-definition
  200. protoc:enum-value-definition?)
  201. (fields name ordinal))
  202. (define-record-type (protoc:enum-definition
  203. protoc:make-enum-definition
  204. protoc:enum-definition?)
  205. (fields name
  206. parent
  207. package
  208. (mutable options
  209. protoc:enum-definition-options
  210. protoc:set-enum-definition-options!)
  211. (mutable values
  212. protoc:enum-definition-values
  213. protoc:set-enum-definition-values!))
  214. (protocol
  215. (lambda (p)
  216. (lambda (name package . parent)
  217. (p name (if (null? parent) #f (car parent)) package '() '() '())))))
  218. (define (merge-package! scope package) #f)
  219. (define (protoc:make-parser lexer)
  220. (define unresolved-type-references (list))
  221. (define unresolved-extensions (list))
  222. (define resolved-type-descriptors (make-hashtable string-hash equal?))
  223. (define external-packages (make-hashtable string-hash equal?))
  224. (define internal-packages (make-hashtable string-hash equal?))
  225. (define root-package (protoc:make-package #f #f))
  226. (define proto (protoc:make-proto root-package))
  227. (define current-package root-package)
  228. (define current-token #f)
  229. (define current-category #f)
  230. (define current-value #f)
  231. (define token-stack (list))
  232. (define (unexpected-token-error)
  233. (raise (condition
  234. (make-assertion-violation)
  235. (make-message-condition
  236. (string-append "Unexpected token: "
  237. (symbol->string current-category))))))
  238. (define (get-token)
  239. (define (set-data token)
  240. (set! current-token token)
  241. (if (eq? token '*eoi*)
  242. (begin
  243. (set! current-category '*eoi*)
  244. (set! current-value '*eoi*))
  245. (begin
  246. (set! current-category
  247. (protoc:lexical-token-category current-token))
  248. (set! current-value
  249. (protoc:lexical-token-value current-token)))))
  250. (if (null? token-stack)
  251. (set-data (lexer))
  252. (begin (set-data (car token-stack))
  253. (set! token-stack (cdr token-stack)))))
  254. (define (unget-token token)
  255. (set! current-token #f)
  256. (set! current-category #f)
  257. (set! current-value #f)
  258. (set! token-stack (cons token token-stack)))
  259. (define (assert-next-category category)
  260. (get-token)
  261. (if (not (eq? current-category category))
  262. (unexpected-token-error)))
  263. (define (resolve-type type-reference)
  264. (define (resolve-type-relative name context)
  265. (define (resolve-type-relative-inner components context)
  266. (let* ((first-component (car components))
  267. (definitions
  268. (cond ((protoc:package? context)
  269. (protoc:package-definitions context))
  270. ((protoc:message-definition? context)
  271. (protoc:message-definition-definitions context))
  272. ((protoc:extension-definition? context) '())
  273. (else (raise (make-assertion-violation))))))
  274. (let loop ((definitions definitions))
  275. (and (not (null? definitions))
  276. (let ((definition (car definitions)))
  277. (cond ((protoc:message-definition? definition)
  278. (if (equal? first-component
  279. (protoc:message-definition-name
  280. definition))
  281. (if (= (length components) 1)
  282. definition
  283. (resolve-type-relative-inner
  284. (cdr components) definition))
  285. (loop (cdr definitions))))
  286. ((protoc:enum-definition? definition)
  287. (if (equal? first-component
  288. (protoc:enum-definition-name
  289. definition))
  290. definition
  291. (loop (cdr definitions))))
  292. (else (loop (cdr definitions)))))))))
  293. (resolve-type-relative-inner (string-split name #\.) context))
  294. (define (resolve-type-upwards name context)
  295. (let ((definition (resolve-type-relative name context)))
  296. (or definition
  297. (cond ((protoc:message-definition? context)
  298. (cond ((protoc:message-definition-parent context)
  299. (resolve-type-upwards
  300. name (protoc:message-definition-parent context)))
  301. ((protoc:message-definition-package context)
  302. (resolve-type-upwards
  303. name (protoc:message-definition-package context)))
  304. (else #f)))
  305. ((protoc:extension-definition? context)
  306. (cond ((protoc:extension-definition-parent context)
  307. (resolve-type-upwards
  308. name (protoc:extension-definition-parent context)))
  309. ((protoc:extension-definition-package context)
  310. (resolve-type-upwards
  311. name (protoc:extension-definition-package
  312. context)))
  313. (else #f)))
  314. ((protoc:package? context)
  315. (and (protoc:package-parent context)
  316. (resolve-type-upwards
  317. name (protoc:package-parent context))))
  318. (else (raise (make-assertion-violation)))))))
  319. (define (resolve-type-downwards name package)
  320. (define (strip-package-prefix name package-name)
  321. (and (string-prefix? (string-append package-name ".") name)
  322. (substring name (+ (string-length package-name) 1))))
  323. (let ((definition (resolve-type-relative name package)))
  324. (or definition
  325. (let ((components (string-split name #\.)))
  326. (and (> (length components) 1)
  327. (let loop ((subpackages
  328. (protoc:package-subpackages package)))
  329. (and (not (null? subpackages))
  330. (let* ((subpackage (car subpackages))
  331. (subname (strip-package-prefix
  332. name (protoc:package-name
  333. subpackage))))
  334. (or (and subname
  335. (resolve-type-downwards
  336. subname subpackage))
  337. (loop (cdr subpackages)))))))))))
  338. (define (definition->descriptor definition)
  339. (define (message-definition->descriptor definition)
  340. (protobuf:make-message-field-type-descriptor
  341. (protoc:message-definition-name definition)
  342. 'length-delimited #f #f #f #f definition))
  343. (define (enum-definition->descriptor definition)
  344. (protobuf:make-enum-field-type-descriptor
  345. (protoc:enum-definition-name definition)
  346. 'varint #f #f #f #f definition))
  347. (cond ((protoc:message-definition? definition)
  348. (message-definition->descriptor definition))
  349. ((protoc:enum-definition? definition)
  350. (enum-definition->descriptor definition))
  351. (else raise (make-assertion-violation))))
  352. (let* ((location (protoc:type-reference-location type-reference))
  353. (location (cond ((protoc:extension-definition? location) location)
  354. ((protoc:field-definition? location)
  355. (protoc:field-definition-parent location))
  356. (else (raise (make-assertion-violation)))))
  357. (package (cond ((protoc:extension-definition? location)
  358. (protoc:extension-definition-package location))
  359. ((protoc:message-definition? location)
  360. (protoc:message-definition-package location))
  361. (else #f)))
  362. (name (protoc:type-reference-name type-reference))
  363. (descriptor (hashtable-ref resolved-type-descriptors name #f))
  364. (definition (and (not descriptor)
  365. (or (resolve-type-upwards name location)
  366. (resolve-type-downwards name root-package))))
  367. (descriptor
  368. (or descriptor
  369. (and definition (definition->descriptor definition)))))
  370. (if descriptor
  371. (begin
  372. (if (not (hashtable-contains? resolved-type-descriptors name))
  373. (hashtable-set! resolved-type-descriptors name descriptor))
  374. (let ((definition-package
  375. (cond ((protoc:message-definition? definition)
  376. (protoc:message-definition-package definition))
  377. ((protoc:enum-definition? definition)
  378. (protoc:enum-definition-package definition))
  379. (else (raise (make-assertion-violation)))))
  380. (required-packages (protoc:package-required-packages
  381. package)))
  382. (if (and (not (equal? (protoc:package-name definition-package)
  383. (protoc:package-name package)))
  384. (not (memp (lambda (p)
  385. (equal? (protoc:package-name p)
  386. (protoc:package-name
  387. definition-package)))
  388. required-packages)))
  389. (protoc:set-package-required-packages!
  390. package (cons definition-package required-packages))))
  391. (protoc:set-type-reference-descriptor! type-reference descriptor))
  392. (raise (condition
  393. (make-assertion-violation)
  394. (make-message-condition
  395. (string-append "Reference to unknown type " name)))))))
  396. (define (resolve-extension extension-def)
  397. (define (valid-extension? extension-field message-def)
  398. (define idx (protoc:field-definition-ordinal extension-field))
  399. (define (extension-field-within-range? extension-range)
  400. (and (>= idx (protoc:extension-range-definition-from extension-range))
  401. (<= idx (protoc:extension-range-definition-to extension-range))))
  402. (find extension-field-within-range?
  403. (protoc:message-definition-extension-ranges message-def)))
  404. (let* ((type (protoc:extension-definition-target extension-def))
  405. (descriptor (protoc:type-reference-descriptor type)))
  406. (if (not (protobuf:message-field-type-descriptor? descriptor))
  407. (raise (condition
  408. (make-assertion-violation)
  409. (make-message-condition
  410. (string-append "Cannot extend non-message type "
  411. (protobuf:field-type-descriptor-name
  412. descriptor))))))
  413. (let ((m (protobuf:message-field-type-descriptor-definition
  414. descriptor)))
  415. (for-each
  416. (lambda (extension-field)
  417. (or (valid-extension? extension-field m)
  418. (raise
  419. (condition
  420. (make-assertion-violation)
  421. (make-message-condition
  422. (string-append "Invalid extension index "
  423. (number->string
  424. (protoc:field-definition-ordinal
  425. extension-field))
  426. " for message "
  427. (protoc:message-definition-name m)))))))
  428. (protoc:extension-definition-fields extension-def)))))
  429. (define (parse-type)
  430. (get-token)
  431. (case current-category
  432. ((DOUBLE)
  433. (protoc:make-type-reference "double" protobuf:field-type-double))
  434. ((FLOAT) (protoc:make-type-reference "float" protobuf:field-type-float))
  435. ((INT32) (protoc:make-type-reference "int32" protobuf:field-type-int32))
  436. ((INT64) (protoc:make-type-reference "int64" protobuf:field-type-int64))
  437. ((UINT32)
  438. (protoc:make-type-reference"uint32" protobuf:field-type-uint32))
  439. ((UINT64)
  440. (protoc:make-type-reference "uint64" protobuf:field-type-uint64))
  441. ((SINT32)
  442. (protoc:make-type-reference "sint32" protobuf:field-type-sint32))
  443. ((SINT64)
  444. (protoc:make-type-reference "sint64" protobuf:field-type-sint64))
  445. ((FIXED32)
  446. (protoc:make-type-reference "fixed32" protobuf:field-type-fixed32))
  447. ((FIXED64)
  448. (protoc:make-type-reference "fixed64" protobuf:field-type-fixed64))
  449. ((SFIXED32)
  450. (protoc:make-type-reference "sfixed32" protobuf:field-type-sfixed32))
  451. ((SFIXED64)
  452. (protoc:make-type-reference "sfixed64" protobuf:field-type-sfixed64))
  453. ((BOOL) (protoc:make-type-reference "bool" protobuf:field-type-bool))
  454. ((STRING)
  455. (protoc:make-type-reference "string" protobuf:field-type-string))
  456. ((BYTES) (protoc:make-type-reference "bytes" protobuf:field-type-bytes))
  457. ((IDENTIFIER)
  458. (let loop ((name ""))
  459. (let ((val current-value))
  460. (get-token)
  461. (if (eq? current-category 'DOT)
  462. (begin (get-token) (loop (string-append name val ".")))
  463. (begin (unget-token current-token)
  464. (protoc:make-type-reference
  465. (string-append name val)))))))
  466. (else (unexpected-token-error))))
  467. (define (parse-package)
  468. (define (parse-package-element parent pkg-name)
  469. (assert-next-category 'IDENTIFIER)
  470. (let* ((pkg-name (string-append pkg-name current-value))
  471. (package (hashtable-ref internal-packages pkg-name #f))
  472. (package
  473. (or package
  474. (let ((p (protoc:make-package pkg-name parent)))
  475. (hashtable-set! internal-packages pkg-name p)
  476. (protoc:set-package-subpackages!
  477. parent (cons p (protoc:package-subpackages parent)))
  478. p))))
  479. (set! current-package package)
  480. (get-token)
  481. (case current-category
  482. ((DOT) (parse-package-element package (string-append pkg-name ".")))
  483. ((SEMICOLON) package)
  484. (else (unexpected-token-error)))))
  485. (parse-package-element root-package ""))
  486. (define (parse-import)
  487. (define (merge-package to from)
  488. (protoc:set-package-definitions!
  489. to (append (protoc:package-definitions to)
  490. (protoc:package-definitions from)))
  491. (for-each (lambda (s)
  492. (let ((ts (find (lambda (x)
  493. (equal? (protoc:package-name x)
  494. (protoc:package-name s)))
  495. (protoc:package-subpackages to))))
  496. (if ts
  497. (merge-package ts s)
  498. (protoc:set-package-subpackages!
  499. to (cons s (protoc:package-subpackages to))))))
  500. (protoc:package-subpackages from)))
  501. (assert-next-category 'STRING-LITERAL)
  502. (let* ((lexer (protoc:make-tokenizer
  503. (open-input-file current-value)))
  504. (parser (protoc:make-parser lexer))
  505. (proto (parser)))
  506. (merge-package root-package (protoc:proto-root-package proto)))
  507. (assert-next-category 'SEMICOLON))
  508. (define (parse-enum parent)
  509. (define (parse-enum-elements enum)
  510. (define (parse-enum-field field-name)
  511. (assert-next-category 'EQUAL)
  512. (assert-next-category 'NUM-INTEGER)
  513. (let ((value (protoc:make-enum-value-definition
  514. field-name current-value)))
  515. (assert-next-category 'SEMICOLON)
  516. value))
  517. (get-token)
  518. (case current-category
  519. ((IDENTIFIER)
  520. (protoc:set-enum-definition-values!
  521. enum (cons (parse-enum-field current-value)
  522. (protoc:enum-definition-values enum)))
  523. (parse-enum-elements enum))
  524. ((OPTION) (parse-enum-elements enum))
  525. ((RBRACE) enum)
  526. (else (unexpected-token-error))))
  527. (assert-next-category 'IDENTIFIER)
  528. (let ((enum (protoc:make-enum-definition
  529. current-value current-package parent)))
  530. (assert-next-category 'LBRACE)
  531. (parse-enum-elements enum)))
  532. (define (parse-field parent rule)
  533. (define (parse-maybe-field-options)
  534. (define (parse-field-options-inner options)
  535. (define (parse-field-option)
  536. (let ((name current-value))
  537. (assert-next-category 'EQUAL)
  538. (get-token)
  539. (let ((value
  540. (cond ((memq current-category
  541. '(IDENTIFIER
  542. NUM-FLOAT
  543. NUM-INTEGER
  544. STRING-LITERAL))
  545. current-value)
  546. ((eq? current-category 'TRUE) #t)
  547. ((eq? current-category 'FALSE) #f)
  548. (else (unexpected-token-error)))))
  549. (get-token)
  550. (cond ((eq? current-category 'COMMA)
  551. (assert-next-category 'IDENTIFIER)
  552. (unget-token current-token))
  553. ((eq? current-category 'RBRACK)
  554. (unget-token current-token))
  555. (else (unexpected-token-error)))
  556. (protoc:make-option-declaration (string->symbol name) value))))
  557. (get-token)
  558. (cond ((eq? current-category 'RBRACK) (reverse options))
  559. ((eq? current-category 'IDENTIFIER)
  560. (parse-field-options-inner
  561. (cons (parse-field-option) options)))
  562. (else (unexpected-token-error))))
  563. (get-token)
  564. (if (eq? current-category 'LBRACK)
  565. (parse-field-options-inner '())
  566. (begin (unget-token current-token) #f)))
  567. (let ((type (parse-type)))
  568. (assert-next-category 'IDENTIFIER)
  569. (let ((field-name current-value))
  570. (assert-next-category 'EQUAL)
  571. (assert-next-category 'NUM-INTEGER)
  572. (let* ((index current-value)
  573. (options (parse-maybe-field-options))
  574. (fd (protoc:make-field-definition
  575. parent rule type field-name index options)))
  576. (if (not (protoc:type-reference-descriptor type))
  577. (set! unresolved-type-references
  578. (cons type unresolved-type-references)))
  579. (assert-next-category 'SEMICOLON)
  580. (protoc:set-type-reference-location! type fd)
  581. fd))))
  582. (define (parse-message parent)
  583. (define (parse-message-element message-def)
  584. (define (parse-extension-ranges)
  585. (define (parse-extension-range-element exts)
  586. (assert-next-category 'NUM-INTEGER)
  587. (let ((from current-value))
  588. (get-token)
  589. (case current-category
  590. ((COMMA)
  591. (parse-extension-range-element
  592. (cons (protoc:make-extension-range-definition from from)
  593. exts)))
  594. ((SEMICOLON)
  595. (reverse
  596. (cons (protoc:make-extension-range-definition from from)
  597. exts)))
  598. ((TO)
  599. (get-token)
  600. (let* ((to (case current-category
  601. ((NUM-INTEGER) current-value)
  602. ((MAX) 536870911)
  603. (else (unexpected-token-error))))
  604. (ext (protoc:make-extension-range-definition from to)))
  605. (get-token)
  606. (case current-category
  607. ((COMMA) (parse-extension-range-element (cons ext exts)))
  608. ((SEMICOLON) (reverse (cons ext exts)))
  609. (else (unexpected-token-error)))))
  610. (else (unexpected-token-error)))))
  611. (parse-extension-range-element (list)))
  612. (get-token)
  613. (case current-category
  614. ((ENUM)
  615. (protoc:set-message-definition-definitions!
  616. message-def
  617. (cons (parse-enum message-def)
  618. (protoc:message-definition-definitions message-def)))
  619. (parse-message-element message-def))
  620. ((EXTEND)
  621. (protoc:set-message-definition-definitions!
  622. message-def
  623. (cons (parse-extension message-def)
  624. (protoc:message-definition-definitions message-def)))
  625. (parse-message-element message-def))
  626. ((EXTENSIONS)
  627. (protoc:set-message-definition-extension-ranges!
  628. message-def (parse-extension-ranges))
  629. (parse-message-element message-def))
  630. ((MESSAGE)
  631. (protoc:set-message-definition-definitions!
  632. message-def
  633. (cons (parse-message message-def)
  634. (protoc:message-definition-definitions message-def)))
  635. (parse-message-element message-def))
  636. ((OPTIONAL)
  637. (protoc:set-message-definition-fields!
  638. message-def (cons (parse-field message-def 'optional)
  639. (protoc:message-definition-fields message-def)))
  640. (parse-message-element message-def))
  641. ((RBRACE) message-def)
  642. ((REPEATED)
  643. (protoc:set-message-definition-fields!
  644. message-def (cons (parse-field message-def 'repeated)
  645. (protoc:message-definition-fields message-def)))
  646. (parse-message-element message-def))
  647. ((REQUIRED)
  648. (protoc:set-message-definition-fields!
  649. message-def (cons (parse-field message-def 'required)
  650. (protoc:message-definition-fields message-def)))
  651. (parse-message-element message-def))
  652. (else (unexpected-token-error))))
  653. (assert-next-category 'IDENTIFIER)
  654. (let ((name current-value))
  655. (assert-next-category 'LBRACE)
  656. (let ((md (protoc:make-message-definition name current-package parent)))
  657. (parse-message-element md))))
  658. (define (parse-extension parent)
  659. (define (parse-extension-element extension-def)
  660. (get-token)
  661. (case current-category
  662. ((OPTIONAL)
  663. (protoc:set-extension-definition-fields!
  664. extension-def (cons (parse-field extension-def 'optional)
  665. (protoc:extension-definition-fields
  666. extension-def)))
  667. (parse-extension-element extension-def))
  668. ((REPEATED)
  669. (protoc:set-extension-definition-fields!
  670. extension-def (cons (parse-field extension-def 'repeated)
  671. (protoc:extension-definition-fields
  672. extension-def)))
  673. (parse-extension-element extension-def))
  674. ((RBRACE) extension-def)
  675. ((REQUIRED)
  676. (protoc:set-extension-definition-fields!
  677. extension-def (cons (parse-field extension-def 'required)
  678. (protoc:extension-definition-fields
  679. extension-def)))
  680. (parse-extension-element extension-def))
  681. (else (unexpected-token-error))))
  682. (let* ((type (parse-type))
  683. (extension-def (protoc:make-extension-definition
  684. type parent current-package)))
  685. (set! unresolved-type-references (cons type unresolved-type-references))
  686. (set! unresolved-extensions (cons extension-def unresolved-extensions))
  687. (protoc:set-type-reference-location! type extension-def)
  688. (assert-next-category 'LBRACE)
  689. (parse-extension-element extension-def)))
  690. (define (parse-proto)
  691. (define (parse-proto-elements)
  692. (get-token)
  693. (case current-category
  694. ((ENUM)
  695. (let ((enum (parse-enum #f)))
  696. (protoc:set-package-definitions!
  697. current-package (cons enum (protoc:package-definitions
  698. current-package))))
  699. (parse-proto-elements))
  700. ((EXTEND)
  701. (let ((extension (parse-extension #f)))
  702. (protoc:set-package-definitions!
  703. current-package (cons extension (protoc:package-definitions
  704. current-package))))
  705. (parse-proto-elements))
  706. ((IMPORT) (parse-import) (parse-proto-elements))
  707. ((MESSAGE)
  708. (let ((message (parse-message #f)))
  709. (protoc:set-package-definitions!
  710. current-package (cons message (protoc:package-definitions
  711. current-package))))
  712. (parse-proto-elements))
  713. ((PACKAGE) (parse-package) (parse-proto-elements))
  714. ((*eoi*) proto)
  715. (else (unexpected-token-error))))
  716. (parse-proto-elements)
  717. (for-each resolve-type unresolved-type-references)
  718. (for-each resolve-extension unresolved-extensions)
  719. proto)
  720. (lambda () (parse-proto)))
  721. )