indexer.js 1.8 KB

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