checks.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. /**
  2. * @fileoverview Proto internal runtime checks.
  3. *
  4. * Checks are grouped into different severity, see:
  5. * http://g3doc/third_party/protobuf/javascript/README.md#configurable-check-support-in-protocol-buffers
  6. *
  7. * Checks are also grouped into different sections:
  8. * - CHECK_BOUNDS:
  9. * Checks that ensure that indexed access is within bounds
  10. * (e.g. an array being accessed past its size).
  11. * - CHECK_STATE
  12. * Checks related to the state of an object
  13. * (e.g. a parser hitting an invalid case).
  14. * - CHECK_TYPE:
  15. * Checks that relate to type errors (e.g. code receives a number instead
  16. * of a string).
  17. */
  18. goog.module('protobuf.internal.checks');
  19. const ByteString = goog.require('protobuf.ByteString');
  20. const Int64 = goog.require('protobuf.Int64');
  21. const WireType = goog.require('protobuf.binary.WireType');
  22. //
  23. // See
  24. // http://g3doc/third_party/protobuf/javascript/README.md#configurable-check-support-in-protocol-buffers
  25. //
  26. /** @define{string} */
  27. const CHECK_LEVEL_DEFINE = goog.define('protobuf.defines.CHECK_LEVEL', '');
  28. /** @define{boolean} */
  29. const POLYFILL_TEXT_ENCODING =
  30. goog.define('protobuf.defines.POLYFILL_TEXT_ENCODING', true);
  31. /**
  32. * @const {number}
  33. */
  34. const MAX_FIELD_NUMBER = Math.pow(2, 29) - 1;
  35. /**
  36. * The largest finite float32 value.
  37. * @const {number}
  38. */
  39. const FLOAT32_MAX = 3.4028234663852886e+38;
  40. /** @enum {number} */
  41. const CheckLevel = {
  42. DEBUG: 0,
  43. CRITICAL: 1,
  44. OFF: 2
  45. };
  46. /** @return {!CheckLevel} */
  47. function calculateCheckLevel() {
  48. const definedLevel = CHECK_LEVEL_DEFINE.toUpperCase();
  49. if (definedLevel === '') {
  50. // user did not set a value, value now just depends on goog.DEBUG
  51. return goog.DEBUG ? CheckLevel.DEBUG : CheckLevel.CRITICAL;
  52. }
  53. if (definedLevel === 'CRITICAL') {
  54. return CheckLevel.CRITICAL;
  55. }
  56. if (definedLevel === 'OFF') {
  57. return CheckLevel.OFF;
  58. }
  59. if (definedLevel === 'DEBUG') {
  60. return CheckLevel.DEBUG;
  61. }
  62. throw new Error(`Unknown value for CHECK_LEVEL: ${CHECK_LEVEL_DEFINE}`);
  63. }
  64. const /** !CheckLevel */ CHECK_LEVEL = calculateCheckLevel();
  65. const /** boolean */ CHECK_STATE = CHECK_LEVEL === CheckLevel.DEBUG;
  66. const /** boolean */ CHECK_CRITICAL_STATE =
  67. CHECK_LEVEL === CheckLevel.CRITICAL || CHECK_LEVEL === CheckLevel.DEBUG;
  68. const /** boolean */ CHECK_BOUNDS = CHECK_LEVEL === CheckLevel.DEBUG;
  69. const /** boolean */ CHECK_CRITICAL_BOUNDS =
  70. CHECK_LEVEL === CheckLevel.CRITICAL || CHECK_LEVEL === CheckLevel.DEBUG;
  71. const /** boolean */ CHECK_TYPE = CHECK_LEVEL === CheckLevel.DEBUG;
  72. const /** boolean */ CHECK_CRITICAL_TYPE =
  73. CHECK_LEVEL === CheckLevel.CRITICAL || CHECK_LEVEL === CheckLevel.DEBUG;
  74. /**
  75. * Ensures the truth of an expression involving the state of the calling
  76. * instance, but not involving any parameters to the calling method.
  77. *
  78. * For cases where failing fast is pretty important and not failing early could
  79. * cause bugs that are much harder to debug.
  80. * @param {boolean} state
  81. * @param {string=} message
  82. * @throws {!Error} If the state is false and the check state is critical.
  83. */
  84. function checkCriticalState(state, message = '') {
  85. if (!CHECK_CRITICAL_STATE) {
  86. return;
  87. }
  88. if (!state) {
  89. throw new Error(message);
  90. }
  91. }
  92. /**
  93. * Ensures the truth of an expression involving the state of the calling
  94. * instance, but not involving any parameters to the calling method.
  95. *
  96. * @param {boolean} state
  97. * @param {string=} message
  98. * @throws {!Error} If the state is false and the check state is debug.
  99. */
  100. function checkState(state, message = '') {
  101. if (!CHECK_STATE) {
  102. return;
  103. }
  104. checkCriticalState(state, message);
  105. }
  106. /**
  107. * Ensures that `index` specifies a valid position in an indexable object of
  108. * size `size`. A position index may range from zero to size, inclusive.
  109. * @param {number} index
  110. * @param {number} size
  111. * @throws {!Error} If the index is out of range and the check state is debug.
  112. */
  113. function checkPositionIndex(index, size) {
  114. if (!CHECK_BOUNDS) {
  115. return;
  116. }
  117. checkCriticalPositionIndex(index, size);
  118. }
  119. /**
  120. * Ensures that `index` specifies a valid position in an indexable object of
  121. * size `size`. A position index may range from zero to size, inclusive.
  122. * @param {number} index
  123. * @param {number} size
  124. * @throws {!Error} If the index is out of range and the check state is
  125. * critical.
  126. */
  127. function checkCriticalPositionIndex(index, size) {
  128. if (!CHECK_CRITICAL_BOUNDS) {
  129. return;
  130. }
  131. if (index < 0 || index > size) {
  132. throw new Error(`Index out of bounds: index: ${index} size: ${size}`);
  133. }
  134. }
  135. /**
  136. * Ensures that `index` specifies a valid element in an indexable object of
  137. * size `size`. A element index may range from zero to size, exclusive.
  138. * @param {number} index
  139. * @param {number} size
  140. * @throws {!Error} If the index is out of range and the check state is
  141. * debug.
  142. */
  143. function checkElementIndex(index, size) {
  144. if (!CHECK_BOUNDS) {
  145. return;
  146. }
  147. checkCriticalElementIndex(index, size);
  148. }
  149. /**
  150. * Ensures that `index` specifies a valid element in an indexable object of
  151. * size `size`. A element index may range from zero to size, exclusive.
  152. * @param {number} index
  153. * @param {number} size
  154. * @throws {!Error} If the index is out of range and the check state is
  155. * critical.
  156. */
  157. function checkCriticalElementIndex(index, size) {
  158. if (!CHECK_CRITICAL_BOUNDS) {
  159. return;
  160. }
  161. if (index < 0 || index >= size) {
  162. throw new Error(`Index out of bounds: index: ${index} size: ${size}`);
  163. }
  164. }
  165. /**
  166. * Ensures the range of [start, end) is with the range of [0, size).
  167. * @param {number} start
  168. * @param {number} end
  169. * @param {number} size
  170. * @throws {!Error} If start and end are out of range and the check state is
  171. * debug.
  172. */
  173. function checkRange(start, end, size) {
  174. if (!CHECK_BOUNDS) {
  175. return;
  176. }
  177. checkCriticalRange(start, end, size);
  178. }
  179. /**
  180. * Ensures the range of [start, end) is with the range of [0, size).
  181. * @param {number} start
  182. * @param {number} end
  183. * @param {number} size
  184. * @throws {!Error} If start and end are out of range and the check state is
  185. * critical.
  186. */
  187. function checkCriticalRange(start, end, size) {
  188. if (!CHECK_CRITICAL_BOUNDS) {
  189. return;
  190. }
  191. if (start < 0 || end < 0 || start > size || end > size) {
  192. throw new Error(`Range error: start: ${start} end: ${end} size: ${size}`);
  193. }
  194. if (start > end) {
  195. throw new Error(`Start > end: ${start} > ${end}`);
  196. }
  197. }
  198. /**
  199. * Ensures that field number is an integer and within the range of
  200. * [1, MAX_FIELD_NUMBER].
  201. * @param {number} fieldNumber
  202. * @throws {!Error} If the field number is out of range and the check state is
  203. * debug.
  204. */
  205. function checkFieldNumber(fieldNumber) {
  206. if (!CHECK_TYPE) {
  207. return;
  208. }
  209. checkCriticalFieldNumber(fieldNumber);
  210. }
  211. /**
  212. * Ensures that the value is neither null nor undefined.
  213. *
  214. * @param {T} value
  215. * @return {R}
  216. *
  217. * @template T
  218. * @template R :=
  219. * mapunion(T, (V) =>
  220. * cond(eq(V, 'null'),
  221. * none(),
  222. * cond(eq(V, 'undefined'),
  223. * none(),
  224. * V)))
  225. * =:
  226. */
  227. function checkDefAndNotNull(value) {
  228. if (CHECK_TYPE) {
  229. // Note that undefined == null.
  230. if (value == null) {
  231. throw new Error(`Value can't be null`);
  232. }
  233. }
  234. return value;
  235. }
  236. /**
  237. * Ensures that the value exists and is a function.
  238. *
  239. * @param {function(?): ?} func
  240. */
  241. function checkFunctionExists(func) {
  242. if (CHECK_TYPE) {
  243. if (typeof func !== 'function') {
  244. throw new Error(`${func} is not a function`);
  245. }
  246. }
  247. }
  248. /**
  249. * Ensures that field number is an integer and within the range of
  250. * [1, MAX_FIELD_NUMBER].
  251. * @param {number} fieldNumber
  252. * @throws {!Error} If the field number is out of range and the check state is
  253. * critical.
  254. */
  255. function checkCriticalFieldNumber(fieldNumber) {
  256. if (!CHECK_CRITICAL_TYPE) {
  257. return;
  258. }
  259. if (fieldNumber <= 0 || fieldNumber > MAX_FIELD_NUMBER) {
  260. throw new Error(`Field number is out of range: ${fieldNumber}`);
  261. }
  262. }
  263. /**
  264. * Ensures that wire type is valid.
  265. * @param {!WireType} wireType
  266. * @throws {!Error} If the wire type is invalid and the check state is debug.
  267. */
  268. function checkWireType(wireType) {
  269. if (!CHECK_TYPE) {
  270. return;
  271. }
  272. checkCriticalWireType(wireType);
  273. }
  274. /**
  275. * Ensures that wire type is valid.
  276. * @param {!WireType} wireType
  277. * @throws {!Error} If the wire type is invalid and the check state is critical.
  278. */
  279. function checkCriticalWireType(wireType) {
  280. if (!CHECK_CRITICAL_TYPE) {
  281. return;
  282. }
  283. if (wireType < WireType.VARINT || wireType > WireType.FIXED32) {
  284. throw new Error(`Invalid wire type: ${wireType}`);
  285. }
  286. }
  287. /**
  288. * Ensures the given value has the correct type.
  289. * @param {boolean} expression
  290. * @param {string} errorMsg
  291. * @throws {!Error} If the value has the wrong type and the check state is
  292. * critical.
  293. */
  294. function checkCriticalType(expression, errorMsg) {
  295. if (!CHECK_CRITICAL_TYPE) {
  296. return;
  297. }
  298. if (!expression) {
  299. throw new Error(errorMsg);
  300. }
  301. }
  302. /**
  303. * Checks whether a given object is an array.
  304. * @param {*} value
  305. * @return {!Array<*>}
  306. */
  307. function checkCriticalTypeArray(value) {
  308. checkCriticalType(
  309. Array.isArray(value), `Must be an array, but got: ${value}`);
  310. return /** @type {!Array<*>} */ (value);
  311. }
  312. /**
  313. * Checks whether a given object is an iterable.
  314. * @param {*} value
  315. * @return {!Iterable<*>}
  316. */
  317. function checkCriticalTypeIterable(value) {
  318. checkCriticalType(
  319. !!value[Symbol.iterator], `Must be an iterable, but got: ${value}`);
  320. return /** @type {!Iterable<*>} */ (value);
  321. }
  322. /**
  323. * Checks whether a given object is a boolean.
  324. * @param {*} value
  325. */
  326. function checkCriticalTypeBool(value) {
  327. checkCriticalType(
  328. typeof value === 'boolean', `Must be a boolean, but got: ${value}`);
  329. }
  330. /**
  331. * Checks whether a given object is an array of boolean.
  332. * @param {*} values
  333. */
  334. function checkCriticalTypeBoolArray(values) {
  335. // TODO(b/134765672)
  336. if (!CHECK_CRITICAL_TYPE) {
  337. return;
  338. }
  339. const array = checkCriticalTypeArray(values);
  340. for (const value of array) {
  341. checkCriticalTypeBool(value);
  342. }
  343. }
  344. /**
  345. * Checks whether a given object is a ByteString.
  346. * @param {*} value
  347. */
  348. function checkCriticalTypeByteString(value) {
  349. checkCriticalType(
  350. value instanceof ByteString, `Must be a ByteString, but got: ${value}`);
  351. }
  352. /**
  353. * Checks whether a given object is an array of ByteString.
  354. * @param {*} values
  355. */
  356. function checkCriticalTypeByteStringArray(values) {
  357. // TODO(b/134765672)
  358. if (!CHECK_CRITICAL_TYPE) {
  359. return;
  360. }
  361. const array = checkCriticalTypeArray(values);
  362. for (const value of array) {
  363. checkCriticalTypeByteString(value);
  364. }
  365. }
  366. /**
  367. * Checks whether a given object is a number.
  368. * @param {*} value
  369. * @throws {!Error} If the value is not float and the check state is debug.
  370. */
  371. function checkTypeDouble(value) {
  372. if (!CHECK_TYPE) {
  373. return;
  374. }
  375. checkCriticalTypeDouble(value);
  376. }
  377. /**
  378. * Checks whether a given object is a number.
  379. * @param {*} value
  380. * @throws {!Error} If the value is not float and the check state is critical.
  381. */
  382. function checkCriticalTypeDouble(value) {
  383. checkCriticalType(
  384. typeof value === 'number', `Must be a number, but got: ${value}`);
  385. }
  386. /**
  387. * Checks whether a given object is an array of double.
  388. * @param {*} values
  389. */
  390. function checkCriticalTypeDoubleArray(values) {
  391. // TODO(b/134765672)
  392. if (!CHECK_CRITICAL_TYPE) {
  393. return;
  394. }
  395. const array = checkCriticalTypeArray(values);
  396. for (const value of array) {
  397. checkCriticalTypeDouble(value);
  398. }
  399. }
  400. /**
  401. * Checks whether a given object is a number.
  402. * @param {*} value
  403. * @throws {!Error} If the value is not signed int32 and the check state is
  404. * debug.
  405. */
  406. function checkTypeSignedInt32(value) {
  407. if (!CHECK_TYPE) {
  408. return;
  409. }
  410. checkCriticalTypeSignedInt32(value);
  411. }
  412. /**
  413. * Checks whether a given object is a number.
  414. * @param {*} value
  415. * @throws {!Error} If the value is not signed int32 and the check state is
  416. * critical.
  417. */
  418. function checkCriticalTypeSignedInt32(value) {
  419. checkCriticalTypeDouble(value);
  420. const valueAsNumber = /** @type {number} */ (value);
  421. if (CHECK_CRITICAL_TYPE) {
  422. if (valueAsNumber < -Math.pow(2, 31) || valueAsNumber > Math.pow(2, 31) ||
  423. !Number.isInteger(valueAsNumber)) {
  424. throw new Error(`Must be int32, but got: ${valueAsNumber}`);
  425. }
  426. }
  427. }
  428. /**
  429. * Checks whether a given object is an array of numbers.
  430. * @param {*} values
  431. */
  432. function checkCriticalTypeSignedInt32Array(values) {
  433. // TODO(b/134765672)
  434. if (!CHECK_CRITICAL_TYPE) {
  435. return;
  436. }
  437. const array = checkCriticalTypeArray(values);
  438. for (const value of array) {
  439. checkCriticalTypeSignedInt32(value);
  440. }
  441. }
  442. /**
  443. * Ensures that value is a long instance.
  444. * @param {*} value
  445. * @throws {!Error} If the value is not a long instance and check state is
  446. * debug.
  447. */
  448. function checkTypeSignedInt64(value) {
  449. if (!CHECK_TYPE) {
  450. return;
  451. }
  452. checkCriticalTypeSignedInt64(value);
  453. }
  454. /**
  455. * Ensures that value is a long instance.
  456. * @param {*} value
  457. * @throws {!Error} If the value is not a long instance and check state is
  458. * critical.
  459. */
  460. function checkCriticalTypeSignedInt64(value) {
  461. if (!CHECK_CRITICAL_TYPE) {
  462. return;
  463. }
  464. if (!(value instanceof Int64)) {
  465. throw new Error(`Must be Int64 instance, but got: ${value}`);
  466. }
  467. }
  468. /**
  469. * Checks whether a given object is an array of long instances.
  470. * @param {*} values
  471. * @throws {!Error} If values is not an array of long instances.
  472. */
  473. function checkCriticalTypeSignedInt64Array(values) {
  474. // TODO(b/134765672)
  475. if (!CHECK_CRITICAL_TYPE) {
  476. return;
  477. }
  478. const array = checkCriticalTypeArray(values);
  479. for (const value of array) {
  480. checkCriticalTypeSignedInt64(value);
  481. }
  482. }
  483. /**
  484. * Checks whether a given object is a number and within float32 precision.
  485. * @param {*} value
  486. * @throws {!Error} If the value is not float and the check state is debug.
  487. */
  488. function checkTypeFloat(value) {
  489. if (!CHECK_TYPE) {
  490. return;
  491. }
  492. checkCriticalTypeFloat(value);
  493. }
  494. /**
  495. * Checks whether a given object is a number and within float32 precision.
  496. * @param {*} value
  497. * @throws {!Error} If the value is not float and the check state is critical.
  498. */
  499. function checkCriticalTypeFloat(value) {
  500. checkCriticalTypeDouble(value);
  501. if (CHECK_CRITICAL_TYPE) {
  502. const valueAsNumber = /** @type {number} */ (value);
  503. if (Number.isFinite(valueAsNumber) &&
  504. (valueAsNumber > FLOAT32_MAX || valueAsNumber < -FLOAT32_MAX)) {
  505. throw new Error(
  506. `Given number does not fit into float precision: ${value}`);
  507. }
  508. }
  509. }
  510. /**
  511. * Checks whether a given object is an iterable of floats.
  512. * @param {*} values
  513. */
  514. function checkCriticalTypeFloatIterable(values) {
  515. // TODO(b/134765672)
  516. if (!CHECK_CRITICAL_TYPE) {
  517. return;
  518. }
  519. const iterable = checkCriticalTypeIterable(values);
  520. for (const value of iterable) {
  521. checkCriticalTypeFloat(value);
  522. }
  523. }
  524. /**
  525. * Checks whether a given object is a string.
  526. * @param {*} value
  527. */
  528. function checkCriticalTypeString(value) {
  529. checkCriticalType(
  530. typeof value === 'string', `Must be string, but got: ${value}`);
  531. }
  532. /**
  533. * Checks whether a given object is an array of string.
  534. * @param {*} values
  535. */
  536. function checkCriticalTypeStringArray(values) {
  537. // TODO(b/134765672)
  538. if (!CHECK_CRITICAL_TYPE) {
  539. return;
  540. }
  541. const array = checkCriticalTypeArray(values);
  542. for (const value of array) {
  543. checkCriticalTypeString(value);
  544. }
  545. }
  546. /**
  547. * Ensures that value is a valid unsigned int32.
  548. * @param {*} value
  549. * @throws {!Error} If the value is out of range and the check state is debug.
  550. */
  551. function checkTypeUnsignedInt32(value) {
  552. if (!CHECK_TYPE) {
  553. return;
  554. }
  555. checkCriticalTypeUnsignedInt32(value);
  556. }
  557. /**
  558. * Ensures that value is a valid unsigned int32.
  559. * @param {*} value
  560. * @throws {!Error} If the value is out of range and the check state
  561. * is critical.
  562. */
  563. function checkCriticalTypeUnsignedInt32(value) {
  564. if (!CHECK_CRITICAL_TYPE) {
  565. return;
  566. }
  567. checkCriticalTypeDouble(value);
  568. const valueAsNumber = /** @type {number} */ (value);
  569. if (valueAsNumber < 0 || valueAsNumber > Math.pow(2, 32) - 1 ||
  570. !Number.isInteger(valueAsNumber)) {
  571. throw new Error(`Must be uint32, but got: ${value}`);
  572. }
  573. }
  574. /**
  575. * Checks whether a given object is an array of unsigned int32.
  576. * @param {*} values
  577. */
  578. function checkCriticalTypeUnsignedInt32Array(values) {
  579. // TODO(b/134765672)
  580. if (!CHECK_CRITICAL_TYPE) {
  581. return;
  582. }
  583. const array = checkCriticalTypeArray(values);
  584. for (const value of array) {
  585. checkCriticalTypeUnsignedInt32(value);
  586. }
  587. }
  588. /**
  589. * Checks whether a given object is an array of message.
  590. * @param {*} values
  591. */
  592. function checkCriticalTypeMessageArray(values) {
  593. // TODO(b/134765672)
  594. if (!CHECK_CRITICAL_TYPE) {
  595. return;
  596. }
  597. const array = checkCriticalTypeArray(values);
  598. for (const value of array) {
  599. checkCriticalType(
  600. value !== null, 'Given value is not a message instance: null');
  601. }
  602. }
  603. exports = {
  604. checkDefAndNotNull,
  605. checkCriticalElementIndex,
  606. checkCriticalFieldNumber,
  607. checkCriticalPositionIndex,
  608. checkCriticalRange,
  609. checkCriticalState,
  610. checkCriticalTypeBool,
  611. checkCriticalTypeBoolArray,
  612. checkCriticalTypeByteString,
  613. checkCriticalTypeByteStringArray,
  614. checkCriticalTypeDouble,
  615. checkTypeDouble,
  616. checkCriticalTypeDoubleArray,
  617. checkTypeFloat,
  618. checkCriticalTypeFloat,
  619. checkCriticalTypeFloatIterable,
  620. checkCriticalTypeMessageArray,
  621. checkCriticalTypeSignedInt32,
  622. checkCriticalTypeSignedInt32Array,
  623. checkCriticalTypeSignedInt64,
  624. checkTypeSignedInt64,
  625. checkCriticalTypeSignedInt64Array,
  626. checkCriticalTypeString,
  627. checkCriticalTypeStringArray,
  628. checkCriticalTypeUnsignedInt32,
  629. checkCriticalTypeUnsignedInt32Array,
  630. checkCriticalType,
  631. checkCriticalWireType,
  632. checkElementIndex,
  633. checkFieldNumber,
  634. checkFunctionExists,
  635. checkPositionIndex,
  636. checkRange,
  637. checkState,
  638. checkTypeUnsignedInt32,
  639. checkTypeSignedInt32,
  640. checkWireType,
  641. CHECK_BOUNDS,
  642. CHECK_CRITICAL_BOUNDS,
  643. CHECK_STATE,
  644. CHECK_CRITICAL_STATE,
  645. CHECK_TYPE,
  646. CHECK_CRITICAL_TYPE,
  647. MAX_FIELD_NUMBER,
  648. POLYFILL_TEXT_ENCODING,
  649. };