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

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

Issue 2590803003: Revert "third_party/protobuf: Update to HEAD (83d681ee2c)" (Closed)
Patch Set: Created 3 years, 12 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/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');
38 goog.provide('jspb.ExtensionFieldInfo'); 37 goog.provide('jspb.ExtensionFieldInfo');
39 goog.provide('jspb.Message'); 38 goog.provide('jspb.Message');
40 39
41 goog.require('goog.array'); 40 goog.require('goog.array');
42 goog.require('goog.asserts'); 41 goog.require('goog.asserts');
43 goog.require('goog.crypt.base64'); 42 goog.require('goog.crypt.base64');
44 goog.require('goog.json'); 43 goog.require('goog.json');
45 goog.require('jspb.Map');
46 44
47 // Not needed in compilation units that have no protos with xids. 45 // Not needed in compilation units that have no protos with xids.
48 goog.forwardDeclare('xid.String'); 46 goog.forwardDeclare('xid.String');
49 47
50 48
51 49
52 /** 50 /**
53 * Stores information for a single extension field. 51 * Stores information for a single extension field.
54 * 52 *
55 * For example, an extension field defined like so: 53 * For example, an extension field defined like so:
(...skipping 22 matching lines...) Expand all
78 * always provided. binaryReaderFn and binaryWriterFn are references to the 76 * always provided. binaryReaderFn and binaryWriterFn are references to the
79 * appropriate methods on BinaryReader/BinaryWriter to read/write the value of 77 * appropriate methods on BinaryReader/BinaryWriter to read/write the value of
80 * this extension, and binaryMessageSerializeFn is a reference to the message 78 * this extension, and binaryMessageSerializeFn is a reference to the message
81 * class's .serializeBinary method, if available. 79 * class's .serializeBinary method, if available.
82 * 80 *
83 * @param {number} fieldNumber 81 * @param {number} fieldNumber
84 * @param {Object} fieldName This has the extension field name as a property. 82 * @param {Object} fieldName This has the extension field name as a property.
85 * @param {?function(new: jspb.Message, Array=)} ctor 83 * @param {?function(new: jspb.Message, Array=)} ctor
86 * @param {?function((boolean|undefined),!jspb.Message):!Object} toObjectFn 84 * @param {?function((boolean|undefined),!jspb.Message):!Object} toObjectFn
87 * @param {number} isRepeated 85 * @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
88 * @constructor 91 * @constructor
89 * @struct 92 * @struct
90 * @template T 93 * @template T
91 */ 94 */
92 jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn, 95 jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn,
93 isRepeated) { 96 isRepeated, opt_binaryReaderFn, opt_binaryWriterFn,
97 opt_binaryMessageSerializeFn, opt_binaryMessageDeserializeFn,
98 opt_isPacked) {
94 /** @const */ 99 /** @const */
95 this.fieldIndex = fieldNumber; 100 this.fieldIndex = fieldNumber;
96 /** @const */ 101 /** @const */
97 this.fieldName = fieldName; 102 this.fieldName = fieldName;
98 /** @const */ 103 /** @const */
99 this.ctor = ctor; 104 this.ctor = ctor;
100 /** @const */ 105 /** @const */
101 this.toObjectFn = toObjectFn; 106 this.toObjectFn = toObjectFn;
102 /** @const */ 107 /** @const */
103 this.isRepeated = isRepeated; 108 this.binaryReaderFn = opt_binaryReaderFn;
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) {
120 /** @const */ 109 /** @const */
121 this.fieldInfo = fieldInfo; 110 this.binaryWriterFn = opt_binaryWriterFn;
122 /** @const */
123 this.binaryReaderFn = binaryReaderFn;
124 /** @const */
125 this.binaryWriterFn = binaryWriterFn;
126 /** @const */ 111 /** @const */
127 this.binaryMessageSerializeFn = opt_binaryMessageSerializeFn; 112 this.binaryMessageSerializeFn = opt_binaryMessageSerializeFn;
128 /** @const */ 113 /** @const */
129 this.binaryMessageDeserializeFn = opt_binaryMessageDeserializeFn; 114 this.binaryMessageDeserializeFn = opt_binaryMessageDeserializeFn;
130 /** @const */ 115 /** @const */
116 this.isRepeated = isRepeated;
117 /** @const */
131 this.isPacked = opt_isPacked; 118 this.isPacked = opt_isPacked;
132 }; 119 };
133 120
121
134 /** 122 /**
135 * @return {boolean} Does this field represent a sub Message? 123 * @return {boolean} Does this field represent a sub Message?
136 */ 124 */
137 jspb.ExtensionFieldInfo.prototype.isMessageType = function() { 125 jspb.ExtensionFieldInfo.prototype.isMessageType = function() {
138 return !!this.ctor; 126 return !!this.ctor;
139 }; 127 };
140 128
141 129
142 /** 130 /**
143 * Base class for all JsPb messages. 131 * Base class for all JsPb messages.
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 */ 364 */
377 jspb.Message.materializeExtensionObject_ = function(msg, suggestedPivot) { 365 jspb.Message.materializeExtensionObject_ = function(msg, suggestedPivot) {
378 if (msg.array.length) { 366 if (msg.array.length) {
379 var foundIndex = msg.array.length - 1; 367 var foundIndex = msg.array.length - 1;
380 var obj = msg.array[foundIndex]; 368 var obj = msg.array[foundIndex];
381 // Normal fields are never objects, so we can be sure that if we find an 369 // Normal fields are never objects, so we can be sure that if we find an
382 // object here, then it's the extension object. However, we must ensure that 370 // object here, then it's the extension object. However, we must ensure that
383 // the object is not an array, since arrays are valid field values. 371 // the object is not an array, since arrays are valid field values.
384 // NOTE(lukestebbing): We avoid looking at .length to avoid a JIT bug 372 // NOTE(lukestebbing): We avoid looking at .length to avoid a JIT bug
385 // in Safari on iOS 8. See the description of CL/86511464 for details. 373 // in Safari on iOS 8. See the description of CL/86511464 for details.
386 if (obj && typeof obj == 'object' && !goog.isArray(obj) && 374 if (obj && typeof obj == 'object' && !goog.isArray(obj)) {
387 !(jspb.Message.SUPPORTS_UINT8ARRAY_ && obj instanceof Uint8Array)) {
388 msg.pivot_ = foundIndex - msg.arrayIndexOffset_; 375 msg.pivot_ = foundIndex - msg.arrayIndexOffset_;
389 msg.extensionObject_ = obj; 376 msg.extensionObject_ = obj;
390 return; 377 return;
391 } 378 }
392 } 379 }
393 // This complexity exists because we keep all extension fields in the 380 // This complexity exists because we keep all extension fields in the
394 // extensionObject_ regardless of proto field number. Changing this would 381 // extensionObject_ regardless of proto field number. Changing this would
395 // simplify the code here, but it would require changing the serialization 382 // simplify the code here, but it would require changing the serialization
396 // format from the server, which is not backwards compatible. 383 // format from the server, which is not backwards compatible.
397 // TODO(jshneier): Should we just treat extension fields the same as 384 // TODO(jshneier): Should we just treat extension fields the same as
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 * Writes a proto's extension data to a binary-format output stream. 482 * Writes a proto's extension data to a binary-format output stream.
496 * @param {!jspb.Message} proto The proto whose extensions to convert. 483 * @param {!jspb.Message} proto The proto whose extensions to convert.
497 * @param {*} writer The binary-format writer to write to. 484 * @param {*} writer The binary-format writer to write to.
498 * @param {!Object} extensions The proto class' registered extensions. 485 * @param {!Object} extensions The proto class' registered extensions.
499 * @param {function(jspb.ExtensionFieldInfo) : *} getExtensionFn The proto 486 * @param {function(jspb.ExtensionFieldInfo) : *} getExtensionFn The proto
500 * class' getExtension function. Passed for effective dead code removal. 487 * class' getExtension function. Passed for effective dead code removal.
501 */ 488 */
502 jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions, 489 jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
503 getExtensionFn) { 490 getExtensionFn) {
504 for (var fieldNumber in extensions) { 491 for (var fieldNumber in extensions) {
505 var binaryFieldInfo = extensions[fieldNumber]; 492 var fieldInfo = extensions[fieldNumber];
506 var fieldInfo = binaryFieldInfo.fieldInfo;
507
508 // 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
509 // 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
510 // below. 495 // below.
511 if (!binaryFieldInfo.binaryWriterFn) { 496 if (!fieldInfo.binaryWriterFn) {
512 throw new Error('Message extension present that was generated ' + 497 throw new Error('Message extension present that was generated ' +
513 'without binary serialization support'); 498 'without binary serialization support');
514 } 499 }
515 var value = getExtensionFn.call(proto, fieldInfo); 500 var value = getExtensionFn.call(proto, fieldInfo);
516 if (value) { 501 if (value) {
517 if (fieldInfo.isMessageType()) { 502 if (fieldInfo.isMessageType()) {
518 // If the message type of the extension was generated without binary 503 // If the message type of the extension was generated without binary
519 // support, there may not be a binary message serializer function, and 504 // support, there may not be a binary message serializer function, and
520 // 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
521 // 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
522 // 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
523 // extensions!). 508 // extensions!).
524 if (binaryFieldInfo.binaryMessageSerializeFn) { 509 if (fieldInfo.binaryMessageSerializeFn) {
525 binaryFieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex, 510 fieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex,
526 value, binaryFieldInfo.binaryMessageSerializeFn); 511 value, fieldInfo.binaryMessageSerializeFn);
527 } else { 512 } else {
528 throw new Error('Message extension present holding submessage ' + 513 throw new Error('Message extension present holding submessage ' +
529 'without binary support enabled, and message is ' + 514 'without binary support enabled, and message is ' +
530 'being serialized to binary format'); 515 'being serialized to binary format');
531 } 516 }
532 } else { 517 } else {
533 binaryFieldInfo.binaryWriterFn.call( 518 fieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex, value);
534 writer, fieldInfo.fieldIndex, value);
535 } 519 }
536 } 520 }
537 } 521 }
538 }; 522 };
539 523
540 524
541 /** 525 /**
542 * Reads an extension field from the given reader and, if a valid extension, 526 * Reads an extension field from the given reader and, if a valid extension,
543 * sets the extension value. 527 * sets the extension value.
544 * @param {!jspb.Message} msg A jspb proto. 528 * @param {!jspb.Message} msg A jspb proto.
545 * @param {{skipField:function(),getFieldNumber:function():number}} reader 529 * @param {{skipField:function(),getFieldNumber:function():number}} reader
546 * @param {!Object} extensions The extensions object. 530 * @param {!Object} extensions The extensions object.
547 * @param {function(jspb.ExtensionFieldInfo)} getExtensionFn 531 * @param {function(jspb.ExtensionFieldInfo)} getExtensionFn
548 * @param {function(jspb.ExtensionFieldInfo, ?)} setExtensionFn 532 * @param {function(jspb.ExtensionFieldInfo, ?)} setExtensionFn
549 */ 533 */
550 jspb.Message.readBinaryExtension = function(msg, reader, extensions, 534 jspb.Message.readBinaryExtension = function(msg, reader, extensions,
551 getExtensionFn, setExtensionFn) { 535 getExtensionFn, setExtensionFn) {
552 var binaryFieldInfo = extensions[reader.getFieldNumber()]; 536 var fieldInfo = extensions[reader.getFieldNumber()];
553 if (!binaryFieldInfo) { 537 if (!fieldInfo) {
554 reader.skipField(); 538 reader.skipField();
555 return; 539 return;
556 } 540 }
557 var fieldInfo = binaryFieldInfo.fieldInfo; 541 if (!fieldInfo.binaryReaderFn) {
558 if (!binaryFieldInfo.binaryReaderFn) {
559 throw new Error('Deserializing extension whose generated code does not ' + 542 throw new Error('Deserializing extension whose generated code does not ' +
560 'support binary format'); 543 'support binary format');
561 } 544 }
562 545
563 var value; 546 var value;
564 if (fieldInfo.isMessageType()) { 547 if (fieldInfo.isMessageType()) {
565 value = new fieldInfo.ctor(); 548 value = new fieldInfo.ctor();
566 binaryFieldInfo.binaryReaderFn.call( 549 fieldInfo.binaryReaderFn.call(
567 reader, value, binaryFieldInfo.binaryMessageDeserializeFn); 550 reader, value, fieldInfo.binaryMessageDeserializeFn);
568 } else { 551 } else {
569 // All other types. 552 // All other types.
570 value = binaryFieldInfo.binaryReaderFn.call(reader); 553 value = fieldInfo.binaryReaderFn.call(reader);
571 } 554 }
572 555
573 if (fieldInfo.isRepeated && !binaryFieldInfo.isPacked) { 556 if (fieldInfo.isRepeated && !fieldInfo.isPacked) {
574 var currentList = getExtensionFn.call(msg, fieldInfo); 557 var currentList = getExtensionFn.call(msg, fieldInfo);
575 if (!currentList) { 558 if (!currentList) {
576 setExtensionFn.call(msg, fieldInfo, [value]); 559 setExtensionFn.call(msg, fieldInfo, [value]);
577 } else { 560 } else {
578 currentList.push(value); 561 currentList.push(value);
579 } 562 }
580 } else { 563 } else {
581 setExtensionFn.call(msg, fieldInfo, value); 564 setExtensionFn.call(msg, fieldInfo, value);
582 } 565 }
583 }; 566 };
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 * 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
738 * primitives) semantics. Returns `defaultValue` if the field is not otherwise 721 * primitives) semantics. Returns `defaultValue` if the field is not otherwise
739 * set. 722 * set.
740 * @template T 723 * @template T
741 * @param {!jspb.Message} msg A jspb proto. 724 * @param {!jspb.Message} msg A jspb proto.
742 * @param {number} fieldNumber The field number. 725 * @param {number} fieldNumber The field number.
743 * @param {T} defaultValue The default value. 726 * @param {T} defaultValue The default value.
744 * @return {T} The field's value. 727 * @return {T} The field's value.
745 * @protected 728 * @protected
746 */ 729 */
747 jspb.Message.getFieldWithDefault = function(msg, fieldNumber, defaultValue) { 730 jspb.Message.getFieldProto3 = function(msg, fieldNumber, defaultValue) {
748 var value = jspb.Message.getField(msg, fieldNumber); 731 var value = jspb.Message.getField(msg, fieldNumber);
749 if (value == null) { 732 if (value == null) {
750 return defaultValue; 733 return defaultValue;
751 } else { 734 } else {
752 return value; 735 return value;
753 } 736 }
754 }; 737 };
755 738
756 739
757 /** 740 /**
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 /**
810 * Sets the value of a non-extension field. 741 * Sets the value of a non-extension field.
811 * @param {!jspb.Message} msg A jspb proto. 742 * @param {!jspb.Message} msg A jspb proto.
812 * @param {number} fieldNumber The field number. 743 * @param {number} fieldNumber The field number.
813 * @param {string|number|boolean|Uint8Array|Array|undefined} value New value 744 * @param {string|number|boolean|Uint8Array|Array|undefined} value New value
814 * @protected 745 * @protected
815 */ 746 */
816 jspb.Message.setField = function(msg, fieldNumber, value) { 747 jspb.Message.setField = function(msg, fieldNumber, value) {
817 if (fieldNumber < msg.pivot_) { 748 if (fieldNumber < msg.pivot_) {
818 msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = value; 749 msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = value;
819 } else { 750 } else {
820 msg.extensionObject_[fieldNumber] = value; 751 msg.extensionObject_[fieldNumber] = value;
821 } 752 }
822 }; 753 };
823 754
824 755
825 /** 756 /**
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 /**
844 * Sets the value of a field in a oneof union and clears all other fields in 757 * Sets the value of a field in a oneof union and clears all other fields in
845 * the union. 758 * the union.
846 * @param {!jspb.Message} msg A jspb proto. 759 * @param {!jspb.Message} msg A jspb proto.
847 * @param {number} fieldNumber The field number. 760 * @param {number} fieldNumber The field number.
848 * @param {!Array<number>} oneof The fields belonging to the union. 761 * @param {!Array<number>} oneof The fields belonging to the union.
849 * @param {string|number|boolean|Uint8Array|Array|undefined} value New value 762 * @param {string|number|boolean|Uint8Array|Array|undefined} value New value
850 * @protected 763 * @protected
851 */ 764 */
852 jspb.Message.setOneofField = function(msg, fieldNumber, oneof, value) { 765 jspb.Message.setOneofField = function(msg, fieldNumber, oneof, value) {
853 var currentCase = jspb.Message.computeOneofCase(msg, oneof); 766 var currentCase = jspb.Message.computeOneofCase(msg, oneof);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 843
931 /** 844 /**
932 * Gets and wraps a repeated proto field on access. 845 * Gets and wraps a repeated proto field on access.
933 * @param {!jspb.Message} msg A jspb proto. 846 * @param {!jspb.Message} msg A jspb proto.
934 * @param {function(new:jspb.Message, Array)} ctor Constructor for the field. 847 * @param {function(new:jspb.Message, Array)} ctor Constructor for the field.
935 * @param {number} fieldNumber The field number. 848 * @param {number} fieldNumber The field number.
936 * @return {Array<!jspb.Message>} The repeated field as an array of protos. 849 * @return {Array<!jspb.Message>} The repeated field as an array of protos.
937 * @protected 850 * @protected
938 */ 851 */
939 jspb.Message.getRepeatedWrapperField = function(msg, ctor, fieldNumber) { 852 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) {
958 if (!msg.wrappers_) { 853 if (!msg.wrappers_) {
959 msg.wrappers_ = {}; 854 msg.wrappers_ = {};
960 } 855 }
961 if (!msg.wrappers_[fieldNumber]) { 856 if (!msg.wrappers_[fieldNumber]) {
962 var data = jspb.Message.getField(msg, fieldNumber); 857 var data = jspb.Message.getField(msg, fieldNumber);
963 for (var wrappers = [], i = 0; i < data.length; i++) { 858 for (var wrappers = [], i = 0; i < data.length; i++) {
964 wrappers[i] = new ctor(data[i]); 859 wrappers[i] = new ctor(data[i]);
965 } 860 }
966 msg.wrappers_[fieldNumber] = wrappers; 861 msg.wrappers_[fieldNumber] = wrappers;
967 } 862 }
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);
968 }; 868 };
969 869
970 870
971 /** 871 /**
972 * Sets a proto field and syncs it to the backing array. 872 * Sets a proto field and syncs it to the backing array.
973 * @param {!jspb.Message} msg A jspb proto. 873 * @param {!jspb.Message} msg A jspb proto.
974 * @param {number} fieldNumber The field number. 874 * @param {number} fieldNumber The field number.
975 * @param {?jspb.Message|?jspb.Map|undefined} value A new value for this proto 875 * @param {jspb.Message|undefined} value A new value for this proto field.
976 * field.
977 * @protected 876 * @protected
978 */ 877 */
979 jspb.Message.setWrapperField = function(msg, fieldNumber, value) { 878 jspb.Message.setWrapperField = function(msg, fieldNumber, value) {
980 if (!msg.wrappers_) { 879 if (!msg.wrappers_) {
981 msg.wrappers_ = {}; 880 msg.wrappers_ = {};
982 } 881 }
983 var data = value ? value.toArray() : value; 882 var data = value ? value.toArray() : value;
984 msg.wrappers_[fieldNumber] = value; 883 msg.wrappers_[fieldNumber] = value;
985 jspb.Message.setField(msg, fieldNumber, data); 884 jspb.Message.setField(msg, fieldNumber, data);
986 }; 885 };
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 value = value || []; 917 value = value || [];
1019 for (var data = [], i = 0; i < value.length; i++) { 918 for (var data = [], i = 0; i < value.length; i++) {
1020 data[i] = value[i].toArray(); 919 data[i] = value[i].toArray();
1021 } 920 }
1022 msg.wrappers_[fieldNumber] = value; 921 msg.wrappers_[fieldNumber] = value;
1023 jspb.Message.setField(msg, fieldNumber, data); 922 jspb.Message.setField(msg, fieldNumber, data);
1024 }; 923 };
1025 924
1026 925
1027 /** 926 /**
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 /**
1070 * Converts a JsPb repeated message field into a map. The map will contain 927 * Converts a JsPb repeated message field into a map. The map will contain
1071 * protos unless an optional toObject function is given, in which case it will 928 * protos unless an optional toObject function is given, in which case it will
1072 * contain objects suitable for Soy rendering. 929 * contain objects suitable for Soy rendering.
1073 * @param {!Array<T>} field The repeated message field to be 930 * @param {!Array<T>} field The repeated message field to be
1074 * converted. 931 * converted.
1075 * @param {function() : string?} mapKeyGetterFn The function to get the key of 932 * @param {function() : string?} mapKeyGetterFn The function to get the key of
1076 * the map. 933 * the map.
1077 * @param {?function(boolean=): Object| 934 * @param {?function(boolean=): Object|
1078 * function((boolean|undefined),T): Object} opt_toObjectFn The 935 * function((boolean|undefined),T): Object} opt_toObjectFn The
1079 * toObject function for this field. We need to pass this for effective 936 * toObject function for this field. We need to pass this for effective
1080 * dead code removal. 937 * dead code removal.
1081 * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 938 * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
1082 * for transitional soy proto support: http://goto/soy-param-migration 939 * for transitional soy proto support: http://goto/soy-param-migration
1083 * @return {!Object.<string, Object>} A map of proto or Soy objects. 940 * @return {!Object.<string, Object>} A map of proto or Soy objects.
1084 * @template T 941 * @template T
1085 */ 942 */
1086 jspb.Message.toMap = function( 943 jspb.Message.toMap = function(
1087 field, mapKeyGetterFn, opt_toObjectFn, opt_includeInstance) { 944 field, mapKeyGetterFn, opt_toObjectFn, opt_includeInstance) {
1088 var result = {}; 945 var result = {};
1089 for (var i = 0; i < field.length; i++) { 946 for (var i = 0; i < field.length; i++) {
1090 result[mapKeyGetterFn.call(field[i])] = opt_toObjectFn ? 947 result[mapKeyGetterFn.call(field[i])] = opt_toObjectFn ?
1091 opt_toObjectFn.call(field[i], opt_includeInstance, 948 opt_toObjectFn.call(field[i], opt_includeInstance,
1092 /** @type {!jspb.Message} */ (field[i])) : field[i]; 949 /** @type {!jspb.Message} */ (field[i])) : field[i];
1093 } 950 }
1094 return result; 951 return result;
1095 }; 952 };
1096 953
1097 954
1098 /** 955 /**
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 /**
1131 * Returns the internal array of this proto. 956 * Returns the internal array of this proto.
1132 * <p>Note: If you use this array to construct a second proto, the content 957 * <p>Note: If you use this array to construct a second proto, the content
1133 * would then be partially shared between the two protos. 958 * would then be partially shared between the two protos.
1134 * @return {!Array} The proto represented as an array. 959 * @return {!Array} The proto represented as an array.
1135 */ 960 */
1136 jspb.Message.prototype.toArray = function() { 961 jspb.Message.prototype.toArray = function() {
1137 this.syncMapFields_();
1138 return this.array; 962 return this.array;
1139 }; 963 };
1140 964
1141 965
1142 966
1143 967
1144 /** 968 /**
1145 * Creates a string representation of the internal data array of this proto. 969 * Creates a string representation of the internal data array of this proto.
1146 * <p>NOTE: This string is *not* suitable for use in server requests. 970 * <p>NOTE: This string is *not* suitable for use in server requests.
1147 * @return {string} A string representation of this proto. 971 * @return {string} A string representation of this proto.
1148 * @override 972 * @override
1149 */ 973 */
1150 jspb.Message.prototype.toString = function() { 974 jspb.Message.prototype.toString = function() {
1151 this.syncMapFields_();
1152 return this.array.toString(); 975 return this.array.toString();
1153 }; 976 };
1154 977
1155 978
1156 /** 979 /**
1157 * Gets the value of the extension field from the extended object. 980 * Gets the value of the extension field from the extended object.
1158 * @param {jspb.ExtensionFieldInfo.<T>} fieldInfo Specifies the field to get. 981 * @param {jspb.ExtensionFieldInfo.<T>} fieldInfo Specifies the field to get.
1159 * @return {T} The value of the field. 982 * @return {T} The value of the field.
1160 * @template T 983 * @template T
1161 */ 984 */
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 } 1016 }
1194 } 1017 }
1195 }; 1018 };
1196 1019
1197 1020
1198 /** 1021 /**
1199 * Sets the value of the extension field in the extended object. 1022 * Sets the value of the extension field in the extended object.
1200 * @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to set. 1023 * @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to set.
1201 * @param {jspb.Message|string|Uint8Array|number|boolean|Array?} value The value 1024 * @param {jspb.Message|string|Uint8Array|number|boolean|Array?} value The value
1202 * to set. 1025 * to set.
1203 * @return {THIS} For chaining
1204 * @this {THIS}
1205 * @template THIS
1206 */ 1026 */
1207 jspb.Message.prototype.setExtension = function(fieldInfo, value) { 1027 jspb.Message.prototype.setExtension = function(fieldInfo, value) {
1208 // Cast self, since the inferred THIS is unknown inside the function body. 1028 if (!this.wrappers_) {
1209 // https://github.com/google/closure-compiler/issues/1411#issuecomment-2324422 20 1029 this.wrappers_ = {};
1210 var self = /** @type {!jspb.Message} */ (this);
1211 if (!self.wrappers_) {
1212 self.wrappers_ = {};
1213 } 1030 }
1214 jspb.Message.maybeInitEmptyExtensionObject_(self); 1031 jspb.Message.maybeInitEmptyExtensionObject_(this);
1215 var fieldNumber = fieldInfo.fieldIndex; 1032 var fieldNumber = fieldInfo.fieldIndex;
1216 if (fieldInfo.isRepeated) { 1033 if (fieldInfo.isRepeated) {
1217 value = value || []; 1034 value = value || [];
1218 if (fieldInfo.isMessageType()) { 1035 if (fieldInfo.isMessageType()) {
1219 self.wrappers_[fieldNumber] = value; 1036 this.wrappers_[fieldNumber] = value;
1220 self.extensionObject_[fieldNumber] = goog.array.map( 1037 this.extensionObject_[fieldNumber] = goog.array.map(
1221 /** @type {Array<jspb.Message>} */ (value), function(msg) { 1038 /** @type {Array<jspb.Message>} */ (value), function(msg) {
1222 return msg.toArray(); 1039 return msg.toArray();
1223 }); 1040 });
1224 } else { 1041 } else {
1225 self.extensionObject_[fieldNumber] = value; 1042 this.extensionObject_[fieldNumber] = value;
1226 } 1043 }
1227 } else { 1044 } else {
1228 if (fieldInfo.isMessageType()) { 1045 if (fieldInfo.isMessageType()) {
1229 self.wrappers_[fieldNumber] = value; 1046 this.wrappers_[fieldNumber] = value;
1230 self.extensionObject_[fieldNumber] = value ? value.toArray() : value; 1047 this.extensionObject_[fieldNumber] = value ? value.toArray() : value;
1231 } else { 1048 } else {
1232 self.extensionObject_[fieldNumber] = value; 1049 this.extensionObject_[fieldNumber] = value;
1233 } 1050 }
1234 } 1051 }
1235 return self;
1236 }; 1052 };
1237 1053
1238 1054
1239 /** 1055 /**
1240 * Creates a difference object between two messages. 1056 * Creates a difference object between two messages.
1241 * 1057 *
1242 * The result will contain the top-level fields of m2 that differ from those of 1058 * The result will contain the top-level fields of m2 that differ from those of
1243 * m1 at any level of nesting. No data is cloned, the result object will 1059 * m1 at any level of nesting. No data is cloned, the result object will
1244 * share its top-level elements with m2 (but not with m1). 1060 * share its top-level elements with m2 (but not with m1).
1245 * 1061 *
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 // extensions. 1210 // extensions.
1395 if (field1.constructor === Object) { 1211 if (field1.constructor === Object) {
1396 return jspb.Message.compareExtensions(field1, field2); 1212 return jspb.Message.compareExtensions(field1, field2);
1397 } 1213 }
1398 1214
1399 throw new Error('Invalid type in JSPB array'); 1215 throw new Error('Invalid type in JSPB array');
1400 }; 1216 };
1401 1217
1402 1218
1403 /** 1219 /**
1404 * Templated, type-safe cloneMessage definition. 1220 * Static clone function. NOTE: A type-safe method called "cloneMessage" exists
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
1428 * on each generated JsPb class. Do not call this function directly. 1221 * on each generated JsPb class. Do not call this function directly.
1429 * @param {!jspb.Message} msg A message to clone. 1222 * @param {!jspb.Message} msg A message to clone.
1430 * @return {!jspb.Message} A deep clone of the given message. 1223 * @return {!jspb.Message} A deep clone of the given message.
1431 */ 1224 */
1432 jspb.Message.clone = function(msg) { 1225 jspb.Message.clone = function(msg) {
1433 // Although we could include the wrappers, we leave them out here. 1226 // Although we could include the wrappers, we leave them out here.
1434 return jspb.Message.cloneMessage(msg); 1227 return jspb.Message.cloneMessage(msg);
1435 }; 1228 };
1436 1229
1437 1230
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 // Allocate array of correct size. 1286 // Allocate array of correct size.
1494 var clonedArray = new Array(obj.length); 1287 var clonedArray = new Array(obj.length);
1495 // Use array iteration where possible because it is faster than for-in. 1288 // Use array iteration where possible because it is faster than for-in.
1496 for (var i = 0; i < obj.length; i++) { 1289 for (var i = 0; i < obj.length; i++) {
1497 if ((o = obj[i]) != null) { 1290 if ((o = obj[i]) != null) {
1498 clonedArray[i] = typeof o == 'object' ? jspb.Message.clone_(o) : o; 1291 clonedArray[i] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
1499 } 1292 }
1500 } 1293 }
1501 return clonedArray; 1294 return clonedArray;
1502 } 1295 }
1503 if (jspb.Message.SUPPORTS_UINT8ARRAY_ && obj instanceof Uint8Array) {
1504 return new Uint8Array(obj);
1505 }
1506 var clone = {}; 1296 var clone = {};
1507 for (var key in obj) { 1297 for (var key in obj) {
1508 if ((o = obj[key]) != null) { 1298 if ((o = obj[key]) != null) {
1509 clone[key] = typeof o == 'object' ? jspb.Message.clone_(o) : o; 1299 clone[key] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
1510 } 1300 }
1511 } 1301 }
1512 return clone; 1302 return clone;
1513 }; 1303 };
1514 1304
1515 1305
(...skipping 22 matching lines...) Expand all
1538 * 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
1539 * private API. 1329 * private API.
1540 * 1330 *
1541 * This is similar to [jspb class name].extensions object for 1331 * This is similar to [jspb class name].extensions object for
1542 * 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
1543 * to goog.require MessageSet from classes that extends MessageSet. 1333 * to goog.require MessageSet from classes that extends MessageSet.
1544 * 1334 *
1545 * @type {!Object.<number, jspb.ExtensionFieldInfo>} 1335 * @type {!Object.<number, jspb.ExtensionFieldInfo>}
1546 */ 1336 */
1547 jspb.Message.messageSetExtensions = {}; 1337 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