1/** 2 * @fileoverview Utilities to index a binary proto by fieldnumbers without 3 * relying on strutural proto information. 4 */ 5goog.module('protobuf.binary.indexer'); 6 7const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage'); 8const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); 9const WireType = goog.require('protobuf.binary.WireType'); 10const {Field} = goog.require('protobuf.binary.field'); 11const {checkCriticalState} = goog.require('protobuf.internal.checks'); 12const {skipField, tagToFieldNumber, tagToWireType} = goog.require('protobuf.binary.tag'); 13 14/** 15 * Appends a new entry in the index array for the given field number. 16 * @param {!BinaryStorage<!Field>} storage 17 * @param {number} fieldNumber 18 * @param {!WireType} wireType 19 * @param {number} startIndex 20 */ 21function addIndexEntry(storage, fieldNumber, wireType, startIndex) { 22 const field = storage.get(fieldNumber); 23 if (field !== undefined) { 24 field.addIndexEntry(wireType, startIndex); 25 } else { 26 storage.set(fieldNumber, Field.fromFirstIndexEntry(wireType, startIndex)); 27 } 28} 29 30/** 31 * Creates an index of field locations in a given binary protobuf. 32 * @param {!BufferDecoder} bufferDecoder 33 * @param {number|undefined} pivot 34 * @return {!BinaryStorage<!Field>} 35 * @package 36 */ 37function buildIndex(bufferDecoder, pivot) { 38 bufferDecoder.setCursor(bufferDecoder.startIndex()); 39 40 const storage = new BinaryStorage(pivot); 41 while (bufferDecoder.hasNext()) { 42 const tag = bufferDecoder.getUnsignedVarint32(); 43 const wireType = tagToWireType(tag); 44 const fieldNumber = tagToFieldNumber(tag); 45 checkCriticalState(fieldNumber > 0, `Invalid field number ${fieldNumber}`); 46 addIndexEntry(storage, fieldNumber, wireType, bufferDecoder.cursor()); 47 skipField(bufferDecoder, wireType, fieldNumber); 48 } 49 return storage; 50} 51 52exports = { 53 buildIndex, 54 tagToWireType, 55}; 56