PageRenderTime 28ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/protobuf/private.scm

http://r6rs-protobuf.googlecode.com/
Scheme | 634 lines | 524 code | 96 blank | 14 comment | 2 complexity | b86ec809cfcd44f4637481d46fc70a2f MD5 | raw file
Possible License(s): GPL-3.0
  1. ;; private.scm: private definitions and support API 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 private)
  15. (export protobuf:make-field-type-descriptor
  16. protobuf:field-type-descriptor-default
  17. protobuf:field-type-descriptor-name
  18. protobuf:field-type-descriptor-predicate
  19. protobuf:field-type-descriptor-wire-type
  20. protobuf:make-message-field-type-descriptor
  21. protobuf:message-field-type-descriptor?
  22. protobuf:message-field-type-descriptor-definition
  23. protobuf:make-enum-field-type-descriptor
  24. protobuf:enum-field-type-descriptor?
  25. protobuf:enum-field-type-descriptor-definition
  26. protobuf:field-type-double
  27. protobuf:field-type-float
  28. protobuf:field-type-int32
  29. protobuf:field-type-int64
  30. protobuf:field-type-uint32
  31. protobuf:field-type-uint64
  32. protobuf:field-type-sint32
  33. protobuf:field-type-sint64
  34. protobuf:field-type-fixed32
  35. protobuf:field-type-fixed64
  36. protobuf:field-type-sfixed32
  37. protobuf:field-type-sfixed64
  38. protobuf:field-type-bool
  39. protobuf:field-type-string
  40. protobuf:field-type-bytes
  41. protobuf:field-type-message
  42. protobuf:make-field-descriptor
  43. protobuf:field-descriptor-default
  44. protobuf:field-descriptor-name
  45. protobuf:make-extension-field-descriptor
  46. protobuf:make-field
  47. protobuf:field-field-descriptor
  48. protobuf:field-value
  49. protobuf:field-has-value?
  50. protobuf:set-field-value!
  51. protobuf:clear-field!
  52. protobuf:register-extension
  53. protobuf:message-builder-build
  54. protobuf:message-builder-field
  55. protobuf:clear-message-builder-extension!
  56. protobuf:message-builder-extension
  57. protobuf:message-builder-has-extension?
  58. protobuf:set-message-builder-extension!
  59. protobuf:make-message
  60. protobuf:message-extension
  61. protobuf:message-field
  62. protobuf:message-has-extension?
  63. protobuf:message-write
  64. protobuf:message-read
  65. protobuf:read-varint
  66. protobuf:write-varint
  67. protobuf:write-double
  68. protobuf:write-float
  69. protobuf:write-int32
  70. protobuf:write-int64
  71. protobuf:write-uint32
  72. protobuf:write-uint64
  73. protobuf:write-sint32
  74. protobuf:write-sint64
  75. protobuf:write-fixed32
  76. protobuf:write-fixed64
  77. protobuf:write-sfixed32
  78. protobuf:write-sfixed64
  79. protobuf:write-bool
  80. protobuf:write-string
  81. protobuf:write-bytes
  82. protobuf:write-message)
  83. (import (rnrs))
  84. (define (zigzag-encode n bits)
  85. (bitwise-xor (bitwise-arithmetic-shift-left n 1)
  86. (bitwise-arithmetic-shift-right n (- bits 1))))
  87. (define (zigzag-decode n bits)
  88. (- (bitwise-arithmetic-shift-right n 1)
  89. (* (bitwise-and n 1) n)))
  90. (define (protobuf:write-varint port varint)
  91. (let ((b (bitwise-bit-field varint 0 7)))
  92. (if (> varint 127)
  93. (begin (put-u8
  94. port (bitwise-ior (bitwise-arithmetic-shift-left 1 7) b))
  95. (protobuf:write-varint
  96. port (bitwise-arithmetic-shift-right varint 7)))
  97. (put-u8 port b))))
  98. (define (read-varint port)
  99. (define (read-varint-inner port tally septets)
  100. (let* ((b (get-u8 port))
  101. (tally (bitwise-ior (bitwise-arithmetic-shift-left
  102. (bitwise-bit-field b 0 7) (* septets 7))
  103. tally)))
  104. (if (bitwise-bit-set? b 7)
  105. (read-varint-inner port tally (+ septets 1))
  106. tally)))
  107. (read-varint-inner port 0 0))
  108. (define protobuf:read-varint read-varint)
  109. (define (protobuf:write-double port double)
  110. (let ((vec (make-bytevector 8)))
  111. (bytevector-ieee-double-set! vec 0 double (endianness little))
  112. (put-bytevector port vec)))
  113. (define (protobuf:write-float port float)
  114. (let ((vec (make-bytevector 4)))
  115. (bytevector-ieee-single-set! vec 0 float (endianness little))
  116. (put-bytevector port vec)))
  117. (define (protobuf:write-int32 port int32) (protobuf:write-varint port int32))
  118. (define (protobuf:write-int64 port int64) (protobuf:write-varint port int64))
  119. (define (protobuf:write-uint32 port uint32)
  120. (protobuf:write-varint port uint32))
  121. (define (protobuf:write-uint64 port uint64)
  122. (protobuf:write-varint port uint64))
  123. (define (protobuf:write-sint32 port sint32)
  124. (protobuf:write-varint port (zigzag-encode sint32 32)))
  125. (define (protobuf:write-sint64 port sint64)
  126. (protobuf:write-varint port (zigzag-encode sint64 64)))
  127. (define (protobuf:write-fixed32 port fixed32)
  128. (let ((vec (make-bytevector 4)))
  129. (bytevector-u32-set! vec 0 fixed32 (endianness little))
  130. (put-bytevector port vec)))
  131. (define (protobuf:write-fixed64 port fixed64)
  132. (let ((vec (make-bytevector 8)))
  133. (bytevector-u64-set! vec 0 fixed64 (endianness little))
  134. (put-bytevector port vec)))
  135. (define (protobuf:write-sfixed32 port sfixed32)
  136. (let ((vec (make-bytevector 4)))
  137. (bytevector-s32-set! vec 0 sfixed32 (endianness little))
  138. (put-bytevector port vec)))
  139. (define (protobuf:write-sfixed64 port sfixed64)
  140. (let ((vec (make-bytevector 8)))
  141. (bytevector-s64-set! vec 0 sfixed64 (endianness little))
  142. (put-bytevector port vec)))
  143. (define (protobuf:write-bool port bool) (put-u8 port (if bool 1 0)))
  144. (define (protobuf:write-string port string)
  145. (protobuf:write-varint port (string-length string))
  146. (put-bytevector port (string->utf8 string)))
  147. (define (protobuf:write-bytes port bytes)
  148. (protobuf:write-varint port (bytevector-length bytes))
  149. (put-bytevector port bytes))
  150. (define (protobuf:write-message port message)
  151. (protobuf:message-write message port))
  152. (define (read-double port)
  153. (bytevector-ieee-double-ref
  154. (get-bytevector-n port 8) 0 (endianness little)))
  155. (define (read-float port)
  156. (bytevector-ieee-single-ref
  157. (get-bytevector-n port 4) 0 (endianness little)))
  158. (define (read-int32 port) (read-varint port))
  159. (define (read-int64 port) (read-varint port))
  160. (define (read-uint32 port) (read-varint port))
  161. (define (read-uint64 port) (read-varint port))
  162. (define (read-sint32 port) (zigzag-decode (read-varint port) 32))
  163. (define (read-sint64 port) (zigzag-decode (read-varint port) 64))
  164. (define (read-fixed32 port)
  165. (bytevector-u32-ref (get-bytevector-n port 4) 0 (endianness little)))
  166. (define (read-fixed64 port)
  167. (bytevector-u64-ref (get-bytevector-n port 8) 0 (endianness little)))
  168. (define (read-sfixed32 port)
  169. (bytevector-s32-ref (get-bytevector-n port 4) 0 (endianness little)))
  170. (define (read-sfixed64 port)
  171. (bytevector-s64-ref (get-bytevector-n port 8) 0 (endianness little)))
  172. (define (read-bool port)
  173. (case (get-u8 port)
  174. ((0) #f) ((1) #t) (else (raise (make-assertion-violation)))))
  175. (define (read-string port)
  176. (utf8->string (get-bytevector-n port (read-varint port))))
  177. (define (read-bytes port) (get-bytevector-n port (read-varint port)))
  178. (define-enumeration
  179. wire-type
  180. (varint fixed64 length-delimited start-group end-group fixed32)
  181. wire-types)
  182. (define-enumeration
  183. field-type
  184. (double float int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64
  185. sfixed32 sfixed64 bool string bytes message)
  186. field-types)
  187. (define-record-type (protobuf:field-type-descriptor
  188. protobuf:make-field-type-descriptor
  189. protobuf:field-type-descriptor?)
  190. (fields name wire-type serializer deserializer predicate default))
  191. (define-record-type (protobuf:message-field-type-descriptor
  192. protobuf:make-message-field-type-descriptor
  193. protobuf:message-field-type-descriptor?)
  194. (parent protobuf:field-type-descriptor)
  195. (fields definition))
  196. (define-record-type (protobuf:enum-field-type-descriptor
  197. protobuf:make-enum-field-type-descriptor
  198. protobuf:enum-field-type-descriptor?)
  199. (parent protobuf:field-type-descriptor)
  200. (fields definition))
  201. (define-record-type (protobuf:field-descriptor
  202. protobuf:make-field-descriptor
  203. protobuf:field-descriptor?)
  204. (fields index name type repeated? required? default))
  205. (define-record-type (protobuf:extension-field-descriptor
  206. protobuf:make-extension-field-descriptor
  207. protobuf:extension-field-descriptor?)
  208. (parent protobuf:field-descriptor)
  209. (opaque #t))
  210. (define-record-type (protobuf:field protobuf:make-field protobuf:field?)
  211. (fields
  212. (mutable value protobuf:field-value protobuf:set-field-value-internal!)
  213. (immutable descriptor protobuf:field-field-descriptor)
  214. (mutable has-value?
  215. protobuf:field-has-value?
  216. protobuf:set-field-has-value!))
  217. (protocol
  218. (lambda (p)
  219. (lambda (descriptor . value)
  220. (if (null? value)
  221. (p (protobuf:field-descriptor-default descriptor) descriptor #f)
  222. (p (car value) descriptor #t))))))
  223. (define-record-type (protobuf:message protobuf:make-message protobuf:message?)
  224. (fields fields extension-fields))
  225. (define-record-type (protobuf:message-builder
  226. protobuf:make-message-builder
  227. protobuf:message-builder?)
  228. (fields type fields extension-fields)
  229. (protocol
  230. (lambda (p)
  231. (lambda (type field-descriptors)
  232. (p type
  233. (map protobuf:make-field field-descriptors)
  234. (make-eqv-hashtable))))))
  235. (define (protobuf:message-field message index)
  236. (find (lambda (x)
  237. (eqv? (protobuf:field-descriptor-index
  238. (protobuf:field-field-descriptor x))
  239. index))
  240. (protobuf:message-fields message)))
  241. (define extension-registry (make-eq-hashtable))
  242. (define (protobuf:register-extension prototype fd)
  243. (define type (protobuf:message-builder-type prototype))
  244. (define (update exts)
  245. (hashtable-set! exts (protobuf:field-descriptor-index fd) fd) exts)
  246. (hashtable-update! extension-registry type update (make-eqv-hashtable)))
  247. (define (assert-registered-extension type fd)
  248. (or (hashtable-contains?
  249. (hashtable-ref extension-registry type (make-eqv-hashtable))
  250. (protobuf:field-descriptor-index fd))
  251. (raise (condition (make-assertion-violation)
  252. (make-message-condition "Unknown extension.")))))
  253. (define (protobuf:message-has-extension? m type fd)
  254. (assert-registered-extension type fd)
  255. (hashtable-contains? (protobuf:message-extension-fields m)
  256. (protobuf:field-descriptor-index fd)))
  257. (define (protobuf:message-extension m type fd)
  258. (assert-registered-extension type fd)
  259. (let ((field (hashtable-ref (protobuf:message-extension-fields m)
  260. (protobuf:field-descriptor-index fd)
  261. #f)))
  262. (if field
  263. (protobuf:field-value field)
  264. (protobuf:field-descriptor-default fd))))
  265. (define (protobuf:message-builder-has-extension? b fd)
  266. (assert-registered-extension (protobuf:message-builder-type b) fd)
  267. (hashtable-contains? (protobuf:message-builder-extension-fields b)
  268. (protobuf:field-descriptor-index fd)))
  269. (define (protobuf:clear-message-builder-extension! b fd)
  270. (assert-registered-extension (protobuf:message-builder-type b) fd)
  271. (hashtable-delete! (protobuf:message-builder-extension-fields b)
  272. (protobuf:field-descriptor-index fd)))
  273. (define (protobuf:set-message-builder-extension! b fd val)
  274. (assert-registered-extension (protobuf:message-builder-type b) fd)
  275. (let ((f (protobuf:make-field fd)))
  276. (protobuf:set-field-value! f val)
  277. (hashtable-set! (protobuf:message-builder-extension-fields b)
  278. (protobuf:field-descriptor-index fd)
  279. f)))
  280. (define (protobuf:message-builder-extension b fd)
  281. (assert-registered-extension (protobuf:message-builder-type b) fd)
  282. (let ((field (hashtable-ref (protobuf:message-builder-extension-fields b)
  283. (protobuf:field-descriptor-index fd)
  284. #f)))
  285. (if field
  286. (protobuf:field-value field)
  287. (protobuf:field-descriptor-default fd))))
  288. (define (protobuf:message-builder-build b)
  289. (define (clone-field field)
  290. (if (protobuf:field-has-value? field)
  291. (if (protobuf:field-descriptor-repeated?
  292. (protobuf:field-field-descriptor field))
  293. (protobuf:make-field
  294. (protobuf:field-field-descriptor field)
  295. (list->vector (protobuf:field-value field)))
  296. (protobuf:make-field (protobuf:field-field-descriptor field)
  297. (protobuf:field-value field)))
  298. (if (protobuf:field-descriptor-repeated?
  299. (protobuf:field-field-descriptor field))
  300. (protobuf:make-field
  301. (protobuf:field-field-descriptor field) (vector))
  302. (protobuf:make-field (protobuf:field-field-descriptor field)))))
  303. (define (clone-extensions extension-fields)
  304. (let ((ht (make-eqv-hashtable)))
  305. (vector-for-each
  306. (lambda (k)
  307. (hashtable-set!
  308. ht k (clone-field (hashtable-ref extension-fields k #f))))
  309. (hashtable-keys extension-fields))
  310. ht))
  311. (define (ensure-required f)
  312. (let ((fd (protobuf:field-field-descriptor f)))
  313. (if (and (protobuf:field-descriptor-required? fd)
  314. (not (protobuf:field-has-value? f)))
  315. (raise (condition
  316. (make-assertion-violation)
  317. (make-message-condition
  318. (string-append "Field "
  319. (protobuf:field-descriptor-name fd)
  320. " is required.")))))))
  321. (let* ((type (protobuf:message-builder-type b))
  322. (ctor (record-constructor
  323. (make-record-constructor-descriptor type #f #f)))
  324. (fields (protobuf:message-builder-fields b)))
  325. (for-each ensure-required fields)
  326. (let ((cfs (map clone-field fields))
  327. (ecfs (clone-extensions
  328. (protobuf:message-builder-extension-fields b))))
  329. (apply ctor (cons cfs (cons ecfs (map protobuf:field-value cfs)))))))
  330. (define (protobuf:message-builder-field builder index)
  331. (find (lambda (x)
  332. (eqv? (protobuf:field-descriptor-index
  333. (protobuf:field-field-descriptor x))
  334. index))
  335. (protobuf:message-builder-fields builder)))
  336. (define (protobuf:set-field-value! field value)
  337. (let* ((field-descriptor (protobuf:field-field-descriptor field))
  338. (type-descriptor (protobuf:field-descriptor-type field-descriptor))
  339. (predicate (protobuf:field-type-descriptor-predicate
  340. type-descriptor)))
  341. (if (protobuf:field-descriptor-repeated? field-descriptor)
  342. (begin (if (not (list? value))
  343. (raise (condition
  344. (make-assertion-violation)
  345. (make-message-condition
  346. (string-append "Repeated field "
  347. (protobuf:field-descriptor-name
  348. field-descriptor)
  349. " must be a list"))))
  350. (if (not (for-all predicate value))
  351. (raise (condition
  352. (make-assertion-violation)
  353. (make-message-condition
  354. (string-append
  355. "Wrong type in value list for field "
  356. (protobuf:field-descriptor-name
  357. field-descriptor))))))))
  358. (if (not (predicate value))
  359. (raise (condition
  360. (make-assertion-violation)
  361. (make-message-condition
  362. (string-append
  363. "Wrong type for field "
  364. (protobuf:field-descriptor-name field-descriptor)))))))
  365. (protobuf:set-field-value-internal! field value)
  366. (protobuf:set-field-has-value! field #t)))
  367. (define (protobuf:clear-field! field)
  368. (let ((field-descriptor (protobuf:field-field-descriptor field)))
  369. (if (not (protobuf:field-descriptor-repeated? field-descriptor))
  370. (protobuf:set-field-has-value! field #f))
  371. (protobuf:set-field-value-internal!
  372. field (protobuf:field-descriptor-default field-descriptor))))
  373. (define (int32? obj)
  374. (and (integer? obj) (>= obj -2147483648) (<= obj 2147483647)))
  375. (define (uint32? obj) (and (integer? obj) (>= obj 0) (<= 4294967295)))
  376. (define (int64? obj)
  377. (and (integer? obj)
  378. (>= obj -9223372036854775808)
  379. (<= obj 9223372036854775807)))
  380. (define (uint64? obj)
  381. (and (integer? obj) (>= obj 0) (<= 18446744073709551615)))
  382. (define protobuf:field-type-double
  383. (protobuf:make-field-type-descriptor
  384. (field-type double)
  385. (wire-type fixed64) protobuf:write-double read-double real? 0))
  386. (define protobuf:field-type-float
  387. (protobuf:make-field-type-descriptor
  388. (field-type float)
  389. (wire-type fixed32) protobuf:write-float read-float real? 0))
  390. (define protobuf:field-type-int32
  391. (protobuf:make-field-type-descriptor
  392. (field-type int32)
  393. (wire-type varint) protobuf:write-int32 read-int32 int32? 0))
  394. (define protobuf:field-type-int64
  395. (protobuf:make-field-type-descriptor
  396. (field-type int64)
  397. (wire-type varint) protobuf:write-int64 read-int64 int64? 0))
  398. (define protobuf:field-type-uint32
  399. (protobuf:make-field-type-descriptor
  400. (field-type uint32)
  401. (wire-type varint) protobuf:write-uint32 read-uint32 uint32? 0))
  402. (define protobuf:field-type-uint64
  403. (protobuf:make-field-type-descriptor
  404. (field-type uint64)
  405. (wire-type varint) protobuf:write-uint64 read-uint64 uint64? 0))
  406. (define protobuf:field-type-sint32
  407. (protobuf:make-field-type-descriptor
  408. (field-type sint32)
  409. (wire-type varint) protobuf:write-sint32 read-sint32 int32? 0))
  410. (define protobuf:field-type-sint64
  411. (protobuf:make-field-type-descriptor
  412. (field-type sint64)
  413. (wire-type varint) protobuf:write-sint64 read-sint64 int64? 0))
  414. (define protobuf:field-type-fixed32
  415. (protobuf:make-field-type-descriptor
  416. (field-type fixed32)
  417. (wire-type fixed32) protobuf:write-fixed32 read-fixed32 int32? 0))
  418. (define protobuf:field-type-fixed64
  419. (protobuf:make-field-type-descriptor
  420. (field-type fixed64)
  421. (wire-type fixed64) protobuf:write-fixed64 read-fixed64 int64? 0))
  422. (define protobuf:field-type-sfixed32
  423. (protobuf:make-field-type-descriptor
  424. (field-type sfixed32)
  425. (wire-type fixed32) protobuf:write-sfixed32 read-sfixed32 int32? 0))
  426. (define protobuf:field-type-sfixed64
  427. (protobuf:make-field-type-descriptor
  428. (field-type sfixed64)
  429. (wire-type fixed64) protobuf:write-sfixed64 read-sfixed64 int64? 0))
  430. (define protobuf:field-type-bool
  431. (protobuf:make-field-type-descriptor
  432. (field-type bool)
  433. (wire-type varint) protobuf:write-bool read-bool boolean? #f))
  434. (define protobuf:field-type-string
  435. (protobuf:make-field-type-descriptor
  436. (field-type string)
  437. (wire-type length-delimited) protobuf:write-string read-string string? ""))
  438. (define protobuf:field-type-bytes
  439. (protobuf:make-field-type-descriptor
  440. (field-type bytes)
  441. (wire-type length-delimited)
  442. protobuf:write-bytes read-bytes bytevector? (make-bytevector 0)))
  443. (define (protobuf:message-write obj port)
  444. (define extension-fields
  445. (let ((efs (protobuf:message-extension-fields obj)))
  446. (let-values (((keys values) (hashtable-entries efs))) values)))
  447. (define (write-field field)
  448. (define (wire-type->ordinal wire-type)
  449. (case wire-type
  450. ((varint) 0)
  451. ((fixed64) 1)
  452. ((length-delimited) 2)
  453. ((fixed32) 5)))
  454. (define field-descriptor (protobuf:field-field-descriptor field))
  455. (define type-descriptor (protobuf:field-descriptor-type field-descriptor))
  456. (define serialize (protobuf:field-type-descriptor-serializer
  457. type-descriptor))
  458. (define (write-field-inner value)
  459. (protobuf:write-varint
  460. port (bitwise-ior
  461. (bitwise-arithmetic-shift-left
  462. (protobuf:field-descriptor-index field-descriptor) 3)
  463. (wire-type->ordinal
  464. (protobuf:field-type-descriptor-wire-type
  465. type-descriptor))))
  466. (serialize port value))
  467. (if (protobuf:field-has-value? field)
  468. (if (protobuf:field-descriptor-repeated? field-descriptor)
  469. (vector-for-each write-field-inner (protobuf:field-value field))
  470. (write-field-inner (protobuf:field-value field)))))
  471. (for-each write-field (protobuf:message-fields obj))
  472. (vector-for-each write-field extension-fields))
  473. (define (protobuf:message-read builder port)
  474. (define field-table (make-eqv-hashtable))
  475. (define (lookup-field-metadata field-number)
  476. (let ((field (hashtable-ref field-table field-number #f)))
  477. (if field
  478. (values field (protobuf:field-field-descriptor field))
  479. (values #f (hashtable-ref (hashtable-ref
  480. extension-registry
  481. (protobuf:message-builder-type builder)
  482. (make-eqv-hashtable))
  483. field-number
  484. #f)))))
  485. (define (read-fields)
  486. (define (read-field)
  487. (define (ordinal->wire-type ordinal)
  488. (case ordinal
  489. ((0) (wire-type varint))
  490. ((1) (wire-type fixed64))
  491. ((2) (wire-type length-delimited))
  492. ((3) (wire-type start-group))
  493. ((4) (wire-type end-group))
  494. ((5) (wire-type fixed32))
  495. (else (raise (make-assertion-violation)))))
  496. (let* ((field-header (read-varint port))
  497. (wire-type (ordinal->wire-type (bitwise-and field-header 7)))
  498. (field-number (bitwise-arithmetic-shift-right field-header 3)))
  499. (let-values (((field field-descriptor)
  500. (lookup-field-metadata field-number)))
  501. (if field-descriptor
  502. (let ((deserializer (protobuf:field-type-descriptor-deserializer
  503. (protobuf:field-descriptor-type
  504. field-descriptor))))
  505. (if (protobuf:field-descriptor-repeated? field-descriptor)
  506. (if field
  507. (protobuf:set-field-value!
  508. field (append (protobuf:field-value field)
  509. (list (deserializer port))))
  510. (protobuf:set-message-builder-extension!
  511. builder field-descriptor
  512. (append (protobuf:message-builder-extension
  513. builder field-descriptor)
  514. (list (deserializer port)))))
  515. (if field
  516. (protobuf:set-field-value! field (deserializer port))
  517. (protobuf:set-message-builder-extension!
  518. builder field-descriptor (deserializer port)))))
  519. ;; If we don't have metadata about the field, consume its content
  520. ;; based on its wire type and then discard it.
  521. (case wire-type
  522. ((varint) (read-varint port))
  523. ((fixed64) (read-fixed64 port))
  524. ((length-delimited) (read-string port))
  525. ((start-group) (read-string port))
  526. ((end-group) #f)
  527. ((fixed32) (read-fixed32 port)))))))
  528. (if (port-eof? port)
  529. (protobuf:message-builder-build builder)
  530. (begin (read-field) (read-fields))))
  531. (for-each (lambda (field)
  532. (hashtable-set! field-table
  533. (protobuf:field-descriptor-index
  534. (protobuf:field-field-descriptor field))
  535. field))
  536. (protobuf:message-builder-fields builder))
  537. (read-fields))
  538. )