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