iw6-mod/deps/protobuf/js/experimental/runtime/kernel/indexer.js
2024-02-27 01:34:37 -05:00

56 lines
1.8 KiB
JavaScript

/**
* @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<!Field>} 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<!Field>}
* @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,
};