| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 | 
							- /**
 
-  * @fileoverview Contains classes that hold data for a protobuf field.
 
-  */
 
- goog.module('protobuf.binary.field');
 
- const WireType = goog.requireType('protobuf.binary.WireType');
 
- const Writer = goog.requireType('protobuf.binary.Writer');
 
- const {checkDefAndNotNull, checkState} = goog.require('protobuf.internal.checks');
 
- /**
 
-  * Number of bits taken to represent a wire type.
 
-  * @const {number}
 
-  */
 
- const WIRE_TYPE_LENGTH_BITS = 3;
 
- /** @const {number} */
 
- const WIRE_TYPE_EXTRACTOR = (1 << WIRE_TYPE_LENGTH_BITS) - 1;
 
- /**
 
-  * An IndexEntry consists of the wire type and the position of a field in the
 
-  * binary data. The wire type and the position are encoded into a single number
 
-  * to save memory, which can be decoded using Field.getWireType() and
 
-  * Field.getStartIndex() methods.
 
-  * @typedef {number}
 
-  */
 
- let IndexEntry;
 
- /**
 
-  * An entry containing the index into the binary data and/or the corresponding
 
-  * cached JS object(s) for a field.
 
-  * @template T
 
-  * @final
 
-  * @package
 
-  */
 
- class Field {
 
-   /**
 
-    * Creates a field and inserts the wireType and position of the first
 
-    * occurrence of a field.
 
-    * @param {!WireType} wireType
 
-    * @param {number} startIndex
 
-    * @return {!Field}
 
-    */
 
-   static fromFirstIndexEntry(wireType, startIndex) {
 
-     return new Field([Field.encodeIndexEntry(wireType, startIndex)]);
 
-   }
 
-   /**
 
-    * @param {T} decodedValue The cached JS object decoded from the binary data.
 
-    * @param {function(!Writer, number, T):void|undefined} encoder Write function
 
-    *     to encode the cache into binary bytes.
 
-    * @return {!Field}
 
-    * @template T
 
-    */
 
-   static fromDecodedValue(decodedValue, encoder) {
 
-     return new Field(null, decodedValue, encoder);
 
-   }
 
-   /**
 
-    * @param {!WireType} wireType
 
-    * @param {number} startIndex
 
-    * @return {!IndexEntry}
 
-    */
 
-   static encodeIndexEntry(wireType, startIndex) {
 
-     return startIndex << WIRE_TYPE_LENGTH_BITS | wireType;
 
-   }
 
-   /**
 
-    * @param {!IndexEntry} indexEntry
 
-    * @return {!WireType}
 
-    */
 
-   static getWireType(indexEntry) {
 
-     return /** @type {!WireType} */ (indexEntry & WIRE_TYPE_EXTRACTOR);
 
-   }
 
-   /**
 
-    * @param {!IndexEntry} indexEntry
 
-    * @return {number}
 
-    */
 
-   static getStartIndex(indexEntry) {
 
-     return indexEntry >> WIRE_TYPE_LENGTH_BITS;
 
-   }
 
-   /**
 
-    * @param {?Array<!IndexEntry>} indexArray
 
-    * @param {T=} decodedValue
 
-    * @param {function(!Writer, number, T):void=} encoder
 
-    * @private
 
-    */
 
-   constructor(indexArray, decodedValue = undefined, encoder = undefined) {
 
-     checkState(
 
-         !!indexArray || decodedValue !== undefined,
 
-         'At least one of indexArray and decodedValue must be set');
 
-     /** @private {?Array<!IndexEntry>} */
 
-     this.indexArray_ = indexArray;
 
-     /** @private {T|undefined} */
 
-     this.decodedValue_ = decodedValue;
 
-     // TODO: Consider storing an enum to represent encoder
 
-     /** @private {function(!Writer, number, T)|undefined} */
 
-     this.encoder_ = encoder;
 
-   }
 
-   /**
 
-    * Adds a new IndexEntry.
 
-    * @param {!WireType} wireType
 
-    * @param {number} startIndex
 
-    */
 
-   addIndexEntry(wireType, startIndex) {
 
-     checkDefAndNotNull(this.indexArray_)
 
-         .push(Field.encodeIndexEntry(wireType, startIndex));
 
-   }
 
-   /**
 
-    * Returns the array of IndexEntry.
 
-    * @return {?Array<!IndexEntry>}
 
-    */
 
-   getIndexArray() {
 
-     return this.indexArray_;
 
-   }
 
-   /**
 
-    * Caches the decoded value and sets the write function to encode cache into
 
-    * binary bytes.
 
-    * @param {T} decodedValue
 
-    * @param {function(!Writer, number, T):void|undefined} encoder
 
-    */
 
-   setCache(decodedValue, encoder) {
 
-     this.decodedValue_ = decodedValue;
 
-     this.encoder_ = encoder;
 
-     this.maybeRemoveIndexArray_();
 
-   }
 
-   /**
 
-    * If the decoded value has been set.
 
-    * @return {boolean}
 
-    */
 
-   hasDecodedValue() {
 
-     return this.decodedValue_ !== undefined;
 
-   }
 
-   /**
 
-    * Returns the cached decoded value. The value needs to be set when this
 
-    * method is called.
 
-    * @return {T}
 
-    */
 
-   getDecodedValue() {
 
-     // Makes sure that the decoded value in the cache has already been set. This
 
-     // prevents callers from doing `if (field.getDecodedValue()) {...}` to check
 
-     // if a value exist in the cache, because the check might return false even
 
-     // if the cache has a valid value set (e.g. 0 or empty string).
 
-     checkState(this.decodedValue_ !== undefined);
 
-     return this.decodedValue_;
 
-   }
 
-   /**
 
-    * Returns the write function to encode cache into binary bytes.
 
-    * @return {function(!Writer, number, T)|undefined}
 
-    */
 
-   getEncoder() {
 
-     return this.encoder_;
 
-   }
 
-   /**
 
-    * Returns a copy of the field, containing the original index entries and a
 
-    * shallow copy of the cache.
 
-    * @return {!Field}
 
-    */
 
-   shallowCopy() {
 
-     // Repeated fields are arrays in the cache.
 
-     // We have to copy the array to make sure that modifications to a repeated
 
-     // field (e.g. add) are not seen on a cloned accessor.
 
-     const copiedCache = this.hasDecodedValue() ?
 
-         (Array.isArray(this.getDecodedValue()) ? [...this.getDecodedValue()] :
 
-                                                  this.getDecodedValue()) :
 
-         undefined;
 
-     return new Field(this.getIndexArray(), copiedCache, this.getEncoder());
 
-   }
 
-   /**
 
-    * @private
 
-    */
 
-   maybeRemoveIndexArray_() {
 
-     checkState(
 
-         this.encoder_ === undefined || this.decodedValue_ !== undefined,
 
-         'Encoder exists but decoded value doesn\'t');
 
-     if (this.encoder_ !== undefined) {
 
-       this.indexArray_ = null;
 
-     }
 
-   }
 
- }
 
- exports = {
 
-   IndexEntry,
 
-   Field,
 
- };
 
 
  |