Skip to content

Commit

Permalink
Project import generated by Copybara
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 298409332
  • Loading branch information
rafi-kamal authored and copybara-github committed Mar 2, 2020
1 parent 4ff0fb8 commit 64f151f
Showing 1 changed file with 78 additions and 100 deletions.
178 changes: 78 additions & 100 deletions js/experimental/runtime/kernel/indexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,118 +47,96 @@ function tagToFieldNumber(tag) {
}

/**
* An Indexer that indexes a given binary protobuf by fieldnumber.
* Creates an index of field locations in a given binary protobuf.
* @param {!BufferDecoder} bufferDecoder
* @param {number|undefined} pivot
* @return {!Storage<!Field>}
* @package
*/
class Indexer {
/**
* @param {!BufferDecoder} bufferDecoder
* @private
*/
constructor(bufferDecoder) {
/** @private @const {!BufferDecoder} */
this.bufferDecoder_ = bufferDecoder;
}

/**
* @param {number|undefined} pivot
* @return {!Storage<!Field>}
*/
index(pivot) {
this.bufferDecoder_.setCursor(this.bufferDecoder_.startIndex());

const storage = new Storage(pivot);
while (this.bufferDecoder_.hasNext()) {
const tag = this.bufferDecoder_.getUnsignedVarint32();
const wireType = tagToWireType(tag);
const fieldNumber = tagToFieldNumber(tag);
checkCriticalState(
fieldNumber > 0, `Invalid field number ${fieldNumber}`);
function buildIndex(bufferDecoder, pivot) {
bufferDecoder.setCursor(bufferDecoder.startIndex());

addIndexEntry(
storage, fieldNumber, wireType, this.bufferDecoder_.cursor());
const storage = new Storage(pivot);
while (bufferDecoder.hasNext()) {
const tag = bufferDecoder.getUnsignedVarint32();
const wireType = tagToWireType(tag);
const fieldNumber = tagToFieldNumber(tag);
checkCriticalState(fieldNumber > 0, `Invalid field number ${fieldNumber}`);

checkCriticalState(
!this.skipField_(wireType, fieldNumber),
'Found unmatched stop group.');
}
return storage;
}
addIndexEntry(storage, fieldNumber, wireType, bufferDecoder.cursor());

/**
* Skips over fields until the next field of the message.
* @param {!WireType} wireType
* @param {number} fieldNumber
* @return {boolean} Whether the field we skipped over was a stop group.
* @private
*/
skipField_(wireType, fieldNumber) {
switch (wireType) {
case WireType.VARINT:
checkCriticalElementIndex(
this.bufferDecoder_.cursor(), this.bufferDecoder_.endIndex());
this.bufferDecoder_.skipVarint(this.bufferDecoder_.cursor());
return false;
case WireType.FIXED64:
this.bufferDecoder_.skip(8);
return false;
case WireType.DELIMITED:
checkCriticalElementIndex(
this.bufferDecoder_.cursor(), this.bufferDecoder_.endIndex());
const length = this.bufferDecoder_.getUnsignedVarint32();
this.bufferDecoder_.skip(length);
return false;
case WireType.START_GROUP:
checkCriticalState(this.skipGroup_(fieldNumber), 'No end group found.');
return false;
case WireType.END_GROUP:
// Signal that we found a stop group to the caller
return true;
case WireType.FIXED32:
this.bufferDecoder_.skip(4);
return false;
default:
throw new Error(`Invalid wire type: ${wireType}`);
}
checkCriticalState(
!skipField_(bufferDecoder, wireType, fieldNumber),
'Found unmatched stop group.');
}
return storage;
}

/**
* Skips over fields until it finds the end of a given group.
* @param {number} groupFieldNumber
* @return {boolean} Returns true if an end was found.
* @private
*/
skipGroup_(groupFieldNumber) {
// On a start group we need to keep skipping fields until we find a
// corresponding stop group
// Note: Since we are calling skipField from here nested groups will be
// handled by recursion of this method and thus we will not see a nested
// STOP GROUP here unless there is something wrong with the input data.
while (this.bufferDecoder_.hasNext()) {
const tag = this.bufferDecoder_.getUnsignedVarint32();
const wireType = tagToWireType(tag);
const fieldNumber = tagToFieldNumber(tag);

if (this.skipField_(wireType, fieldNumber)) {
checkCriticalState(
groupFieldNumber === fieldNumber,
`Expected stop group for fieldnumber ${
groupFieldNumber} not found.`);
return true;
}
}
return false;
/**
* Skips over fields until the next field of the message.
* @param {!BufferDecoder} bufferDecoder
* @param {!WireType} wireType
* @param {number} fieldNumber
* @return {boolean} Whether the field we skipped over was a stop group.
* @private
*/
function skipField_(bufferDecoder, wireType, fieldNumber) {
switch (wireType) {
case WireType.VARINT:
checkCriticalElementIndex(
bufferDecoder.cursor(), bufferDecoder.endIndex());
bufferDecoder.skipVarint(bufferDecoder.cursor());
return false;
case WireType.FIXED64:
bufferDecoder.skip(8);
return false;
case WireType.DELIMITED:
checkCriticalElementIndex(
bufferDecoder.cursor(), bufferDecoder.endIndex());
const length = bufferDecoder.getUnsignedVarint32();
bufferDecoder.skip(length);
return false;
case WireType.START_GROUP:
checkCriticalState(
skipGroup_(bufferDecoder, fieldNumber), 'No end group found.');
return false;
case WireType.END_GROUP:
// Signal that we found a stop group to the caller
return true;
case WireType.FIXED32:
bufferDecoder.skip(4);
return false;
default:
throw new Error(`Invalid wire type: ${wireType}`);
}
}

/**
* Creates an index of field locations in a given binary protobuf.
* Skips over fields until it finds the end of a given group.
* @param {!BufferDecoder} bufferDecoder
* @param {number|undefined} pivot
* @return {!Storage<!Field>}
* @package
* @param {number} groupFieldNumber
* @return {boolean} Returns true if an end was found.
* @private
*/
function buildIndex(bufferDecoder, pivot) {
return new Indexer(bufferDecoder).index(pivot);
function skipGroup_(bufferDecoder, groupFieldNumber) {
// On a start group we need to keep skipping fields until we find a
// corresponding stop group
// Note: Since we are calling skipField from here nested groups will be
// handled by recursion of this method and thus we will not see a nested
// STOP GROUP here unless there is something wrong with the input data.
while (bufferDecoder.hasNext()) {
const tag = bufferDecoder.getUnsignedVarint32();
const wireType = tagToWireType(tag);
const fieldNumber = tagToFieldNumber(tag);

if (skipField_(bufferDecoder, wireType, fieldNumber)) {
checkCriticalState(
groupFieldNumber === fieldNumber,
`Expected stop group for fieldnumber ${groupFieldNumber} not found.`);
return true;
}
}
return false;
}

exports = {
Expand Down

0 comments on commit 64f151f

Please sign in to comment.