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

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

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years 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/maps_test.js ('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 16 matching lines...) Expand all
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 /** 31 /**
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.ExtensionFieldBinaryInfo');
37 goog.provide('jspb.ExtensionFieldInfo'); 38 goog.provide('jspb.ExtensionFieldInfo');
38 goog.provide('jspb.Message'); 39 goog.provide('jspb.Message');
39 40
40 goog.require('goog.array'); 41 goog.require('goog.array');
41 goog.require('goog.asserts'); 42 goog.require('goog.asserts');
42 goog.require('goog.crypt.base64'); 43 goog.require('goog.crypt.base64');
43 goog.require('goog.json'); 44 goog.require('goog.json');
45 goog.require('jspb.Map');
44 46
45 // Not needed in compilation units that have no protos with xids. 47 // Not needed in compilation units that have no protos with xids.
46 goog.forwardDeclare('xid.String'); 48 goog.forwardDeclare('xid.String');
47 49
48 50
49 51
50 /** 52 /**
51 * Stores information for a single extension field. 53 * Stores information for a single extension field.
52 * 54 *
53 * For example, an extension field defined like so: 55 * For example, an extension field defined like so:
(...skipping 22 matching lines...) Expand all
76 * always provided. binaryReaderFn and binaryWriterFn are references to the 78 * always provided. binaryReaderFn and binaryWriterFn are references to the
77 * appropriate methods on BinaryReader/BinaryWriter to read/write the value of 79 * appropriate methods on BinaryReader/BinaryWriter to read/write the value of
78 * this extension, and binaryMessageSerializeFn is a reference to the message 80 * this extension, and binaryMessageSerializeFn is a reference to the message
79 * class's .serializeBinary method, if available. 81 * class's .serializeBinary method, if available.
80 * 82 *
81 * @param {number} fieldNumber 83 * @param {number} fieldNumber
82 * @param {Object} fieldName This has the extension field name as a property. 84 * @param {Object} fieldName This has the extension field name as a property.
83 * @param {?function(new: jspb.Message, Array=)} ctor 85 * @param {?function(new: jspb.Message, Array=)} ctor
84 * @param {?function((boolean|undefined),!jspb.Message):!Object} toObjectFn 86 * @param {?function((boolean|undefined),!jspb.Message):!Object} toObjectFn
85 * @param {number} isRepeated 87 * @param {number} isRepeated
86 * @param {?function(number,?)=} opt_binaryReaderFn
87 * @param {?function(number,?)|function(number,?,?,?,?,?)=} opt_binaryWriterFn
88 * @param {?function(?,?)=} opt_binaryMessageSerializeFn
89 * @param {?function(?,?)=} opt_binaryMessageDeserializeFn
90 * @param {?boolean=} opt_isPacked
91 * @constructor 88 * @constructor
92 * @struct 89 * @struct
93 * @template T 90 * @template T
94 */ 91 */
95 jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn, 92 jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn,
96 isRepeated, opt_binaryReaderFn, opt_binaryWriterFn, 93 isRepeated) {
97 opt_binaryMessageSerializeFn, opt_binaryMessageDeserializeFn,
98 opt_isPacked) {
99 /** @const */ 94 /** @const */
100 this.fieldIndex = fieldNumber; 95 this.fieldIndex = fieldNumber;
101 /** @const */ 96 /** @const */
102 this.fieldName = fieldName; 97 this.fieldName = fieldName;
103 /** @const */ 98 /** @const */
104 this.ctor = ctor; 99 this.ctor = ctor;
105 /** @const */ 100 /** @const */
106 this.toObjectFn = toObjectFn; 101 this.toObjectFn = toObjectFn;
107 /** @const */ 102 /** @const */
108 this.binaryReaderFn = opt_binaryReaderFn; 103 this.isRepeated = isRepeated;
104 };
105
106 /**
107 * Stores binary-related information for a single extension field.
108 * @param {!jspb.ExtensionFieldInfo<T>} fieldInfo
109 * @param {!function(number,?)} binaryReaderFn
110 * @param {!function(number,?)|function(number,?,?,?,?,?)} binaryWriterFn
111 * @param {function(?,?)=} opt_binaryMessageSerializeFn
112 * @param {function(?,?)=} opt_binaryMessageDeserializeFn
113 * @param {boolean=} opt_isPacked
114 * @constructor
115 * @struct
116 * @template T
117 */
118 jspb.ExtensionFieldBinaryInfo = function(fieldInfo, binaryReaderFn, binaryWriter Fn,
119 opt_binaryMessageSerializeFn, opt_binaryMessageDeserializeFn, opt_isPacked) {
109 /** @const */ 120 /** @const */
110 this.binaryWriterFn = opt_binaryWriterFn; 121 this.fieldInfo = fieldInfo;
122 /** @const */
123 this.binaryReaderFn = binaryReaderFn;
124 /** @const */
125 this.binaryWriterFn = binaryWriterFn;
111 /** @const */ 126 /** @const */
112 this.binaryMessageSerializeFn = opt_binaryMessageSerializeFn; 127 this.binaryMessageSerializeFn = opt_binaryMessageSerializeFn;
113 /** @const */ 128 /** @const */
114 this.binaryMessageDeserializeFn = opt_binaryMessageDeserializeFn; 129 this.binaryMessageDeserializeFn = opt_binaryMessageDeserializeFn;
115 /** @const */ 130 /** @const */
116 this.isRepeated = isRepeated;
117 /** @const */
118 this.isPacked = opt_isPacked; 131 this.isPacked = opt_isPacked;
119 }; 132 };
120 133
121
122 /** 134 /**
123 * @return {boolean} Does this field represent a sub Message? 135 * @return {boolean} Does this field represent a sub Message?
124 */ 136 */
125 jspb.ExtensionFieldInfo.prototype.isMessageType = function() { 137 jspb.ExtensionFieldInfo.prototype.isMessageType = function() {
126 return !!this.ctor; 138 return !!this.ctor;
127 }; 139 };
128 140
129 141
130 /** 142 /**
131 * Base class for all JsPb messages. 143 * Base class for all JsPb messages.
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 */ 376 */
365 jspb.Message.materializeExtensionObject_ = function(msg, suggestedPivot) { 377 jspb.Message.materializeExtensionObject_ = function(msg, suggestedPivot) {
366 if (msg.array.length) { 378 if (msg.array.length) {
367 var foundIndex = msg.array.length - 1; 379 var foundIndex = msg.array.length - 1;
368 var obj = msg.array[foundIndex]; 380 var obj = msg.array[foundIndex];
369 // Normal fields are never objects, so we can be sure that if we find an 381 // Normal fields are never objects, so we can be sure that if we find an
370 // object here, then it's the extension object. However, we must ensure that 382 // object here, then it's the extension object. However, we must ensure that
371 // the object is not an array, since arrays are valid field values. 383 // the object is not an array, since arrays are valid field values.
372 // NOTE(lukestebbing): We avoid looking at .length to avoid a JIT bug 384 // NOTE(lukestebbing): We avoid looking at .length to avoid a JIT bug
373 // in Safari on iOS 8. See the description of CL/86511464 for details. 385 // in Safari on iOS 8. See the description of CL/86511464 for details.
374 if (obj && typeof obj == 'object' && !goog.isArray(obj)) { 386 if (obj && typeof obj == 'object' && !goog.isArray(obj) &&
387 !(jspb.Message.SUPPORTS_UINT8ARRAY_ && obj instanceof Uint8Array)) {
375 msg.pivot_ = foundIndex - msg.arrayIndexOffset_; 388 msg.pivot_ = foundIndex - msg.arrayIndexOffset_;
376 msg.extensionObject_ = obj; 389 msg.extensionObject_ = obj;
377 return; 390 return;
378 } 391 }
379 } 392 }
380 // This complexity exists because we keep all extension fields in the 393 // This complexity exists because we keep all extension fields in the
381 // extensionObject_ regardless of proto field number. Changing this would 394 // extensionObject_ regardless of proto field number. Changing this would
382 // simplify the code here, but it would require changing the serialization 395 // simplify the code here, but it would require changing the serialization
383 // format from the server, which is not backwards compatible. 396 // format from the server, which is not backwards compatible.
384 // TODO(jshneier): Should we just treat extension fields the same as 397 // TODO(jshneier): Should we just treat extension fields the same as
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 * Writes a proto's extension data to a binary-format output stream. 495 * Writes a proto's extension data to a binary-format output stream.
483 * @param {!jspb.Message} proto The proto whose extensions to convert. 496 * @param {!jspb.Message} proto The proto whose extensions to convert.
484 * @param {*} writer The binary-format writer to write to. 497 * @param {*} writer The binary-format writer to write to.
485 * @param {!Object} extensions The proto class' registered extensions. 498 * @param {!Object} extensions The proto class' registered extensions.
486 * @param {function(jspb.ExtensionFieldInfo) : *} getExtensionFn The proto 499 * @param {function(jspb.ExtensionFieldInfo) : *} getExtensionFn The proto
487 * class' getExtension function. Passed for effective dead code removal. 500 * class' getExtension function. Passed for effective dead code removal.
488 */ 501 */
489 jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions, 502 jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
490 getExtensionFn) { 503 getExtensionFn) {
491 for (var fieldNumber in extensions) { 504 for (var fieldNumber in extensions) {
492 var fieldInfo = extensions[fieldNumber]; 505 var binaryFieldInfo = extensions[fieldNumber];
506 var fieldInfo = binaryFieldInfo.fieldInfo;
507
493 // The old codegen doesn't add the extra fields to ExtensionFieldInfo, so we 508 // The old codegen doesn't add the extra fields to ExtensionFieldInfo, so we
494 // need to gracefully error-out here rather than produce a null dereference 509 // need to gracefully error-out here rather than produce a null dereference
495 // below. 510 // below.
496 if (!fieldInfo.binaryWriterFn) { 511 if (!binaryFieldInfo.binaryWriterFn) {
497 throw new Error('Message extension present that was generated ' + 512 throw new Error('Message extension present that was generated ' +
498 'without binary serialization support'); 513 'without binary serialization support');
499 } 514 }
500 var value = getExtensionFn.call(proto, fieldInfo); 515 var value = getExtensionFn.call(proto, fieldInfo);
501 if (value) { 516 if (value) {
502 if (fieldInfo.isMessageType()) { 517 if (fieldInfo.isMessageType()) {
503 // If the message type of the extension was generated without binary 518 // If the message type of the extension was generated without binary
504 // support, there may not be a binary message serializer function, and 519 // support, there may not be a binary message serializer function, and
505 // we can't know when we codegen the extending message that the extended 520 // we can't know when we codegen the extending message that the extended
506 // message may require binary support, so we can *only* catch this error 521 // message may require binary support, so we can *only* catch this error
507 // here, at runtime (and this decoupled codegen is the whole point of 522 // here, at runtime (and this decoupled codegen is the whole point of
508 // extensions!). 523 // extensions!).
509 if (fieldInfo.binaryMessageSerializeFn) { 524 if (binaryFieldInfo.binaryMessageSerializeFn) {
510 fieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex, 525 binaryFieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex,
511 value, fieldInfo.binaryMessageSerializeFn); 526 value, binaryFieldInfo.binaryMessageSerializeFn);
512 } else { 527 } else {
513 throw new Error('Message extension present holding submessage ' + 528 throw new Error('Message extension present holding submessage ' +
514 'without binary support enabled, and message is ' + 529 'without binary support enabled, and message is ' +
515 'being serialized to binary format'); 530 'being serialized to binary format');
516 } 531 }
517 } else { 532 } else {
518 fieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex, value); 533 binaryFieldInfo.binaryWriterFn.call(
534 writer, fieldInfo.fieldIndex, value);
519 } 535 }
520 } 536 }
521 } 537 }
522 }; 538 };
523 539
524 540
525 /** 541 /**
526 * Reads an extension field from the given reader and, if a valid extension, 542 * Reads an extension field from the given reader and, if a valid extension,
527 * sets the extension value. 543 * sets the extension value.
528 * @param {!jspb.Message} msg A jspb proto. 544 * @param {!jspb.Message} msg A jspb proto.
529 * @param {{skipField:function(),getFieldNumber:function():number}} reader 545 * @param {{skipField:function(),getFieldNumber:function():number}} reader
530 * @param {!Object} extensions The extensions object. 546 * @param {!Object} extensions The extensions object.
531 * @param {function(jspb.ExtensionFieldInfo)} getExtensionFn 547 * @param {function(jspb.ExtensionFieldInfo)} getExtensionFn
532 * @param {function(jspb.ExtensionFieldInfo, ?)} setExtensionFn 548 * @param {function(jspb.ExtensionFieldInfo, ?)} setExtensionFn
533 */ 549 */
534 jspb.Message.readBinaryExtension = function(msg, reader, extensions, 550 jspb.Message.readBinaryExtension = function(msg, reader, extensions,
535 getExtensionFn, setExtensionFn) { 551 getExtensionFn, setExtensionFn) {
536 var fieldInfo = extensions[reader.getFieldNumber()]; 552 var binaryFieldInfo = extensions[reader.getFieldNumber()];
537 if (!fieldInfo) { 553 if (!binaryFieldInfo) {
538 reader.skipField(); 554 reader.skipField();
539 return; 555 return;
540 } 556 }
541 if (!fieldInfo.binaryReaderFn) { 557 var fieldInfo = binaryFieldInfo.fieldInfo;
558 if (!binaryFieldInfo.binaryReaderFn) {
542 throw new Error('Deserializing extension whose generated code does not ' + 559 throw new Error('Deserializing extension whose generated code does not ' +
543 'support binary format'); 560 'support binary format');
544 } 561 }
545 562
546 var value; 563 var value;
547 if (fieldInfo.isMessageType()) { 564 if (fieldInfo.isMessageType()) {
548 value = new fieldInfo.ctor(); 565 value = new fieldInfo.ctor();
549 fieldInfo.binaryReaderFn.call( 566 binaryFieldInfo.binaryReaderFn.call(
550 reader, value, fieldInfo.binaryMessageDeserializeFn); 567 reader, value, binaryFieldInfo.binaryMessageDeserializeFn);
551 } else { 568 } else {
552 // All other types. 569 // All other types.
553 value = fieldInfo.binaryReaderFn.call(reader); 570 value = binaryFieldInfo.binaryReaderFn.call(reader);
554 } 571 }
555 572
556 if (fieldInfo.isRepeated && !fieldInfo.isPacked) { 573 if (fieldInfo.isRepeated && !binaryFieldInfo.isPacked) {
557 var currentList = getExtensionFn.call(msg, fieldInfo); 574 var currentList = getExtensionFn.call(msg, fieldInfo);
558 if (!currentList) { 575 if (!currentList) {
559 setExtensionFn.call(msg, fieldInfo, [value]); 576 setExtensionFn.call(msg, fieldInfo, [value]);
560 } else { 577 } else {
561 currentList.push(value); 578 currentList.push(value);
562 } 579 }
563 } else { 580 } else {
564 setExtensionFn.call(msg, fieldInfo, value); 581 setExtensionFn.call(msg, fieldInfo, value);
565 } 582 }
566 }; 583 };
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 * Gets the value of a non-extension primitive field, with proto3 (non-nullable 737 * Gets the value of a non-extension primitive field, with proto3 (non-nullable
721 * primitives) semantics. Returns `defaultValue` if the field is not otherwise 738 * primitives) semantics. Returns `defaultValue` if the field is not otherwise
722 * set. 739 * set.
723 * @template T 740 * @template T
724 * @param {!jspb.Message} msg A jspb proto. 741 * @param {!jspb.Message} msg A jspb proto.
725 * @param {number} fieldNumber The field number. 742 * @param {number} fieldNumber The field number.
726 * @param {T} defaultValue The default value. 743 * @param {T} defaultValue The default value.
727 * @return {T} The field's value. 744 * @return {T} The field's value.
728 * @protected 745 * @protected
729 */ 746 */
730 jspb.Message.getFieldProto3 = function(msg, fieldNumber, defaultValue) { 747 jspb.Message.getFieldWithDefault = function(msg, fieldNumber, defaultValue) {
731 var value = jspb.Message.getField(msg, fieldNumber); 748 var value = jspb.Message.getField(msg, fieldNumber);
732 if (value == null) { 749 if (value == null) {
733 return defaultValue; 750 return defaultValue;
734 } else { 751 } else {
735 return value; 752 return value;
736 } 753 }
737 }; 754 };
738 755
739 756
740 /** 757 /**
758 * Alias for getFieldWithDefault used by older generated code.
759 * @template T
760 * @param {!jspb.Message} msg A jspb proto.
761 * @param {number} fieldNumber The field number.
762 * @param {T} defaultValue The default value.
763 * @return {T} The field's value.
764 * @protected
765 */
766 jspb.Message.getFieldProto3 = jspb.Message.getFieldWithDefault;
767
768
769 /**
770 * Gets the value of a map field, lazily creating the map container if
771 * necessary.
772 *
773 * This should only be called from generated code, because it requires knowledge
774 * of serialization/parsing callbacks (which are required by the map at
775 * construction time, and the map may be constructed here).
776 *
777 * @template K, V
778 * @param {!jspb.Message} msg
779 * @param {number} fieldNumber
780 * @param {boolean|undefined} noLazyCreate
781 * @param {?=} opt_valueCtor
782 * @return {!jspb.Map<K, V>|undefined}
783 * @protected
784 */
785 jspb.Message.getMapField = function(msg, fieldNumber, noLazyCreate,
786 opt_valueCtor) {
787 if (!msg.wrappers_) {
788 msg.wrappers_ = {};
789 }
790 // If we already have a map in the map wrappers, return that.
791 if (fieldNumber in msg.wrappers_) {
792 return msg.wrappers_[fieldNumber];
793 } else if (noLazyCreate) {
794 return undefined;
795 } else {
796 // Wrap the underlying elements array with a Map.
797 var arr = jspb.Message.getField(msg, fieldNumber);
798 if (!arr) {
799 arr = [];
800 jspb.Message.setField(msg, fieldNumber, arr);
801 }
802 return msg.wrappers_[fieldNumber] =
803 new jspb.Map(
804 /** @type {!Array<!Array<!Object>>} */ (arr), opt_valueCtor);
805 }
806 };
807
808
809 /**
741 * Sets the value of a non-extension field. 810 * Sets the value of a non-extension field.
742 * @param {!jspb.Message} msg A jspb proto. 811 * @param {!jspb.Message} msg A jspb proto.
743 * @param {number} fieldNumber The field number. 812 * @param {number} fieldNumber The field number.
744 * @param {string|number|boolean|Uint8Array|Array|undefined} value New value 813 * @param {string|number|boolean|Uint8Array|Array|undefined} value New value
745 * @protected 814 * @protected
746 */ 815 */
747 jspb.Message.setField = function(msg, fieldNumber, value) { 816 jspb.Message.setField = function(msg, fieldNumber, value) {
748 if (fieldNumber < msg.pivot_) { 817 if (fieldNumber < msg.pivot_) {
749 msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = value; 818 msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = value;
750 } else { 819 } else {
751 msg.extensionObject_[fieldNumber] = value; 820 msg.extensionObject_[fieldNumber] = value;
752 } 821 }
753 }; 822 };
754 823
755 824
756 /** 825 /**
826 * Adds a value to a repeated, primitive field.
827 * @param {!jspb.Message} msg A jspb proto.
828 * @param {number} fieldNumber The field number.
829 * @param {string|number|boolean|!Uint8Array} value New value
830 * @param {number=} opt_index Index where to put new value.
831 * @protected
832 */
833 jspb.Message.addToRepeatedField = function(msg, fieldNumber, value, opt_index) {
834 var arr = jspb.Message.getField(msg, fieldNumber);
835 if (opt_index != undefined) {
836 arr.splice(opt_index, 0, value);
837 } else {
838 arr.push(value);
839 }
840 };
841
842
843 /**
757 * Sets the value of a field in a oneof union and clears all other fields in 844 * Sets the value of a field in a oneof union and clears all other fields in
758 * the union. 845 * the union.
759 * @param {!jspb.Message} msg A jspb proto. 846 * @param {!jspb.Message} msg A jspb proto.
760 * @param {number} fieldNumber The field number. 847 * @param {number} fieldNumber The field number.
761 * @param {!Array<number>} oneof The fields belonging to the union. 848 * @param {!Array<number>} oneof The fields belonging to the union.
762 * @param {string|number|boolean|Uint8Array|Array|undefined} value New value 849 * @param {string|number|boolean|Uint8Array|Array|undefined} value New value
763 * @protected 850 * @protected
764 */ 851 */
765 jspb.Message.setOneofField = function(msg, fieldNumber, oneof, value) { 852 jspb.Message.setOneofField = function(msg, fieldNumber, oneof, value) {
766 var currentCase = jspb.Message.computeOneofCase(msg, oneof); 853 var currentCase = jspb.Message.computeOneofCase(msg, oneof);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 930
844 /** 931 /**
845 * Gets and wraps a repeated proto field on access. 932 * Gets and wraps a repeated proto field on access.
846 * @param {!jspb.Message} msg A jspb proto. 933 * @param {!jspb.Message} msg A jspb proto.
847 * @param {function(new:jspb.Message, Array)} ctor Constructor for the field. 934 * @param {function(new:jspb.Message, Array)} ctor Constructor for the field.
848 * @param {number} fieldNumber The field number. 935 * @param {number} fieldNumber The field number.
849 * @return {Array<!jspb.Message>} The repeated field as an array of protos. 936 * @return {Array<!jspb.Message>} The repeated field as an array of protos.
850 * @protected 937 * @protected
851 */ 938 */
852 jspb.Message.getRepeatedWrapperField = function(msg, ctor, fieldNumber) { 939 jspb.Message.getRepeatedWrapperField = function(msg, ctor, fieldNumber) {
940 jspb.Message.wrapRepeatedField_(msg, ctor, fieldNumber);
941 var val = msg.wrappers_[fieldNumber];
942 if (val == jspb.Message.EMPTY_LIST_SENTINEL_) {
943 val = msg.wrappers_[fieldNumber] = [];
944 }
945 return /** @type {!Array<!jspb.Message>} */ (val);
946 };
947
948
949 /**
950 * Wraps underlying array into proto message representation if it wasn't done
951 * before.
952 * @param {!jspb.Message} msg A jspb proto.
953 * @param {function(new:jspb.Message, ?Array)} ctor Constructor for the field.
954 * @param {number} fieldNumber The field number.
955 * @private
956 */
957 jspb.Message.wrapRepeatedField_ = function(msg, ctor, fieldNumber) {
853 if (!msg.wrappers_) { 958 if (!msg.wrappers_) {
854 msg.wrappers_ = {}; 959 msg.wrappers_ = {};
855 } 960 }
856 if (!msg.wrappers_[fieldNumber]) { 961 if (!msg.wrappers_[fieldNumber]) {
857 var data = jspb.Message.getField(msg, fieldNumber); 962 var data = jspb.Message.getField(msg, fieldNumber);
858 for (var wrappers = [], i = 0; i < data.length; i++) { 963 for (var wrappers = [], i = 0; i < data.length; i++) {
859 wrappers[i] = new ctor(data[i]); 964 wrappers[i] = new ctor(data[i]);
860 } 965 }
861 msg.wrappers_[fieldNumber] = wrappers; 966 msg.wrappers_[fieldNumber] = wrappers;
862 } 967 }
863 var val = msg.wrappers_[fieldNumber];
864 if (val == jspb.Message.EMPTY_LIST_SENTINEL_) {
865 val = msg.wrappers_[fieldNumber] = [];
866 }
867 return /** @type {Array<!jspb.Message>} */ (val);
868 }; 968 };
869 969
870 970
871 /** 971 /**
872 * Sets a proto field and syncs it to the backing array. 972 * Sets a proto field and syncs it to the backing array.
873 * @param {!jspb.Message} msg A jspb proto. 973 * @param {!jspb.Message} msg A jspb proto.
874 * @param {number} fieldNumber The field number. 974 * @param {number} fieldNumber The field number.
875 * @param {jspb.Message|undefined} value A new value for this proto field. 975 * @param {?jspb.Message|?jspb.Map|undefined} value A new value for this proto
976 * field.
876 * @protected 977 * @protected
877 */ 978 */
878 jspb.Message.setWrapperField = function(msg, fieldNumber, value) { 979 jspb.Message.setWrapperField = function(msg, fieldNumber, value) {
879 if (!msg.wrappers_) { 980 if (!msg.wrappers_) {
880 msg.wrappers_ = {}; 981 msg.wrappers_ = {};
881 } 982 }
882 var data = value ? value.toArray() : value; 983 var data = value ? value.toArray() : value;
883 msg.wrappers_[fieldNumber] = value; 984 msg.wrappers_[fieldNumber] = value;
884 jspb.Message.setField(msg, fieldNumber, data); 985 jspb.Message.setField(msg, fieldNumber, data);
885 }; 986 };
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 value = value || []; 1018 value = value || [];
918 for (var data = [], i = 0; i < value.length; i++) { 1019 for (var data = [], i = 0; i < value.length; i++) {
919 data[i] = value[i].toArray(); 1020 data[i] = value[i].toArray();
920 } 1021 }
921 msg.wrappers_[fieldNumber] = value; 1022 msg.wrappers_[fieldNumber] = value;
922 jspb.Message.setField(msg, fieldNumber, data); 1023 jspb.Message.setField(msg, fieldNumber, data);
923 }; 1024 };
924 1025
925 1026
926 /** 1027 /**
1028 * Add a message to a repeated proto field.
1029 * @param {!jspb.Message} msg A jspb proto.
1030 * @param {number} fieldNumber The field number.
1031 * @param {T_CHILD|undefined} value Proto that will be added to the
1032 * repeated field.
1033 * @param {function(new:T_CHILD, ?Array=)} ctor The constructor of the
1034 * message type.
1035 * @param {number|undefined} index Index at which to insert the value.
1036 * @return {T_CHILD_NOT_UNDEFINED} proto that was inserted to the repeated field
1037 * @template MessageType
1038 * Use go/closure-ttl to declare a non-undefined version of T_CHILD. Replace the
1039 * undefined in blah|undefined with none. This is necessary because the compiler
1040 * will infer T_CHILD to be |undefined.
1041 * @template T_CHILD
1042 * @template T_CHILD_NOT_UNDEFINED :=
1043 * cond(isUnknown(T_CHILD), unknown(),
1044 * mapunion(T_CHILD, (X) =>
1045 * cond(eq(X, 'undefined'), none(), X)))
1046 * =:
1047 * @protected
1048 */
1049 jspb.Message.addToRepeatedWrapperField = function(
1050 msg, fieldNumber, value, ctor, index) {
1051 jspb.Message.wrapRepeatedField_(msg, ctor, fieldNumber);
1052 var wrapperArray = msg.wrappers_[fieldNumber];
1053 if (!wrapperArray) {
1054 wrapperArray = msg.wrappers_[fieldNumber] = [];
1055 }
1056 var insertedValue = value ? value : new ctor();
1057 var array = jspb.Message.getField(msg, fieldNumber);
1058 if (index != undefined) {
1059 wrapperArray.splice(index, 0, insertedValue);
1060 array.splice(index, 0, insertedValue.toArray());
1061 } else {
1062 wrapperArray.push(insertedValue);
1063 array.push(insertedValue.toArray());
1064 }
1065 return insertedValue;
1066 };
1067
1068
1069 /**
927 * Converts a JsPb repeated message field into a map. The map will contain 1070 * Converts a JsPb repeated message field into a map. The map will contain
928 * protos unless an optional toObject function is given, in which case it will 1071 * protos unless an optional toObject function is given, in which case it will
929 * contain objects suitable for Soy rendering. 1072 * contain objects suitable for Soy rendering.
930 * @param {!Array<T>} field The repeated message field to be 1073 * @param {!Array<T>} field The repeated message field to be
931 * converted. 1074 * converted.
932 * @param {function() : string?} mapKeyGetterFn The function to get the key of 1075 * @param {function() : string?} mapKeyGetterFn The function to get the key of
933 * the map. 1076 * the map.
934 * @param {?function(boolean=): Object| 1077 * @param {?function(boolean=): Object|
935 * function((boolean|undefined),T): Object} opt_toObjectFn The 1078 * function((boolean|undefined),T): Object} opt_toObjectFn The
936 * toObject function for this field. We need to pass this for effective 1079 * toObject function for this field. We need to pass this for effective
937 * dead code removal. 1080 * dead code removal.
938 * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 1081 * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
939 * for transitional soy proto support: http://goto/soy-param-migration 1082 * for transitional soy proto support: http://goto/soy-param-migration
940 * @return {!Object.<string, Object>} A map of proto or Soy objects. 1083 * @return {!Object.<string, Object>} A map of proto or Soy objects.
941 * @template T 1084 * @template T
942 */ 1085 */
943 jspb.Message.toMap = function( 1086 jspb.Message.toMap = function(
944 field, mapKeyGetterFn, opt_toObjectFn, opt_includeInstance) { 1087 field, mapKeyGetterFn, opt_toObjectFn, opt_includeInstance) {
945 var result = {}; 1088 var result = {};
946 for (var i = 0; i < field.length; i++) { 1089 for (var i = 0; i < field.length; i++) {
947 result[mapKeyGetterFn.call(field[i])] = opt_toObjectFn ? 1090 result[mapKeyGetterFn.call(field[i])] = opt_toObjectFn ?
948 opt_toObjectFn.call(field[i], opt_includeInstance, 1091 opt_toObjectFn.call(field[i], opt_includeInstance,
949 /** @type {!jspb.Message} */ (field[i])) : field[i]; 1092 /** @type {!jspb.Message} */ (field[i])) : field[i];
950 } 1093 }
951 return result; 1094 return result;
952 }; 1095 };
953 1096
954 1097
955 /** 1098 /**
1099 * Syncs all map fields' contents back to their underlying arrays.
1100 * @private
1101 */
1102 jspb.Message.prototype.syncMapFields_ = function() {
1103 // This iterates over submessage, map, and repeated fields, which is intended.
1104 // Submessages can contain maps which also need to be synced.
1105 //
1106 // There is a lot of opportunity for optimization here. For example we could
1107 // statically determine that some messages have no submessages with maps and
1108 // optimize this method away for those just by generating one extra static
1109 // boolean per message type.
1110 if (this.wrappers_) {
1111 for (var fieldNumber in this.wrappers_) {
1112 var val = this.wrappers_[fieldNumber];
1113 if (goog.isArray(val)) {
1114 for (var i = 0; i < val.length; i++) {
1115 if (val[i]) {
1116 val[i].toArray();
1117 }
1118 }
1119 } else {
1120 // Works for submessages and maps.
1121 if (val) {
1122 val.toArray();
1123 }
1124 }
1125 }
1126 }
1127 };
1128
1129
1130 /**
956 * Returns the internal array of this proto. 1131 * Returns the internal array of this proto.
957 * <p>Note: If you use this array to construct a second proto, the content 1132 * <p>Note: If you use this array to construct a second proto, the content
958 * would then be partially shared between the two protos. 1133 * would then be partially shared between the two protos.
959 * @return {!Array} The proto represented as an array. 1134 * @return {!Array} The proto represented as an array.
960 */ 1135 */
961 jspb.Message.prototype.toArray = function() { 1136 jspb.Message.prototype.toArray = function() {
1137 this.syncMapFields_();
962 return this.array; 1138 return this.array;
963 }; 1139 };
964 1140
965 1141
966 1142
967 1143
968 /** 1144 /**
969 * Creates a string representation of the internal data array of this proto. 1145 * Creates a string representation of the internal data array of this proto.
970 * <p>NOTE: This string is *not* suitable for use in server requests. 1146 * <p>NOTE: This string is *not* suitable for use in server requests.
971 * @return {string} A string representation of this proto. 1147 * @return {string} A string representation of this proto.
972 * @override 1148 * @override
973 */ 1149 */
974 jspb.Message.prototype.toString = function() { 1150 jspb.Message.prototype.toString = function() {
1151 this.syncMapFields_();
975 return this.array.toString(); 1152 return this.array.toString();
976 }; 1153 };
977 1154
978 1155
979 /** 1156 /**
980 * Gets the value of the extension field from the extended object. 1157 * Gets the value of the extension field from the extended object.
981 * @param {jspb.ExtensionFieldInfo.<T>} fieldInfo Specifies the field to get. 1158 * @param {jspb.ExtensionFieldInfo.<T>} fieldInfo Specifies the field to get.
982 * @return {T} The value of the field. 1159 * @return {T} The value of the field.
983 * @template T 1160 * @template T
984 */ 1161 */
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 } 1193 }
1017 } 1194 }
1018 }; 1195 };
1019 1196
1020 1197
1021 /** 1198 /**
1022 * Sets the value of the extension field in the extended object. 1199 * Sets the value of the extension field in the extended object.
1023 * @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to set. 1200 * @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to set.
1024 * @param {jspb.Message|string|Uint8Array|number|boolean|Array?} value The value 1201 * @param {jspb.Message|string|Uint8Array|number|boolean|Array?} value The value
1025 * to set. 1202 * to set.
1203 * @return {THIS} For chaining
1204 * @this {THIS}
1205 * @template THIS
1026 */ 1206 */
1027 jspb.Message.prototype.setExtension = function(fieldInfo, value) { 1207 jspb.Message.prototype.setExtension = function(fieldInfo, value) {
1028 if (!this.wrappers_) { 1208 // Cast self, since the inferred THIS is unknown inside the function body.
1029 this.wrappers_ = {}; 1209 // https://github.com/google/closure-compiler/issues/1411#issuecomment-2324422 20
1210 var self = /** @type {!jspb.Message} */ (this);
1211 if (!self.wrappers_) {
1212 self.wrappers_ = {};
1030 } 1213 }
1031 jspb.Message.maybeInitEmptyExtensionObject_(this); 1214 jspb.Message.maybeInitEmptyExtensionObject_(self);
1032 var fieldNumber = fieldInfo.fieldIndex; 1215 var fieldNumber = fieldInfo.fieldIndex;
1033 if (fieldInfo.isRepeated) { 1216 if (fieldInfo.isRepeated) {
1034 value = value || []; 1217 value = value || [];
1035 if (fieldInfo.isMessageType()) { 1218 if (fieldInfo.isMessageType()) {
1036 this.wrappers_[fieldNumber] = value; 1219 self.wrappers_[fieldNumber] = value;
1037 this.extensionObject_[fieldNumber] = goog.array.map( 1220 self.extensionObject_[fieldNumber] = goog.array.map(
1038 /** @type {Array<jspb.Message>} */ (value), function(msg) { 1221 /** @type {Array<jspb.Message>} */ (value), function(msg) {
1039 return msg.toArray(); 1222 return msg.toArray();
1040 }); 1223 });
1041 } else { 1224 } else {
1042 this.extensionObject_[fieldNumber] = value; 1225 self.extensionObject_[fieldNumber] = value;
1043 } 1226 }
1044 } else { 1227 } else {
1045 if (fieldInfo.isMessageType()) { 1228 if (fieldInfo.isMessageType()) {
1046 this.wrappers_[fieldNumber] = value; 1229 self.wrappers_[fieldNumber] = value;
1047 this.extensionObject_[fieldNumber] = value ? value.toArray() : value; 1230 self.extensionObject_[fieldNumber] = value ? value.toArray() : value;
1048 } else { 1231 } else {
1049 this.extensionObject_[fieldNumber] = value; 1232 self.extensionObject_[fieldNumber] = value;
1050 } 1233 }
1051 } 1234 }
1235 return self;
1052 }; 1236 };
1053 1237
1054 1238
1055 /** 1239 /**
1056 * Creates a difference object between two messages. 1240 * Creates a difference object between two messages.
1057 * 1241 *
1058 * The result will contain the top-level fields of m2 that differ from those of 1242 * The result will contain the top-level fields of m2 that differ from those of
1059 * m1 at any level of nesting. No data is cloned, the result object will 1243 * m1 at any level of nesting. No data is cloned, the result object will
1060 * share its top-level elements with m2 (but not with m1). 1244 * share its top-level elements with m2 (but not with m1).
1061 * 1245 *
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 // extensions. 1394 // extensions.
1211 if (field1.constructor === Object) { 1395 if (field1.constructor === Object) {
1212 return jspb.Message.compareExtensions(field1, field2); 1396 return jspb.Message.compareExtensions(field1, field2);
1213 } 1397 }
1214 1398
1215 throw new Error('Invalid type in JSPB array'); 1399 throw new Error('Invalid type in JSPB array');
1216 }; 1400 };
1217 1401
1218 1402
1219 /** 1403 /**
1220 * Static clone function. NOTE: A type-safe method called "cloneMessage" exists 1404 * Templated, type-safe cloneMessage definition.
1405 * @return {THIS}
1406 * @this {THIS}
1407 * @template THIS
1408 */
1409 jspb.Message.prototype.cloneMessage = function() {
1410 return jspb.Message.cloneMessage(/** @type {!jspb.Message} */ (this));
1411 };
1412
1413 /**
1414 * Alias clone to cloneMessage. goog.object.unsafeClone uses clone to
1415 * efficiently copy objects. Without this alias, copying jspb messages comes
1416 * with a large performance penalty.
1417 * @return {THIS}
1418 * @this {THIS}
1419 * @template THIS
1420 */
1421 jspb.Message.prototype.clone = function() {
1422 return jspb.Message.cloneMessage(/** @type {!jspb.Message} */ (this));
1423 };
1424
1425 /**
1426 * Static clone function. NOTE: A type-safe method called "cloneMessage"
1427 * exists
1221 * on each generated JsPb class. Do not call this function directly. 1428 * on each generated JsPb class. Do not call this function directly.
1222 * @param {!jspb.Message} msg A message to clone. 1429 * @param {!jspb.Message} msg A message to clone.
1223 * @return {!jspb.Message} A deep clone of the given message. 1430 * @return {!jspb.Message} A deep clone of the given message.
1224 */ 1431 */
1225 jspb.Message.clone = function(msg) { 1432 jspb.Message.clone = function(msg) {
1226 // Although we could include the wrappers, we leave them out here. 1433 // Although we could include the wrappers, we leave them out here.
1227 return jspb.Message.cloneMessage(msg); 1434 return jspb.Message.cloneMessage(msg);
1228 }; 1435 };
1229 1436
1230 1437
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1286 // Allocate array of correct size. 1493 // Allocate array of correct size.
1287 var clonedArray = new Array(obj.length); 1494 var clonedArray = new Array(obj.length);
1288 // Use array iteration where possible because it is faster than for-in. 1495 // Use array iteration where possible because it is faster than for-in.
1289 for (var i = 0; i < obj.length; i++) { 1496 for (var i = 0; i < obj.length; i++) {
1290 if ((o = obj[i]) != null) { 1497 if ((o = obj[i]) != null) {
1291 clonedArray[i] = typeof o == 'object' ? jspb.Message.clone_(o) : o; 1498 clonedArray[i] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
1292 } 1499 }
1293 } 1500 }
1294 return clonedArray; 1501 return clonedArray;
1295 } 1502 }
1503 if (jspb.Message.SUPPORTS_UINT8ARRAY_ && obj instanceof Uint8Array) {
1504 return new Uint8Array(obj);
1505 }
1296 var clone = {}; 1506 var clone = {};
1297 for (var key in obj) { 1507 for (var key in obj) {
1298 if ((o = obj[key]) != null) { 1508 if ((o = obj[key]) != null) {
1299 clone[key] = typeof o == 'object' ? jspb.Message.clone_(o) : o; 1509 clone[key] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
1300 } 1510 }
1301 } 1511 }
1302 return clone; 1512 return clone;
1303 }; 1513 };
1304 1514
1305 1515
(...skipping 22 matching lines...) Expand all
1328 * field number to field info object. This should be considered as a 1538 * field number to field info object. This should be considered as a
1329 * private API. 1539 * private API.
1330 * 1540 *
1331 * This is similar to [jspb class name].extensions object for 1541 * This is similar to [jspb class name].extensions object for
1332 * non-MessageSet. We special case MessageSet so that we do not need 1542 * non-MessageSet. We special case MessageSet so that we do not need
1333 * to goog.require MessageSet from classes that extends MessageSet. 1543 * to goog.require MessageSet from classes that extends MessageSet.
1334 * 1544 *
1335 * @type {!Object.<number, jspb.ExtensionFieldInfo>} 1545 * @type {!Object.<number, jspb.ExtensionFieldInfo>}
1336 */ 1546 */
1337 jspb.Message.messageSetExtensions = {}; 1547 jspb.Message.messageSetExtensions = {};
1548 jspb.Message.messageSetExtensionsBinary = {};
OLDNEW
« no previous file with comments | « third_party/protobuf/js/maps_test.js ('k') | third_party/protobuf/js/message_test.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698