Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: third_party/protobuf/js/message.js

Issue 1983203003: Update third_party/protobuf to protobuf-v3.0.0-beta-3 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: owners Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/protobuf/js/jasmine.json ('k') | third_party/protobuf/js/message_test.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 21 matching lines...) Expand all
32 * @fileoverview Definition of jspb.Message. 32 * @fileoverview Definition of jspb.Message.
33 * 33 *
34 * @author mwr@google.com (Mark Rawling) 34 * @author mwr@google.com (Mark Rawling)
35 */ 35 */
36 36
37 goog.provide('jspb.ExtensionFieldInfo'); 37 goog.provide('jspb.ExtensionFieldInfo');
38 goog.provide('jspb.Message'); 38 goog.provide('jspb.Message');
39 39
40 goog.require('goog.array'); 40 goog.require('goog.array');
41 goog.require('goog.asserts'); 41 goog.require('goog.asserts');
42 goog.require('goog.crypt.base64');
42 goog.require('goog.json'); 43 goog.require('goog.json');
43 goog.require('goog.object');
44 44
45 // Not needed in compilation units that have no protos with xids. 45 // Not needed in compilation units that have no protos with xids.
46 goog.forwardDeclare('xid.String'); 46 goog.forwardDeclare('xid.String');
47 47
48 48
49 49
50 /** 50 /**
51 * Stores information for a single extension field. 51 * Stores information for a single extension field.
52 * 52 *
53 * For example, an extension field defined like so: 53 * For example, an extension field defined like so:
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 /** @const */ 113 /** @const */
114 this.binaryMessageDeserializeFn = opt_binaryMessageDeserializeFn; 114 this.binaryMessageDeserializeFn = opt_binaryMessageDeserializeFn;
115 /** @const */ 115 /** @const */
116 this.isRepeated = isRepeated; 116 this.isRepeated = isRepeated;
117 /** @const */ 117 /** @const */
118 this.isPacked = opt_isPacked; 118 this.isPacked = opt_isPacked;
119 }; 119 };
120 120
121 121
122 /** 122 /**
123 * @return {boolean} Does this field represent a sub Message?
124 */
125 jspb.ExtensionFieldInfo.prototype.isMessageType = function() {
126 return !!this.ctor;
127 };
128
129
130 /**
123 * Base class for all JsPb messages. 131 * Base class for all JsPb messages.
124 * @constructor 132 * @constructor
125 * @struct 133 * @struct
126 */ 134 */
127 jspb.Message = function() { 135 jspb.Message = function() {
128 }; 136 };
129 137
130 138
131 /** 139 /**
132 * @define {boolean} Whether to generate toObject methods for objects. Turn 140 * @define {boolean} Whether to generate toObject methods for objects. Turn
(...skipping 26 matching lines...) Expand all
159 * and only affects private internal state. It may, however, break some 167 * and only affects private internal state. It may, however, break some
160 * tests that use naive deeply-equals algorithms, because using a proto 168 * tests that use naive deeply-equals algorithms, because using a proto
161 * mutates its internal state. 169 * mutates its internal state.
162 * Projects are advised to turn this flag always on. 170 * Projects are advised to turn this flag always on.
163 */ 171 */
164 goog.define('jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS', COMPILED); 172 goog.define('jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS', COMPILED);
165 // TODO(b/19419436) Turn this on by default. 173 // TODO(b/19419436) Turn this on by default.
166 174
167 175
168 /** 176 /**
177 * Does this browser support Uint8Aray typed arrays?
178 * @type {boolean}
179 * @private
180 */
181 jspb.Message.SUPPORTS_UINT8ARRAY_ = (typeof Uint8Array == 'function');
182
183
184 /**
169 * The internal data array. 185 * The internal data array.
170 * @type {!Array} 186 * @type {!Array}
171 * @protected 187 * @protected
172 */ 188 */
173 jspb.Message.prototype.array; 189 jspb.Message.prototype.array;
174 190
175 191
176 /** 192 /**
177 * Wrappers are the constructed instances of message-type fields. They are built 193 * Wrappers are the constructed instances of message-type fields. They are built
178 * on demand from the raw array data. Includes message fields, repeated message 194 * on demand from the raw array data. Includes message fields, repeated message
(...skipping 25 matching lines...) Expand all
204 /** 220 /**
205 * The JsPb message_id of this proto. 221 * The JsPb message_id of this proto.
206 * @type {string|undefined} the message id or undefined if this message 222 * @type {string|undefined} the message id or undefined if this message
207 * has no id. 223 * has no id.
208 * @private 224 * @private
209 */ 225 */
210 jspb.Message.prototype.messageId_; 226 jspb.Message.prototype.messageId_;
211 227
212 228
213 /** 229 /**
230 * Repeated float or double fields which have been converted to include only
231 * numbers and not strings holding "NaN", "Infinity" and "-Infinity".
232 * @private {!Object<number,boolean>|undefined}
233 */
234 jspb.Message.prototype.convertedFloatingPointFields_;
235
236
237 /**
214 * The xid of this proto type (The same for all instances of a proto). Provides 238 * The xid of this proto type (The same for all instances of a proto). Provides
215 * a way to identify a proto by stable obfuscated name. 239 * a way to identify a proto by stable obfuscated name.
216 * @see {xid}. 240 * @see {xid}.
217 * Available if {@link jspb.generate_xid} is added as a Message option to 241 * Available if {@link jspb.generate_xid} is added as a Message option to
218 * a protocol buffer. 242 * a protocol buffer.
219 * @const {!xid.String|undefined} The xid or undefined if message is 243 * @const {!xid.String|undefined} The xid or undefined if message is
220 * annotated to generate the xid. 244 * annotated to generate the xid.
221 */ 245 */
222 jspb.Message.prototype.messageXid; 246 jspb.Message.prototype.messageXid;
223 247
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 if (!data) { 301 if (!data) {
278 data = messageId ? [messageId] : []; 302 data = messageId ? [messageId] : [];
279 } 303 }
280 msg.messageId_ = messageId ? String(messageId) : undefined; 304 msg.messageId_ = messageId ? String(messageId) : undefined;
281 // If the messageId is 0, this message is not a response message, so we shift 305 // If the messageId is 0, this message is not a response message, so we shift
282 // array indices down by 1 so as not to waste the first position in the array, 306 // array indices down by 1 so as not to waste the first position in the array,
283 // which would otherwise go unused. 307 // which would otherwise go unused.
284 msg.arrayIndexOffset_ = messageId === 0 ? -1 : 0; 308 msg.arrayIndexOffset_ = messageId === 0 ? -1 : 0;
285 msg.array = data; 309 msg.array = data;
286 jspb.Message.materializeExtensionObject_(msg, suggestedPivot); 310 jspb.Message.materializeExtensionObject_(msg, suggestedPivot);
311 msg.convertedFloatingPointFields_ = {};
312
287 if (repeatedFields) { 313 if (repeatedFields) {
288 for (var i = 0; i < repeatedFields.length; i++) { 314 for (var i = 0; i < repeatedFields.length; i++) {
289 var fieldNumber = repeatedFields[i]; 315 var fieldNumber = repeatedFields[i];
290 if (fieldNumber < msg.pivot_) { 316 if (fieldNumber < msg.pivot_) {
291 var index = jspb.Message.getIndex_(msg, fieldNumber); 317 var index = jspb.Message.getIndex_(msg, fieldNumber);
292 msg.array[index] = msg.array[index] || 318 msg.array[index] = msg.array[index] ||
293 (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ? 319 (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ?
294 jspb.Message.EMPTY_LIST_SENTINEL_ : 320 jspb.Message.EMPTY_LIST_SENTINEL_ :
295 []); 321 []);
296 } else { 322 } else {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 } 438 }
413 return result; 439 return result;
414 }; 440 };
415 441
416 442
417 /** 443 /**
418 * Adds a proto's extension data to a Soy rendering object. 444 * Adds a proto's extension data to a Soy rendering object.
419 * @param {!jspb.Message} proto The proto whose extensions to convert. 445 * @param {!jspb.Message} proto The proto whose extensions to convert.
420 * @param {!Object} obj The Soy object to add converted extension data to. 446 * @param {!Object} obj The Soy object to add converted extension data to.
421 * @param {!Object} extensions The proto class' registered extensions. 447 * @param {!Object} extensions The proto class' registered extensions.
422 * @param {function(jspb.ExtensionFieldInfo) : *} getExtensionFn The proto 448 * @param {function(this:?, jspb.ExtensionFieldInfo) : *} getExtensionFn
423 * class' getExtension function. Passed for effective dead code removal. 449 * The proto class' getExtension function. Passed for effective dead code
450 * removal.
424 * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 451 * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
425 * for transitional soy proto support: http://goto/soy-param-migration 452 * for transitional soy proto support: http://goto/soy-param-migration
426 */ 453 */
427 jspb.Message.toObjectExtension = function(proto, obj, extensions, 454 jspb.Message.toObjectExtension = function(proto, obj, extensions,
428 getExtensionFn, opt_includeInstance) { 455 getExtensionFn, opt_includeInstance) {
429 for (var fieldNumber in extensions) { 456 for (var fieldNumber in extensions) {
430 var fieldInfo = extensions[fieldNumber]; 457 var fieldInfo = extensions[fieldNumber];
431 var value = getExtensionFn.call(proto, fieldInfo); 458 var value = getExtensionFn.call(proto, fieldInfo);
432 if (value) { 459 if (value) {
433 for (var name in fieldInfo.fieldName) { 460 for (var name in fieldInfo.fieldName) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 var fieldInfo = extensions[fieldNumber]; 492 var fieldInfo = extensions[fieldNumber];
466 // The old codegen doesn't add the extra fields to ExtensionFieldInfo, so we 493 // The old codegen doesn't add the extra fields to ExtensionFieldInfo, so we
467 // need to gracefully error-out here rather than produce a null dereference 494 // need to gracefully error-out here rather than produce a null dereference
468 // below. 495 // below.
469 if (!fieldInfo.binaryWriterFn) { 496 if (!fieldInfo.binaryWriterFn) {
470 throw new Error('Message extension present that was generated ' + 497 throw new Error('Message extension present that was generated ' +
471 'without binary serialization support'); 498 'without binary serialization support');
472 } 499 }
473 var value = getExtensionFn.call(proto, fieldInfo); 500 var value = getExtensionFn.call(proto, fieldInfo);
474 if (value) { 501 if (value) {
475 if (fieldInfo.ctor) { // is this a message type? 502 if (fieldInfo.isMessageType()) {
476 // If the message type of the extension was generated without binary 503 // If the message type of the extension was generated without binary
477 // support, there may not be a binary message serializer function, and 504 // support, there may not be a binary message serializer function, and
478 // we can't know when we codegen the extending message that the extended 505 // we can't know when we codegen the extending message that the extended
479 // message may require binary support, so we can *only* catch this error 506 // message may require binary support, so we can *only* catch this error
480 // here, at runtime (and this decoupled codegen is the whole point of 507 // here, at runtime (and this decoupled codegen is the whole point of
481 // extensions!). 508 // extensions!).
482 if (fieldInfo.binaryMessageSerializeFn) { 509 if (fieldInfo.binaryMessageSerializeFn) {
483 fieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex, 510 fieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex,
484 value, fieldInfo.binaryMessageSerializeFn); 511 value, fieldInfo.binaryMessageSerializeFn);
485 } else { 512 } else {
(...skipping 24 matching lines...) Expand all
510 if (!fieldInfo) { 537 if (!fieldInfo) {
511 reader.skipField(); 538 reader.skipField();
512 return; 539 return;
513 } 540 }
514 if (!fieldInfo.binaryReaderFn) { 541 if (!fieldInfo.binaryReaderFn) {
515 throw new Error('Deserializing extension whose generated code does not ' + 542 throw new Error('Deserializing extension whose generated code does not ' +
516 'support binary format'); 543 'support binary format');
517 } 544 }
518 545
519 var value; 546 var value;
520 if (fieldInfo.ctor) { 547 if (fieldInfo.isMessageType()) {
521 // Message type.
522 value = new fieldInfo.ctor(); 548 value = new fieldInfo.ctor();
523 fieldInfo.binaryReaderFn.call( 549 fieldInfo.binaryReaderFn.call(
524 reader, value, fieldInfo.binaryMessageDeserializeFn); 550 reader, value, fieldInfo.binaryMessageDeserializeFn);
525 } else { 551 } else {
526 // All other types. 552 // All other types.
527 value = fieldInfo.binaryReaderFn.call(reader); 553 value = fieldInfo.binaryReaderFn.call(reader);
528 } 554 }
529 555
530 if (fieldInfo.isRepeated && !fieldInfo.isPacked) { 556 if (fieldInfo.isRepeated && !fieldInfo.isPacked) {
531 var currentList = getExtensionFn.call(msg, fieldInfo); 557 var currentList = getExtensionFn.call(msg, fieldInfo);
(...skipping 28 matching lines...) Expand all
560 var val = msg.extensionObject_[fieldNumber]; 586 var val = msg.extensionObject_[fieldNumber];
561 if (val === jspb.Message.EMPTY_LIST_SENTINEL_) { 587 if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
562 return msg.extensionObject_[fieldNumber] = []; 588 return msg.extensionObject_[fieldNumber] = [];
563 } 589 }
564 return val; 590 return val;
565 } 591 }
566 }; 592 };
567 593
568 594
569 /** 595 /**
596 * Gets the value of an optional float or double field.
597 * @param {!jspb.Message} msg A jspb proto.
598 * @param {number} fieldNumber The field number.
599 * @return {?number|undefined} The field's value.
600 * @protected
601 */
602 jspb.Message.getOptionalFloatingPointField = function(msg, fieldNumber) {
603 var value = jspb.Message.getField(msg, fieldNumber);
604 // Converts "NaN", "Infinity" and "-Infinity" to their corresponding numbers.
605 return value == null ? value : +value;
606 };
607
608
609 /**
610 * Gets the value of a repeated float or double field.
611 * @param {!jspb.Message} msg A jspb proto.
612 * @param {number} fieldNumber The field number.
613 * @return {!Array<number>} The field's value.
614 * @protected
615 */
616 jspb.Message.getRepeatedFloatingPointField = function(msg, fieldNumber) {
617 var values = jspb.Message.getField(msg, fieldNumber);
618 if (!msg.convertedFloatingPointFields_) {
619 msg.convertedFloatingPointFields_ = {};
620 }
621 if (!msg.convertedFloatingPointFields_[fieldNumber]) {
622 for (var i = 0; i < values.length; i++) {
623 // Converts "NaN", "Infinity" and "-Infinity" to their corresponding
624 // numbers.
625 values[i] = +values[i];
626 }
627 msg.convertedFloatingPointFields_[fieldNumber] = true;
628 }
629 return /** @type {!Array<number>} */ (values);
630 };
631
632
633 /**
634 * Coerce a 'bytes' field to a base 64 string.
635 * @param {string|Uint8Array|null} value
636 * @return {?string} The field's coerced value.
637 */
638 jspb.Message.bytesAsB64 = function(value) {
639 if (value == null || goog.isString(value)) {
640 return value;
641 }
642 if (jspb.Message.SUPPORTS_UINT8ARRAY_ && value instanceof Uint8Array) {
643 return goog.crypt.base64.encodeByteArray(value);
644 }
645 goog.asserts.fail('Cannot coerce to b64 string: ' + goog.typeOf(value));
646 return null;
647 };
648
649
650 /**
651 * Coerce a 'bytes' field to a Uint8Array byte buffer.
652 * Note that Uint8Array is not supported on IE versions before 10 nor on Opera
653 * Mini. @see http://caniuse.com/Uint8Array
654 * @param {string|Uint8Array|null} value
655 * @return {?Uint8Array} The field's coerced value.
656 */
657 jspb.Message.bytesAsU8 = function(value) {
658 if (value == null || value instanceof Uint8Array) {
659 return value;
660 }
661 if (goog.isString(value)) {
662 return goog.crypt.base64.decodeStringToUint8Array(value);
663 }
664 goog.asserts.fail('Cannot coerce to Uint8Array: ' + goog.typeOf(value));
665 return null;
666 };
667
668
669 /**
670 * Coerce a repeated 'bytes' field to an array of base 64 strings.
671 * Note: the returned array should be treated as immutable.
672 * @param {!Array<string>|!Array<!Uint8Array>} value
673 * @return {!Array<string?>} The field's coerced value.
674 */
675 jspb.Message.bytesListAsB64 = function(value) {
676 jspb.Message.assertConsistentTypes_(value);
677 if (!value.length || goog.isString(value[0])) {
678 return /** @type {!Array<string>} */ (value);
679 }
680 return goog.array.map(value, jspb.Message.bytesAsB64);
681 };
682
683
684 /**
685 * Coerce a repeated 'bytes' field to an array of Uint8Array byte buffers.
686 * Note: the returned array should be treated as immutable.
687 * Note that Uint8Array is not supported on IE versions before 10 nor on Opera
688 * Mini. @see http://caniuse.com/Uint8Array
689 * @param {!Array<string>|!Array<!Uint8Array>} value
690 * @return {!Array<Uint8Array?>} The field's coerced value.
691 */
692 jspb.Message.bytesListAsU8 = function(value) {
693 jspb.Message.assertConsistentTypes_(value);
694 if (!value.length || value[0] instanceof Uint8Array) {
695 return /** @type {!Array<!Uint8Array>} */ (value);
696 }
697 return goog.array.map(value, jspb.Message.bytesAsU8);
698 };
699
700
701 /**
702 * Asserts that all elements of an array are of the same type.
703 * @param {Array?} array The array to test.
704 * @private
705 */
706 jspb.Message.assertConsistentTypes_ = function(array) {
707 if (goog.DEBUG && array && array.length > 1) {
708 var expected = goog.typeOf(array[0]);
709 goog.array.forEach(array, function(e) {
710 if (goog.typeOf(e) != expected) {
711 goog.asserts.fail('Inconsistent type in JSPB repeated field array. ' +
712 'Got ' + goog.typeOf(e) + ' expected ' + expected);
713 }
714 });
715 }
716 };
717
718
719 /**
570 * Gets the value of a non-extension primitive field, with proto3 (non-nullable 720 * Gets the value of a non-extension primitive field, with proto3 (non-nullable
571 * primitives) semantics. Returns `defaultValue` if the field is not otherwise 721 * primitives) semantics. Returns `defaultValue` if the field is not otherwise
572 * set. 722 * set.
573 * @template T 723 * @template T
574 * @param {!jspb.Message} msg A jspb proto. 724 * @param {!jspb.Message} msg A jspb proto.
575 * @param {number} fieldNumber The field number. 725 * @param {number} fieldNumber The field number.
576 * @param {T} defaultValue The default value. 726 * @param {T} defaultValue The default value.
577 * @return {T} The field's value. 727 * @return {T} The field's value.
578 * @protected 728 * @protected
579 */ 729 */
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 */ 984 */
835 jspb.Message.prototype.getExtension = function(fieldInfo) { 985 jspb.Message.prototype.getExtension = function(fieldInfo) {
836 if (!this.extensionObject_) { 986 if (!this.extensionObject_) {
837 return undefined; 987 return undefined;
838 } 988 }
839 if (!this.wrappers_) { 989 if (!this.wrappers_) {
840 this.wrappers_ = {}; 990 this.wrappers_ = {};
841 } 991 }
842 var fieldNumber = fieldInfo.fieldIndex; 992 var fieldNumber = fieldInfo.fieldIndex;
843 if (fieldInfo.isRepeated) { 993 if (fieldInfo.isRepeated) {
844 if (fieldInfo.ctor) { 994 if (fieldInfo.isMessageType()) {
845 if (!this.wrappers_[fieldNumber]) { 995 if (!this.wrappers_[fieldNumber]) {
846 this.wrappers_[fieldNumber] = 996 this.wrappers_[fieldNumber] =
847 goog.array.map(this.extensionObject_[fieldNumber] || [], 997 goog.array.map(this.extensionObject_[fieldNumber] || [],
848 function(arr) { 998 function(arr) {
849 return new fieldInfo.ctor(arr); 999 return new fieldInfo.ctor(arr);
850 }); 1000 });
851 } 1001 }
852 return this.wrappers_[fieldNumber]; 1002 return this.wrappers_[fieldNumber];
853 } else { 1003 } else {
854 return this.extensionObject_[fieldNumber]; 1004 return this.extensionObject_[fieldNumber];
855 } 1005 }
856 } else { 1006 } else {
857 if (fieldInfo.ctor) { 1007 if (fieldInfo.isMessageType()) {
858 if (!this.wrappers_[fieldNumber] && this.extensionObject_[fieldNumber]) { 1008 if (!this.wrappers_[fieldNumber] && this.extensionObject_[fieldNumber]) {
859 this.wrappers_[fieldNumber] = new fieldInfo.ctor( 1009 this.wrappers_[fieldNumber] = new fieldInfo.ctor(
860 /** @type {Array|undefined} */ ( 1010 /** @type {Array|undefined} */ (
861 this.extensionObject_[fieldNumber])); 1011 this.extensionObject_[fieldNumber]));
862 } 1012 }
863 return this.wrappers_[fieldNumber]; 1013 return this.wrappers_[fieldNumber];
864 } else { 1014 } else {
865 return this.extensionObject_[fieldNumber]; 1015 return this.extensionObject_[fieldNumber];
866 } 1016 }
867 } 1017 }
868 }; 1018 };
869 1019
870 1020
871 /** 1021 /**
872 * Sets the value of the extension field in the extended object. 1022 * Sets the value of the extension field in the extended object.
873 * @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to set. 1023 * @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to set.
874 * @param {jspb.Message|string|number|boolean|Array} value The value to set. 1024 * @param {jspb.Message|string|Uint8Array|number|boolean|Array?} value The value
1025 * to set.
875 */ 1026 */
876 jspb.Message.prototype.setExtension = function(fieldInfo, value) { 1027 jspb.Message.prototype.setExtension = function(fieldInfo, value) {
877 if (!this.wrappers_) { 1028 if (!this.wrappers_) {
878 this.wrappers_ = {}; 1029 this.wrappers_ = {};
879 } 1030 }
880 jspb.Message.maybeInitEmptyExtensionObject_(this); 1031 jspb.Message.maybeInitEmptyExtensionObject_(this);
881 var fieldNumber = fieldInfo.fieldIndex; 1032 var fieldNumber = fieldInfo.fieldIndex;
882 if (fieldInfo.isRepeated) { 1033 if (fieldInfo.isRepeated) {
883 value = value || []; 1034 value = value || [];
884 if (fieldInfo.ctor) { 1035 if (fieldInfo.isMessageType()) {
885 this.wrappers_[fieldNumber] = value; 1036 this.wrappers_[fieldNumber] = value;
886 this.extensionObject_[fieldNumber] = goog.array.map( 1037 this.extensionObject_[fieldNumber] = goog.array.map(
887 /** @type {Array<jspb.Message>} */ (value), function(msg) { 1038 /** @type {Array<jspb.Message>} */ (value), function(msg) {
888 return msg.toArray(); 1039 return msg.toArray();
889 }); 1040 });
890 } else { 1041 } else {
891 this.extensionObject_[fieldNumber] = value; 1042 this.extensionObject_[fieldNumber] = value;
892 } 1043 }
893 } else { 1044 } else {
894 if (fieldInfo.ctor) { 1045 if (fieldInfo.isMessageType()) {
895 this.wrappers_[fieldNumber] = value; 1046 this.wrappers_[fieldNumber] = value;
896 this.extensionObject_[fieldNumber] = value ? value.toArray() : value; 1047 this.extensionObject_[fieldNumber] = value ? value.toArray() : value;
897 } else { 1048 } else {
898 this.extensionObject_[fieldNumber] = value; 1049 this.extensionObject_[fieldNumber] = value;
899 } 1050 }
900 } 1051 }
901 }; 1052 };
902 1053
903 1054
904 /** 1055 /**
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 * @return {boolean} true if both messages are null/undefined, or if both are 1102 * @return {boolean} true if both messages are null/undefined, or if both are
952 * of the same type and have the same field values. 1103 * of the same type and have the same field values.
953 */ 1104 */
954 jspb.Message.equals = function(m1, m2) { 1105 jspb.Message.equals = function(m1, m2) {
955 return m1 == m2 || (!!(m1 && m2) && (m1 instanceof m2.constructor) && 1106 return m1 == m2 || (!!(m1 && m2) && (m1 instanceof m2.constructor) &&
956 jspb.Message.compareFields(m1.toArray(), m2.toArray())); 1107 jspb.Message.compareFields(m1.toArray(), m2.toArray()));
957 }; 1108 };
958 1109
959 1110
960 /** 1111 /**
1112 * Compares two message extension fields recursively.
1113 * @param {!Object} extension1 The first field.
1114 * @param {!Object} extension2 The second field.
1115 * @return {boolean} true if the extensions are null/undefined, or otherwise
1116 * equal.
1117 */
1118 jspb.Message.compareExtensions = function(extension1, extension2) {
1119 extension1 = extension1 || {};
1120 extension2 = extension2 || {};
1121
1122 var keys = {};
1123 for (var name in extension1) {
1124 keys[name] = 0;
1125 }
1126 for (var name in extension2) {
1127 keys[name] = 0;
1128 }
1129 for (name in keys) {
1130 if (!jspb.Message.compareFields(extension1[name], extension2[name])) {
1131 return false;
1132 }
1133 }
1134 return true;
1135 };
1136
1137
1138 /**
961 * Compares two message fields recursively. 1139 * Compares two message fields recursively.
962 * @param {*} field1 The first field. 1140 * @param {*} field1 The first field.
963 * @param {*} field2 The second field. 1141 * @param {*} field2 The second field.
964 * @return {boolean} true if the fields are null/undefined, or otherwise equal. 1142 * @return {boolean} true if the fields are null/undefined, or otherwise equal.
965 */ 1143 */
966 jspb.Message.compareFields = function(field1, field2) { 1144 jspb.Message.compareFields = function(field1, field2) {
967 if (goog.isObject(field1) && goog.isObject(field2)) { 1145 // If the fields are trivially equal, they're equal.
968 var keys = {}, name, extensionObject1, extensionObject2; 1146 if (field1 == field2) return true;
969 for (name in field1) { 1147
970 field1.hasOwnProperty(name) && (keys[name] = 0); 1148 // If the fields aren't trivially equal and one of them isn't an object,
1149 // they can't possibly be equal.
1150 if (!goog.isObject(field1) || !goog.isObject(field2)) {
1151 return false;
1152 }
1153
1154 // We have two objects. If they're different types, they're not equal.
1155 field1 = /** @type {!Object} */(field1);
1156 field2 = /** @type {!Object} */(field2);
1157 if (field1.constructor != field2.constructor) return false;
1158
1159 // If both are Uint8Arrays, compare them element-by-element.
1160 if (jspb.Message.SUPPORTS_UINT8ARRAY_ && field1.constructor === Uint8Array) {
1161 var bytes1 = /** @type {!Uint8Array} */(field1);
1162 var bytes2 = /** @type {!Uint8Array} */(field2);
1163 if (bytes1.length != bytes2.length) return false;
1164 for (var i = 0; i < bytes1.length; i++) {
1165 if (bytes1[i] != bytes2[i]) return false;
971 } 1166 }
972 for (name in field2) { 1167 return true;
973 field2.hasOwnProperty(name) && (keys[name] = 0); 1168 }
974 } 1169
975 for (name in keys) { 1170 // If they're both Arrays, compare them element by element except for the
976 var val1 = field1[name], val2 = field2[name]; 1171 // optional extension objects at the end, which we compare separately.
977 if (goog.isObject(val1) && !goog.isArray(val1)) { 1172 if (field1.constructor === Array) {
978 if (extensionObject1 !== undefined) { 1173 var extension1 = undefined;
979 throw new Error('invalid jspb state'); 1174 var extension2 = undefined;
980 } 1175
981 extensionObject1 = goog.object.isEmpty(val1) ? undefined : val1; 1176 var length = Math.max(field1.length, field2.length);
1177 for (var i = 0; i < length; i++) {
1178 var val1 = field1[i];
1179 var val2 = field2[i];
1180
1181 if (val1 && (val1.constructor == Object)) {
1182 goog.asserts.assert(extension1 === undefined);
1183 goog.asserts.assert(i === field1.length - 1);
1184 extension1 = val1;
982 val1 = undefined; 1185 val1 = undefined;
983 } 1186 }
984 if (goog.isObject(val2) && !goog.isArray(val2)) { 1187
985 if (extensionObject2 !== undefined) { 1188 if (val2 && (val2.constructor == Object)) {
986 throw new Error('invalid jspb state'); 1189 goog.asserts.assert(extension2 === undefined);
987 } 1190 goog.asserts.assert(i === field2.length - 1);
988 extensionObject2 = goog.object.isEmpty(val2) ? undefined : val2; 1191 extension2 = val2;
989 val2 = undefined; 1192 val2 = undefined;
990 } 1193 }
1194
991 if (!jspb.Message.compareFields(val1, val2)) { 1195 if (!jspb.Message.compareFields(val1, val2)) {
992 return false; 1196 return false;
993 } 1197 }
994 } 1198 }
995 if (extensionObject1 || extensionObject2) { 1199
996 return jspb.Message.compareFields(extensionObject1, extensionObject2); 1200 if (extension1 || extension2) {
1201 extension1 = extension1 || {};
1202 extension2 = extension2 || {};
1203 return jspb.Message.compareExtensions(extension1, extension2);
997 } 1204 }
1205
998 return true; 1206 return true;
999 } 1207 }
1000 // Primitive fields, null and undefined compare as equal. 1208
1001 // This also forces booleans and 0/1 to compare as equal to ensure 1209 // If they're both plain Objects (i.e. extensions), compare them as
1002 // compatibility with the jspb serializer. 1210 // extensions.
1003 return field1 == field2; 1211 if (field1.constructor === Object) {
1212 return jspb.Message.compareExtensions(field1, field2);
1213 }
1214
1215 throw new Error('Invalid type in JSPB array');
1004 }; 1216 };
1005 1217
1006 1218
1007 /** 1219 /**
1008 * Static clone function. NOTE: A type-safe method called "cloneMessage" exists 1220 * Static clone function. NOTE: A type-safe method called "cloneMessage" exists
1009 * on each generated JsPb class. Do not call this function directly. 1221 * on each generated JsPb class. Do not call this function directly.
1010 * @param {!jspb.Message} msg A message to clone. 1222 * @param {!jspb.Message} msg A message to clone.
1011 * @return {!jspb.Message} A deep clone of the given message. 1223 * @return {!jspb.Message} A deep clone of the given message.
1012 */ 1224 */
1013 jspb.Message.clone = function(msg) { 1225 jspb.Message.clone = function(msg) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 * field number to field info object. This should be considered as a 1328 * field number to field info object. This should be considered as a
1117 * private API. 1329 * private API.
1118 * 1330 *
1119 * This is similar to [jspb class name].extensions object for 1331 * This is similar to [jspb class name].extensions object for
1120 * non-MessageSet. We special case MessageSet so that we do not need 1332 * non-MessageSet. We special case MessageSet so that we do not need
1121 * to goog.require MessageSet from classes that extends MessageSet. 1333 * to goog.require MessageSet from classes that extends MessageSet.
1122 * 1334 *
1123 * @type {!Object.<number, jspb.ExtensionFieldInfo>} 1335 * @type {!Object.<number, jspb.ExtensionFieldInfo>}
1124 */ 1336 */
1125 jspb.Message.messageSetExtensions = {}; 1337 jspb.Message.messageSetExtensions = {};
OLDNEW
« no previous file with comments | « third_party/protobuf/js/jasmine.json ('k') | third_party/protobuf/js/message_test.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698