message.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. // Copyright 2008 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Protocol Buffer Message base class.
  16. * @suppress {unusedPrivateMembers} For descriptor_ declaration.
  17. */
  18. goog.provide('goog.proto2.Message');
  19. goog.require('goog.asserts');
  20. goog.require('goog.proto2.Descriptor');
  21. goog.require('goog.proto2.FieldDescriptor');
  22. goog.forwardDeclare('goog.proto2.LazyDeserializer'); // circular reference
  23. /**
  24. * Abstract base class for all Protocol Buffer 2 messages. It will be
  25. * subclassed in the code generated by the Protocol Compiler. Any other
  26. * subclasses are prohibited.
  27. * @constructor
  28. */
  29. goog.proto2.Message = function() {
  30. /**
  31. * Stores the field values in this message. Keyed by the tag of the fields.
  32. * @type {!Object}
  33. * @private
  34. */
  35. this.values_ = {};
  36. /**
  37. * Stores the field information (i.e. metadata) about this message.
  38. * @type {Object<number, !goog.proto2.FieldDescriptor>}
  39. * @private
  40. */
  41. this.fields_ = this.getDescriptor().getFieldsMap();
  42. /**
  43. * The lazy deserializer for this message instance, if any.
  44. * @type {goog.proto2.LazyDeserializer}
  45. * @private
  46. */
  47. this.lazyDeserializer_ = null;
  48. /**
  49. * A map of those fields deserialized, from tag number to their deserialized
  50. * value.
  51. * @type {Object}
  52. * @private
  53. */
  54. this.deserializedFields_ = null;
  55. };
  56. /**
  57. * An enumeration defining the possible field types.
  58. * Should be a mirror of that defined in descriptor.h.
  59. *
  60. * TODO(user): Remove this alias. The code generator generates code that
  61. * references this enum, so it needs to exist until the code generator is
  62. * changed. The enum was moved to from Message to FieldDescriptor to avoid a
  63. * dependency cycle.
  64. *
  65. * Use goog.proto2.FieldDescriptor.FieldType instead.
  66. *
  67. * @enum {number}
  68. */
  69. goog.proto2.Message.FieldType = {
  70. DOUBLE: 1,
  71. FLOAT: 2,
  72. INT64: 3,
  73. UINT64: 4,
  74. INT32: 5,
  75. FIXED64: 6,
  76. FIXED32: 7,
  77. BOOL: 8,
  78. STRING: 9,
  79. GROUP: 10,
  80. MESSAGE: 11,
  81. BYTES: 12,
  82. UINT32: 13,
  83. ENUM: 14,
  84. SFIXED32: 15,
  85. SFIXED64: 16,
  86. SINT32: 17,
  87. SINT64: 18
  88. };
  89. /**
  90. * All instances of goog.proto2.Message should have a static descriptor_
  91. * property. The Descriptor will be deserialized lazily in the getDescriptor()
  92. * method.
  93. *
  94. * This declaration is just here for documentation purposes.
  95. * goog.proto2.Message does not have its own descriptor.
  96. *
  97. * @type {undefined}
  98. * @private
  99. */
  100. goog.proto2.Message.descriptor_;
  101. /**
  102. * Initializes the message with a lazy deserializer and its associated data.
  103. * This method should be called by internal methods ONLY.
  104. *
  105. * @param {goog.proto2.LazyDeserializer} deserializer The lazy deserializer to
  106. * use to decode the data on the fly.
  107. *
  108. * @param {?} data The data to decode/deserialize.
  109. */
  110. goog.proto2.Message.prototype.initializeForLazyDeserializer = function(
  111. deserializer, data) {
  112. this.lazyDeserializer_ = deserializer;
  113. this.values_ = data;
  114. this.deserializedFields_ = {};
  115. };
  116. /**
  117. * Sets the value of an unknown field, by tag.
  118. *
  119. * @param {number} tag The tag of an unknown field (must be >= 1).
  120. * @param {*} value The value for that unknown field.
  121. */
  122. goog.proto2.Message.prototype.setUnknown = function(tag, value) {
  123. goog.asserts.assert(
  124. !this.fields_[tag], 'Field is not unknown in this message');
  125. goog.asserts.assert(
  126. tag >= 1, 'Tag ' + tag + ' has value "' + value + '" in descriptor ' +
  127. this.getDescriptor().getName());
  128. goog.asserts.assert(value !== null, 'Value cannot be null');
  129. this.values_[tag] = value;
  130. if (this.deserializedFields_) {
  131. delete this.deserializedFields_[tag];
  132. }
  133. };
  134. /**
  135. * Iterates over all the unknown fields in the message.
  136. *
  137. * @param {function(this:T, number, *)} callback A callback method
  138. * which gets invoked for each unknown field.
  139. * @param {T=} opt_scope The scope under which to execute the callback.
  140. * If not given, the current message will be used.
  141. * @template T
  142. */
  143. goog.proto2.Message.prototype.forEachUnknown = function(callback, opt_scope) {
  144. var scope = opt_scope || this;
  145. for (var key in this.values_) {
  146. var keyNum = Number(key);
  147. if (!this.fields_[keyNum]) {
  148. callback.call(scope, keyNum, this.values_[key]);
  149. }
  150. }
  151. };
  152. /**
  153. * Returns the descriptor which describes the current message.
  154. *
  155. * This only works if we assume people never subclass protobufs.
  156. *
  157. * @return {!goog.proto2.Descriptor} The descriptor.
  158. */
  159. goog.proto2.Message.prototype.getDescriptor = goog.abstractMethod;
  160. /**
  161. * Returns whether there is a value stored at the field specified by the
  162. * given field descriptor.
  163. *
  164. * @param {goog.proto2.FieldDescriptor} field The field for which to check
  165. * if there is a value.
  166. *
  167. * @return {boolean} True if a value was found.
  168. */
  169. goog.proto2.Message.prototype.has = function(field) {
  170. goog.asserts.assert(
  171. field.getContainingType() == this.getDescriptor(),
  172. 'The current message does not contain the given field');
  173. return this.has$Value(field.getTag());
  174. };
  175. /**
  176. * Returns the array of values found for the given repeated field.
  177. *
  178. * @param {goog.proto2.FieldDescriptor} field The field for which to
  179. * return the values.
  180. *
  181. * @return {!Array<?>} The values found.
  182. */
  183. goog.proto2.Message.prototype.arrayOf = function(field) {
  184. goog.asserts.assert(
  185. field.getContainingType() == this.getDescriptor(),
  186. 'The current message does not contain the given field');
  187. return this.array$Values(field.getTag());
  188. };
  189. /**
  190. * Returns the number of values stored in the given field.
  191. *
  192. * @param {goog.proto2.FieldDescriptor} field The field for which to count
  193. * the number of values.
  194. *
  195. * @return {number} The count of the values in the given field.
  196. */
  197. goog.proto2.Message.prototype.countOf = function(field) {
  198. goog.asserts.assert(
  199. field.getContainingType() == this.getDescriptor(),
  200. 'The current message does not contain the given field');
  201. return this.count$Values(field.getTag());
  202. };
  203. /**
  204. * Returns the value stored at the field specified by the
  205. * given field descriptor.
  206. *
  207. * @param {goog.proto2.FieldDescriptor} field The field for which to get the
  208. * value.
  209. * @param {number=} opt_index If the field is repeated, the index to use when
  210. * looking up the value.
  211. *
  212. * @return {?} The value found or null if none.
  213. */
  214. goog.proto2.Message.prototype.get = function(field, opt_index) {
  215. goog.asserts.assert(
  216. field.getContainingType() == this.getDescriptor(),
  217. 'The current message does not contain the given field');
  218. return this.get$Value(field.getTag(), opt_index);
  219. };
  220. /**
  221. * Returns the value stored at the field specified by the
  222. * given field descriptor or the default value if none exists.
  223. *
  224. * @param {goog.proto2.FieldDescriptor} field The field for which to get the
  225. * value.
  226. * @param {number=} opt_index If the field is repeated, the index to use when
  227. * looking up the value.
  228. *
  229. * @return {?} The value found or the default if none.
  230. */
  231. goog.proto2.Message.prototype.getOrDefault = function(field, opt_index) {
  232. goog.asserts.assert(
  233. field.getContainingType() == this.getDescriptor(),
  234. 'The current message does not contain the given field');
  235. return this.get$ValueOrDefault(field.getTag(), opt_index);
  236. };
  237. /**
  238. * Stores the given value to the field specified by the
  239. * given field descriptor. Note that the field must not be repeated.
  240. *
  241. * @param {goog.proto2.FieldDescriptor} field The field for which to set
  242. * the value.
  243. * @param {*} value The new value for the field.
  244. */
  245. goog.proto2.Message.prototype.set = function(field, value) {
  246. goog.asserts.assert(
  247. field.getContainingType() == this.getDescriptor(),
  248. 'The current message does not contain the given field');
  249. this.set$Value(field.getTag(), value);
  250. };
  251. /**
  252. * Adds the given value to the field specified by the
  253. * given field descriptor. Note that the field must be repeated.
  254. *
  255. * @param {goog.proto2.FieldDescriptor} field The field in which to add the
  256. * the value.
  257. * @param {*} value The new value to add to the field.
  258. */
  259. goog.proto2.Message.prototype.add = function(field, value) {
  260. goog.asserts.assert(
  261. field.getContainingType() == this.getDescriptor(),
  262. 'The current message does not contain the given field');
  263. this.add$Value(field.getTag(), value);
  264. };
  265. /**
  266. * Clears the field specified.
  267. *
  268. * @param {goog.proto2.FieldDescriptor} field The field to clear.
  269. */
  270. goog.proto2.Message.prototype.clear = function(field) {
  271. goog.asserts.assert(
  272. field.getContainingType() == this.getDescriptor(),
  273. 'The current message does not contain the given field');
  274. this.clear$Field(field.getTag());
  275. };
  276. /**
  277. * Compares this message with another one ignoring the unknown fields.
  278. * @param {?} other The other message.
  279. * @return {boolean} Whether they are equal. Returns false if the {@code other}
  280. * argument is a different type of message or not a message.
  281. */
  282. goog.proto2.Message.prototype.equals = function(other) {
  283. if (!other || this.constructor != other.constructor) {
  284. return false;
  285. }
  286. var fields = this.getDescriptor().getFields();
  287. for (var i = 0; i < fields.length; i++) {
  288. var field = fields[i];
  289. var tag = field.getTag();
  290. if (this.has$Value(tag) != other.has$Value(tag)) {
  291. return false;
  292. }
  293. if (this.has$Value(tag)) {
  294. var isComposite = field.isCompositeType();
  295. var fieldsEqual = function(value1, value2) {
  296. return isComposite ? value1.equals(value2) : value1 == value2;
  297. };
  298. var thisValue = this.getValueForTag_(tag);
  299. var otherValue = other.getValueForTag_(tag);
  300. if (field.isRepeated()) {
  301. // In this case thisValue and otherValue are arrays.
  302. if (thisValue.length != otherValue.length) {
  303. return false;
  304. }
  305. for (var j = 0; j < thisValue.length; j++) {
  306. if (!fieldsEqual(thisValue[j], otherValue[j])) {
  307. return false;
  308. }
  309. }
  310. } else if (!fieldsEqual(thisValue, otherValue)) {
  311. return false;
  312. }
  313. }
  314. }
  315. return true;
  316. };
  317. /**
  318. * Recursively copies the known fields from the given message to this message.
  319. * Removes the fields which are not present in the source message.
  320. * @param {!goog.proto2.Message} message The source message.
  321. */
  322. goog.proto2.Message.prototype.copyFrom = function(message) {
  323. goog.asserts.assert(
  324. this.constructor == message.constructor,
  325. 'The source message must have the same type.');
  326. if (this != message) {
  327. this.values_ = {};
  328. if (this.deserializedFields_) {
  329. this.deserializedFields_ = {};
  330. }
  331. this.mergeFrom(message);
  332. }
  333. };
  334. /**
  335. * Merges the given message into this message.
  336. *
  337. * Singular fields will be overwritten, except for embedded messages which will
  338. * be merged. Repeated fields will be concatenated.
  339. * @param {!goog.proto2.Message} message The source message.
  340. */
  341. goog.proto2.Message.prototype.mergeFrom = function(message) {
  342. goog.asserts.assert(
  343. this.constructor == message.constructor,
  344. 'The source message must have the same type.');
  345. var fields = this.getDescriptor().getFields();
  346. for (var i = 0; i < fields.length; i++) {
  347. var field = fields[i];
  348. var tag = field.getTag();
  349. if (message.has$Value(tag)) {
  350. if (this.deserializedFields_) {
  351. delete this.deserializedFields_[field.getTag()];
  352. }
  353. var isComposite = field.isCompositeType();
  354. if (field.isRepeated()) {
  355. var values = message.array$Values(tag);
  356. for (var j = 0; j < values.length; j++) {
  357. this.add$Value(tag, isComposite ? values[j].clone() : values[j]);
  358. }
  359. } else {
  360. var value = message.getValueForTag_(tag);
  361. if (isComposite) {
  362. var child = this.getValueForTag_(tag);
  363. if (child) {
  364. child.mergeFrom(value);
  365. } else {
  366. this.set$Value(tag, value.clone());
  367. }
  368. } else {
  369. this.set$Value(tag, value);
  370. }
  371. }
  372. }
  373. }
  374. };
  375. /**
  376. * @return {!goog.proto2.Message} Recursive clone of the message only including
  377. * the known fields.
  378. */
  379. goog.proto2.Message.prototype.clone = function() {
  380. /** @type {!goog.proto2.Message} */
  381. var clone = new this.constructor;
  382. clone.copyFrom(this);
  383. return clone;
  384. };
  385. /**
  386. * Fills in the protocol buffer with default values. Any fields that are
  387. * already set will not be overridden.
  388. * @param {boolean} simpleFieldsToo If true, all fields will be initialized;
  389. * if false, only the nested messages and groups.
  390. */
  391. goog.proto2.Message.prototype.initDefaults = function(simpleFieldsToo) {
  392. var fields = this.getDescriptor().getFields();
  393. for (var i = 0; i < fields.length; i++) {
  394. var field = fields[i];
  395. var tag = field.getTag();
  396. var isComposite = field.isCompositeType();
  397. // Initialize missing fields.
  398. if (!this.has$Value(tag) && !field.isRepeated()) {
  399. if (isComposite) {
  400. this.values_[tag] = new /** @type {Function} */ (field.getNativeType());
  401. } else if (simpleFieldsToo) {
  402. this.values_[tag] = field.getDefaultValue();
  403. }
  404. }
  405. // Fill in the existing composite fields recursively.
  406. if (isComposite) {
  407. if (field.isRepeated()) {
  408. var values = this.array$Values(tag);
  409. for (var j = 0; j < values.length; j++) {
  410. values[j].initDefaults(simpleFieldsToo);
  411. }
  412. } else {
  413. this.get$Value(tag).initDefaults(simpleFieldsToo);
  414. }
  415. }
  416. }
  417. };
  418. /**
  419. * Returns the whether or not the field indicated by the given tag
  420. * has a value.
  421. *
  422. * GENERATED CODE USE ONLY. Basis of the has{Field} methods.
  423. *
  424. * @param {number} tag The tag.
  425. *
  426. * @return {boolean} Whether the message has a value for the field.
  427. */
  428. goog.proto2.Message.prototype.has$Value = function(tag) {
  429. return this.values_[tag] != null;
  430. };
  431. /**
  432. * Returns the value for the given tag number. If a lazy deserializer is
  433. * instantiated, lazily deserializes the field if required before returning the
  434. * value.
  435. *
  436. * @param {number} tag The tag number.
  437. * @return {?} The corresponding value, if any.
  438. * @private
  439. */
  440. goog.proto2.Message.prototype.getValueForTag_ = function(tag) {
  441. // Retrieve the current value, which may still be serialized.
  442. var value = this.values_[tag];
  443. if (!goog.isDefAndNotNull(value)) {
  444. return null;
  445. }
  446. // If we have a lazy deserializer, then ensure that the field is
  447. // properly deserialized.
  448. if (this.lazyDeserializer_) {
  449. // If the tag is not deserialized, then we must do so now. Deserialize
  450. // the field's value via the deserializer.
  451. if (!(tag in /** @type {!Object} */ (this.deserializedFields_))) {
  452. var deserializedValue = this.lazyDeserializer_.deserializeField(
  453. this, this.fields_[tag], value);
  454. this.deserializedFields_[tag] = deserializedValue;
  455. return deserializedValue;
  456. }
  457. return this.deserializedFields_[tag];
  458. }
  459. // Otherwise, just return the value.
  460. return value;
  461. };
  462. /**
  463. * Gets the value at the field indicated by the given tag.
  464. *
  465. * GENERATED CODE USE ONLY. Basis of the get{Field} methods.
  466. *
  467. * @param {number} tag The field's tag index.
  468. * @param {number=} opt_index If the field is a repeated field, the index
  469. * at which to get the value.
  470. *
  471. * @return {?} The value found or null for none.
  472. * @protected
  473. */
  474. goog.proto2.Message.prototype.get$Value = function(tag, opt_index) {
  475. var value = this.getValueForTag_(tag);
  476. if (this.fields_[tag].isRepeated()) {
  477. var index = opt_index || 0;
  478. goog.asserts.assert(
  479. index >= 0 && index < value.length,
  480. 'Given index %s is out of bounds. Repeated field length: %s', index,
  481. value.length);
  482. return value[index];
  483. }
  484. return value;
  485. };
  486. /**
  487. * Gets the value at the field indicated by the given tag or the default value
  488. * if none.
  489. *
  490. * GENERATED CODE USE ONLY. Basis of the get{Field} methods.
  491. *
  492. * @param {number} tag The field's tag index.
  493. * @param {number=} opt_index If the field is a repeated field, the index
  494. * at which to get the value.
  495. *
  496. * @return {?} The value found or the default value if none set.
  497. * @protected
  498. */
  499. goog.proto2.Message.prototype.get$ValueOrDefault = function(tag, opt_index) {
  500. if (!this.has$Value(tag)) {
  501. // Return the default value.
  502. var field = this.fields_[tag];
  503. return field.getDefaultValue();
  504. }
  505. return this.get$Value(tag, opt_index);
  506. };
  507. /**
  508. * Gets the values at the field indicated by the given tag.
  509. *
  510. * GENERATED CODE USE ONLY. Basis of the {field}Array methods.
  511. *
  512. * @param {number} tag The field's tag index.
  513. *
  514. * @return {!Array<?>} The values found. If none, returns an empty array.
  515. * @protected
  516. */
  517. goog.proto2.Message.prototype.array$Values = function(tag) {
  518. var value = this.getValueForTag_(tag);
  519. return value || [];
  520. };
  521. /**
  522. * Returns the number of values stored in the field by the given tag.
  523. *
  524. * GENERATED CODE USE ONLY. Basis of the {field}Count methods.
  525. *
  526. * @param {number} tag The tag.
  527. *
  528. * @return {number} The number of values.
  529. * @protected
  530. */
  531. goog.proto2.Message.prototype.count$Values = function(tag) {
  532. var field = this.fields_[tag];
  533. if (field.isRepeated()) {
  534. return this.has$Value(tag) ? this.values_[tag].length : 0;
  535. } else {
  536. return this.has$Value(tag) ? 1 : 0;
  537. }
  538. };
  539. /**
  540. * Sets the value of the *non-repeating* field indicated by the given tag.
  541. *
  542. * GENERATED CODE USE ONLY. Basis of the set{Field} methods.
  543. *
  544. * @param {number} tag The field's tag index.
  545. * @param {*} value The field's value.
  546. * @protected
  547. */
  548. goog.proto2.Message.prototype.set$Value = function(tag, value) {
  549. if (goog.asserts.ENABLE_ASSERTS) {
  550. var field = this.fields_[tag];
  551. this.checkFieldType_(field, value);
  552. }
  553. this.values_[tag] = value;
  554. if (this.deserializedFields_) {
  555. this.deserializedFields_[tag] = value;
  556. }
  557. };
  558. /**
  559. * Adds the value to the *repeating* field indicated by the given tag.
  560. *
  561. * GENERATED CODE USE ONLY. Basis of the add{Field} methods.
  562. *
  563. * @param {number} tag The field's tag index.
  564. * @param {*} value The value to add.
  565. * @protected
  566. */
  567. goog.proto2.Message.prototype.add$Value = function(tag, value) {
  568. if (goog.asserts.ENABLE_ASSERTS) {
  569. var field = this.fields_[tag];
  570. this.checkFieldType_(field, value);
  571. }
  572. if (!this.values_[tag]) {
  573. this.values_[tag] = [];
  574. }
  575. this.values_[tag].push(value);
  576. if (this.deserializedFields_) {
  577. delete this.deserializedFields_[tag];
  578. }
  579. };
  580. /**
  581. * Ensures that the value being assigned to the given field
  582. * is valid.
  583. *
  584. * @param {!goog.proto2.FieldDescriptor} field The field being assigned.
  585. * @param {*} value The value being assigned.
  586. * @private
  587. */
  588. goog.proto2.Message.prototype.checkFieldType_ = function(field, value) {
  589. if (field.getFieldType() == goog.proto2.FieldDescriptor.FieldType.ENUM) {
  590. goog.asserts.assertNumber(value);
  591. } else {
  592. goog.asserts.assert(Object(value).constructor == field.getNativeType());
  593. }
  594. };
  595. /**
  596. * Clears the field specified by tag.
  597. *
  598. * GENERATED CODE USE ONLY. Basis of the clear{Field} methods.
  599. *
  600. * @param {number} tag The tag of the field to clear.
  601. * @protected
  602. */
  603. goog.proto2.Message.prototype.clear$Field = function(tag) {
  604. delete this.values_[tag];
  605. if (this.deserializedFields_) {
  606. delete this.deserializedFields_[tag];
  607. }
  608. };
  609. /**
  610. * Creates the metadata descriptor representing the definition of this message.
  611. *
  612. * @param {function(new:goog.proto2.Message)} messageType Constructor for the
  613. * message type to which this metadata applies.
  614. * @param {!Object} metadataObj The object containing the metadata.
  615. * @return {!goog.proto2.Descriptor} The new descriptor.
  616. */
  617. goog.proto2.Message.createDescriptor = function(messageType, metadataObj) {
  618. var fields = [];
  619. var descriptorInfo = metadataObj[0];
  620. for (var key in metadataObj) {
  621. if (key != 0) {
  622. // Create the field descriptor.
  623. fields.push(
  624. new goog.proto2.FieldDescriptor(messageType, key, metadataObj[key]));
  625. }
  626. }
  627. return new goog.proto2.Descriptor(messageType, descriptorInfo, fields);
  628. };