/** * @fileoverview Utilities to index a binary proto by fieldnumbers without * relying on strutural proto information. */ goog.module('protobuf.binary.indexer'); const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage'); const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); const WireType = goog.require('protobuf.binary.WireType'); const {Field} = goog.require('protobuf.binary.field'); const {checkCriticalState} = goog.require('protobuf.internal.checks'); const {skipField, tagToFieldNumber, tagToWireType} = goog.require('protobuf.binary.tag'); /** * Appends a new entry in the index array for the given field number. * @param {!BinaryStorage} storage * @param {number} fieldNumber * @param {!WireType} wireType * @param {number} startIndex */ function addIndexEntry(storage, fieldNumber, wireType, startIndex) { const field = storage.get(fieldNumber); if (field !== undefined) { field.addIndexEntry(wireType, startIndex); } else { storage.set(fieldNumber, Field.fromFirstIndexEntry(wireType, startIndex)); } } /** * Creates an index of field locations in a given binary protobuf. * @param {!BufferDecoder} bufferDecoder * @param {number|undefined} pivot * @return {!BinaryStorage} * @package */ function buildIndex(bufferDecoder, pivot) { bufferDecoder.setCursor(bufferDecoder.startIndex()); const storage = new BinaryStorage(pivot); while (bufferDecoder.hasNext()) { const tag = bufferDecoder.getUnsignedVarint32(); const wireType = tagToWireType(tag); const fieldNumber = tagToFieldNumber(tag); checkCriticalState(fieldNumber > 0, `Invalid field number ${fieldNumber}`); addIndexEntry(storage, fieldNumber, wireType, bufferDecoder.cursor()); skipField(bufferDecoder, wireType, fieldNumber); } return storage; } exports = { buildIndex, tagToWireType, };