// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:collection';
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';

/**
 * Reader of lists of boolean values.
 *
 * The returned unmodifiable lists lazily read values on access.
 */
class BoolListReader extends Reader<List<bool>> {
  const BoolListReader();

  @override
  int get size => 4;

  @override
  List<bool> read(BufferContext bc, int offset) =>
      new _FbBoolList(bc, bc.derefObject(offset));
}

/**
 * The reader of booleans.
 */
class BoolReader extends Reader<bool> {
  const BoolReader() : super();

  @override
  int get size => 1;

  @override
  bool read(BufferContext bc, int offset) => bc._getInt8(offset) != 0;
}

/**
 * Buffer with data and some context about it.
 */
class BufferContext {
  final ByteData _buffer;

  factory BufferContext.fromBytes(List<int> byteList) {
    Uint8List uint8List = _asUint8List(byteList);
    ByteData buf = new ByteData.view(uint8List.buffer, uint8List.offsetInBytes);
    return new BufferContext._(buf);
  }

  BufferContext._(this._buffer);

  int derefObject(int offset) {
    return offset + _getUint32(offset);
  }

  Uint8List _asUint8LIst(int offset, int length) =>
      _buffer.buffer.asUint8List(_buffer.offsetInBytes + offset, length);

  double _getFloat64(int offset) => _buffer.getFloat64(offset, Endian.little);

  int _getInt32(int offset) => _buffer.getInt32(offset, Endian.little);

  int _getInt8(int offset) => _buffer.getInt8(offset);

  int _getUint16(int offset) => _buffer.getUint16(offset, Endian.little);

  int _getUint32(int offset) => _buffer.getUint32(offset, Endian.little);

  int _getUint8(int offset) => _buffer.getUint8(offset);

  /**
   * If the [byteList] is already a [Uint8List] return it.
   * Otherwise return a [Uint8List] copy of the [byteList].
   */
  static Uint8List _asUint8List(List<int> byteList) {
    if (byteList is Uint8List) {
      return byteList;
    } else {
      return new Uint8List.fromList(byteList);
    }
  }
}

/**
 * Class that helps building flat buffers.
 */
class Builder {
  final int initialSize;

  /**
   * The list of existing VTable(s).
   */
  final List<_VTable> _vTables = <_VTable>[];

  ByteData _buf;

  /**
   * The maximum alignment that has been seen so far.  If [_buf] has to be
   * reallocated in the future (to insert room at its start for more bytes) the
   * reallocation will need to be a multiple of this many bytes.
   */
  int _maxAlign;

  /**
   * The number of bytes that have been written to the buffer so far.  The
   * most recently written byte is this many bytes from the end of [_buf].
   */
  int _tail;

  /**
   * The location of the end of the current table, measured in bytes from the
   * end of [_buf], or `null` if a table is not currently being built.
   */
  int _currentTableEndTail;

  _VTable _currentVTable;

  /**
   * Map containing all strings that have been written so far.  This allows us
   * to avoid duplicating strings.
   */
  Map<String, Offset<String>> _strings = <String, Offset<String>>{};

  Builder({this.initialSize: 1024}) {
    reset();
  }

  /**
   * Add the [field] with the given boolean [value].  The field is not added if
   * the [value] is equal to [def].  Booleans are stored as 8-bit fields with
   * `0` for `false` and `1` for `true`.
   */
  void addBool(int field, bool value, [bool def]) {
    _ensureCurrentVTable();
    if (value != null && value != def) {
      int size = 1;
      _prepare(size, 1);
      _trackField(field);
      _buf.setInt8(_buf.lengthInBytes - _tail, value ? 1 : 0);
    }
  }

  /**
   * Add the [field] with the given 32-bit signed integer [value].  The field is
   * not added if the [value] is equal to [def].
   */
  void addInt32(int field, int value, [int def]) {
    _ensureCurrentVTable();
    if (value != null && value != def) {
      int size = 4;
      _prepare(size, 1);
      _trackField(field);
      _setInt32AtTail(_buf, _tail, value);
    }
  }

  /**
   * Add the [field] with the given 8-bit signed integer [value].  The field is
   * not added if the [value] is equal to [def].
   */
  void addInt8(int field, int value, [int def]) {
    _ensureCurrentVTable();
    if (value != null && value != def) {
      int size = 1;
      _prepare(size, 1);
      _trackField(field);
      _buf.setInt8(_buf.lengthInBytes - _tail, value);
    }
  }

  /**
   * Add the [field] referencing an object with the given [offset].
   */
  void addOffset(int field, Offset offset) {
    _ensureCurrentVTable();
    if (offset != null) {
      _prepare(4, 1);
      _trackField(field);
      _setUint32AtTail(_buf, _tail, _tail - offset._tail);
    }
  }

  /**
   * Add the [field] with the given 32-bit unsigned integer [value].  The field
   * is not added if the [value] is equal to [def].
   */
  void addUint32(int field, int value, [int def]) {
    _ensureCurrentVTable();
    if (value != null && value != def) {
      int size = 4;
      _prepare(size, 1);
      _trackField(field);
      _setUint32AtTail(_buf, _tail, value);
    }
  }

  /**
   * Add the [field] with the given 8-bit unsigned integer [value].  The field
   * is not added if the [value] is equal to [def].
   */
  void addUint8(int field, int value, [int def]) {
    _ensureCurrentVTable();
    if (value != null && value != def) {
      int size = 1;
      _prepare(size, 1);
      _trackField(field);
      _setUint8AtTail(_buf, _tail, value);
    }
  }

  /**
   * End the current table and return its offset.
   */
  Offset endTable() {
    if (_currentVTable == null) {
      throw new StateError('Start a table before ending it.');
    }
    // Prepare for writing the VTable.
    _prepare(4, 1);
    int tableTail = _tail;
    // Prepare the size of the current table.
    _currentVTable.tableSize = tableTail - _currentTableEndTail;
    // Prepare the VTable to use for the current table.
    int vTableTail;
    {
      _currentVTable.computeFieldOffsets(tableTail);
      // Try to find an existing compatible VTable.
      for (int i = 0; i < _vTables.length; i++) {
        _VTable vTable = _vTables[i];
        if (_currentVTable.canUseExistingVTable(vTable)) {
          vTableTail = vTable.tail;
          break;
        }
      }
      // Write a new VTable.
      if (vTableTail == null) {
        _prepare(2, _currentVTable.numOfUint16);
        vTableTail = _tail;
        _currentVTable.tail = vTableTail;
        _currentVTable.output(_buf, _buf.lengthInBytes - _tail);
        _vTables.add(_currentVTable);
      }
    }
    // Set the VTable offset.
    _setInt32AtTail(_buf, tableTail, vTableTail - tableTail);
    // Done with this table.
    _currentVTable = null;
    return new Offset(tableTail);
  }

  /**
   * Finish off the creation of the buffer.  The given [offset] is used as the
   * root object offset, and usually references directly or indirectly every
   * written object.  If [fileIdentifier] is specified (and not `null`), it is
   * interpreted as a 4-byte Latin-1 encoded string that should be placed at
   * bytes 4-7 of the file.
   */
  Uint8List finish(Offset offset, [String fileIdentifier]) {
    _prepare(max(4, _maxAlign), fileIdentifier == null ? 1 : 2);
    int alignedTail = _tail + ((-_tail) % _maxAlign);
    _setUint32AtTail(_buf, alignedTail, alignedTail - offset._tail);
    if (fileIdentifier != null) {
      for (int i = 0; i < 4; i++) {
        _setUint8AtTail(
            _buf, alignedTail - 4 - i, fileIdentifier.codeUnitAt(i));
      }
    }
    return _buf.buffer.asUint8List(_buf.lengthInBytes - alignedTail);
  }

  /**
   * This is a low-level method, it should not be invoked by clients.
   */
  Uint8List lowFinish() {
    int alignedTail = _tail + ((-_tail) % _maxAlign);
    return _buf.buffer.asUint8List(_buf.lengthInBytes - alignedTail);
  }

  /**
   * This is a low-level method, it should not be invoked by clients.
   */
  void lowReset() {
    _buf = new ByteData(initialSize);
    _maxAlign = 1;
    _tail = 0;
  }

  /**
   * This is a low-level method, it should not be invoked by clients.
   */
  void lowWriteUint32(int value) {
    _prepare(4, 1);
    _setUint32AtTail(_buf, _tail, value);
  }

  /**
   * This is a low-level method, it should not be invoked by clients.
   */
  void lowWriteUint8(int value) {
    _prepare(1, 1);
    _buf.setUint8(_buf.lengthInBytes - _tail, value);
  }

  /**
   * Reset the builder and make it ready for filling a new buffer.
   */
  void reset() {
    _buf = new ByteData(initialSize);
    _maxAlign = 1;
    _tail = 0;
    _currentVTable = null;
  }

  /**
   * Start a new table.  Must be finished with [endTable] invocation.
   */
  void startTable() {
    if (_currentVTable != null) {
      throw new StateError('Inline tables are not supported.');
    }
    _currentVTable = new _VTable();
    _currentTableEndTail = _tail;
  }

  /**
   * Write the given list of [values].
   */
  Offset writeList(List<Offset> values) {
    _ensureNoVTable();
    _prepare(4, 1 + values.length);
    Offset result = new Offset(_tail);
    int tail = _tail;
    _setUint32AtTail(_buf, tail, values.length);
    tail -= 4;
    for (Offset value in values) {
      _setUint32AtTail(_buf, tail, tail - value._tail);
      tail -= 4;
    }
    return result;
  }

  /**
   * Write the given list of boolean [values].
   */
  Offset writeListBool(List<bool> values) {
    int bitLength = values.length;
    int padding = (-bitLength) % 8;
    int byteLength = (bitLength + padding) ~/ 8;
    // Prepare the backing Uint8List.
    Uint8List bytes = new Uint8List(byteLength + 1);
    // Record every bit.
    int byteIndex = 0;
    int byte = 0;
    int mask = 1;
    for (int bitIndex = 0; bitIndex < bitLength; bitIndex++) {
      if (bitIndex != 0 && (bitIndex % 8 == 0)) {
        bytes[byteIndex++] = byte;
        byte = 0;
        mask = 1;
      }
      if (values[bitIndex]) {
        byte |= mask;
      }
      mask <<= 1;
    }
    // Write the last byte, even if it may be on the padding.
    bytes[byteIndex] = byte;
    // Write the padding length.
    bytes[byteLength] = padding;
    // Write as a Uint8 list.
    return writeListUint8(bytes);
  }

  /**
   * Write the given list of 64-bit float [values].
   */
  Offset writeListFloat64(List<double> values) {
    _ensureNoVTable();
    _prepare(8, 1 + values.length);
    Offset result = new Offset(_tail);
    int tail = _tail;
    _setUint32AtTail(_buf, tail, values.length);
    tail -= 8;
    for (double value in values) {
      _setFloat64AtTail(_buf, tail, value);
      tail -= 8;
    }
    return result;
  }

  /**
   * Write the given list of signed 32-bit integer [values].
   */
  Offset writeListInt32(List<int> values) {
    _ensureNoVTable();
    _prepare(4, 1 + values.length);
    Offset result = new Offset(_tail);
    int tail = _tail;
    _setUint32AtTail(_buf, tail, values.length);
    tail -= 4;
    for (int value in values) {
      _setInt32AtTail(_buf, tail, value);
      tail -= 4;
    }
    return result;
  }

  /**
   * Write the given list of unsigned 32-bit integer [values].
   */
  Offset writeListUint32(List<int> values) {
    _ensureNoVTable();
    _prepare(4, 1 + values.length);
    Offset result = new Offset(_tail);
    int tail = _tail;
    _setUint32AtTail(_buf, tail, values.length);
    tail -= 4;
    for (int value in values) {
      _setUint32AtTail(_buf, tail, value);
      tail -= 4;
    }
    return result;
  }

  /**
   * Write the given list of unsigned 8-bit integer [values].
   */
  Offset writeListUint8(List<int> values) {
    _ensureNoVTable();
    _prepare(4, 1, additionalBytes: values.length);
    Offset result = new Offset(_tail);
    int tail = _tail;
    _setUint32AtTail(_buf, tail, values.length);
    tail -= 4;
    for (int value in values) {
      _setUint8AtTail(_buf, tail, value);
      tail -= 1;
    }
    return result;
  }

  /**
   * Write the given string [value] and return its [Offset], or `null` if
   * the [value] is equal to [def].
   */
  Offset<String> writeString(String value, [String def]) {
    _ensureNoVTable();
    if (value != def) {
      return _strings.putIfAbsent(value, () {
        // TODO(scheglov) optimize for ASCII strings
        List<int> bytes = utf8.encode(value);
        int length = bytes.length;
        _prepare(4, 1, additionalBytes: length);
        Offset<String> result = new Offset(_tail);
        _setUint32AtTail(_buf, _tail, length);
        int offset = _buf.lengthInBytes - _tail + 4;
        for (int i = 0; i < length; i++) {
          _buf.setUint8(offset++, bytes[i]);
        }
        return result;
      });
    }
    return null;
  }

  /**
   * Throw an exception if there is not currently a vtable.
   */
  void _ensureCurrentVTable() {
    if (_currentVTable == null) {
      throw new StateError('Start a table before adding values.');
    }
  }

  /**
   * Throw an exception if there is currently a vtable.
   */
  void _ensureNoVTable() {
    if (_currentVTable != null) {
      throw new StateError(
          'Cannot write a non-scalar value while writing a table.');
    }
  }

  /**
   * Prepare for writing the given [count] of scalars of the given [size].
   * Additionally allocate the specified [additionalBytes]. Update the current
   * tail pointer to point at the allocated space.
   */
  void _prepare(int size, int count, {int additionalBytes: 0}) {
    // Update the alignment.
    if (_maxAlign < size) {
      _maxAlign = size;
    }
    // Prepare amount of required space.
    int dataSize = size * count + additionalBytes;
    int alignDelta = (-(_tail + dataSize)) % size;
    int bufSize = alignDelta + dataSize;
    // Ensure that we have the required amount of space.
    {
      int oldCapacity = _buf.lengthInBytes;
      if (_tail + bufSize > oldCapacity) {
        int desiredNewCapacity = (oldCapacity + bufSize) * 2;
        int deltaCapacity = desiredNewCapacity - oldCapacity;
        deltaCapacity += (-deltaCapacity) % _maxAlign;
        int newCapacity = oldCapacity + deltaCapacity;
        ByteData newBuf = new ByteData(newCapacity);
        newBuf.buffer
            .asUint8List()
            .setAll(deltaCapacity, _buf.buffer.asUint8List());
        _buf = newBuf;
      }
    }
    // Update the tail pointer.
    _tail += bufSize;
  }

  /**
   * Record the offset of the given [field].
   */
  void _trackField(int field) {
    _currentVTable.addField(field, _tail);
  }

  static void _setFloat64AtTail(ByteData _buf, int tail, double x) {
    _buf.setFloat64(_buf.lengthInBytes - tail, x, Endian.little);
  }

  static void _setInt32AtTail(ByteData _buf, int tail, int x) {
    _buf.setInt32(_buf.lengthInBytes - tail, x, Endian.little);
  }

  static void _setUint32AtTail(ByteData _buf, int tail, int x) {
    _buf.setUint32(_buf.lengthInBytes - tail, x, Endian.little);
  }

  static void _setUint8AtTail(ByteData _buf, int tail, int x) {
    _buf.setUint8(_buf.lengthInBytes - tail, x);
  }
}

/**
 * The reader of lists of 64-bit float values.
 *
 * The returned unmodifiable lists lazily read values on access.
 */
class Float64ListReader extends Reader<List<double>> {
  const Float64ListReader();

  @override
  int get size => 4;

  @override
  List<double> read(BufferContext bc, int offset) =>
      new _FbFloat64List(bc, bc.derefObject(offset));
}

/**
 * The reader of signed 32-bit integers.
 */
class Int32Reader extends Reader<int> {
  const Int32Reader() : super();

  @override
  int get size => 4;

  @override
  int read(BufferContext bc, int offset) => bc._getInt32(offset);
}

/**
 * The reader of 8-bit signed integers.
 */
class Int8Reader extends Reader<int> {
  const Int8Reader() : super();

  @override
  int get size => 1;

  @override
  int read(BufferContext bc, int offset) => bc._getInt8(offset);
}

/**
 * The reader of lists of objects.
 *
 * The returned unmodifiable lists lazily read objects on access.
 */
class ListReader<E> extends Reader<List<E>> {
  final Reader<E> _elementReader;

  const ListReader(this._elementReader);

  @override
  int get size => 4;

  @override
  List<E> read(BufferContext bc, int offset) =>
      new _FbGenericList<E>(_elementReader, bc, bc.derefObject(offset));
}

/**
 * The offset from the end of the buffer to a serialized object of the type [T].
 */
class Offset<T> {
  final int _tail;

  Offset(this._tail);
}

/**
 * Object that can read a value at a [BufferContext].
 */
abstract class Reader<T> {
  const Reader();

  /**
   * The size of the value in bytes.
   */
  int get size;

  /**
   * Read the value at the given [offset] in [bc].
   */
  T read(BufferContext bc, int offset);

  /**
   * Read the value of the given [field] in the given [object].
   */
  T vTableGet(BufferContext object, int offset, int field, [T defaultValue]) {
    int vTableSOffset = object._getInt32(offset);
    int vTableOffset = offset - vTableSOffset;
    int vTableSize = object._getUint16(vTableOffset);
    int vTableFieldOffset = (1 + 1 + field) * 2;
    if (vTableFieldOffset < vTableSize) {
      int fieldOffsetInObject =
          object._getUint16(vTableOffset + vTableFieldOffset);
      if (fieldOffsetInObject != 0) {
        return read(object, offset + fieldOffsetInObject);
      }
    }
    return defaultValue;
  }
}

/**
 * The reader of string values.
 */
class StringReader extends Reader<String> {
  const StringReader() : super();

  @override
  int get size => 4;

  @override
  String read(BufferContext bc, int offset) {
    int strOffset = bc.derefObject(offset);
    int length = bc._getUint32(strOffset);
    Uint8List bytes = bc._asUint8LIst(strOffset + 4, length);
    if (_isLatin(bytes)) {
      return new String.fromCharCodes(bytes);
    }
    return utf8.decode(bytes);
  }

  static bool _isLatin(Uint8List bytes) {
    int length = bytes.length;
    for (int i = 0; i < length; i++) {
      if (bytes[i] > 127) {
        return false;
      }
    }
    return true;
  }
}

/**
 * An abstract reader for tables.
 */
abstract class TableReader<T> extends Reader<T> {
  const TableReader();

  @override
  int get size => 4;

  /**
   * Return the object at [offset].
   */
  T createObject(BufferContext bc, int offset);

  @override
  T read(BufferContext bp, int offset) {
    int objectOffset = bp.derefObject(offset);
    return createObject(bp, objectOffset);
  }
}

/**
 * Reader of lists of unsigned 32-bit integer values.
 *
 * The returned unmodifiable lists lazily read values on access.
 */
class Uint32ListReader extends Reader<List<int>> {
  const Uint32ListReader();

  @override
  int get size => 4;

  @override
  List<int> read(BufferContext bc, int offset) =>
      new _FbUint32List(bc, bc.derefObject(offset));
}

/**
 * The reader of unsigned 32-bit integers.
 */
class Uint32Reader extends Reader<int> {
  const Uint32Reader() : super();

  @override
  int get size => 4;

  @override
  int read(BufferContext bc, int offset) => bc._getUint32(offset);
}

/**
 * Reader of lists of unsigned 8-bit integer values.
 *
 * The returned unmodifiable lists lazily read values on access.
 */
class Uint8ListReader extends Reader<List<int>> {
  const Uint8ListReader();

  @override
  int get size => 4;

  @override
  List<int> read(BufferContext bc, int offset) =>
      new _FbUint8List(bc, bc.derefObject(offset));
}

/**
 * The reader of unsigned 8-bit integers.
 */
class Uint8Reader extends Reader<int> {
  const Uint8Reader() : super();

  @override
  int get size => 1;

  @override
  int read(BufferContext bc, int offset) => bc._getUint8(offset);
}

/**
 * List of booleans backed by 8-bit unsigned integers.
 */
class _FbBoolList with ListMixin<bool> implements List<bool> {
  final BufferContext bc;
  final int offset;
  int _length;

  _FbBoolList(this.bc, this.offset);

  @override
  int get length {
    if (_length == null) {
      int byteLength = bc._getUint32(offset);
      _length = (byteLength - 1) * 8 - _getByte(byteLength - 1);
    }
    return _length;
  }

  @override
  void set length(int i) =>
      throw new StateError('Attempt to modify immutable list');

  @override
  bool operator [](int i) {
    int index = i ~/ 8;
    int mask = 1 << i % 8;
    return _getByte(index) & mask != 0;
  }

  @override
  void operator []=(int i, bool e) =>
      throw new StateError('Attempt to modify immutable list');

  int _getByte(int index) => bc._getUint8(offset + 4 + index);
}

/**
 * The list backed by 64-bit values - Uint64 length and Float64.
 */
class _FbFloat64List extends _FbList<double> {
  _FbFloat64List(BufferContext bc, int offset) : super(bc, offset);

  @override
  double operator [](int i) {
    return bc._getFloat64(offset + 8 + 8 * i);
  }
}

/**
 * List backed by a generic object which may have any size.
 */
class _FbGenericList<E> extends _FbList<E> {
  final Reader<E> elementReader;

  List<E> _items;

  _FbGenericList(this.elementReader, BufferContext bp, int offset)
      : super(bp, offset);

  @override
  E operator [](int i) {
    _items ??= new List<E>(length);
    E item = _items[i];
    if (item == null) {
      item = elementReader.read(bc, offset + 4 + elementReader.size * i);
      _items[i] = item;
    }
    return item;
  }
}

/**
 * The base class for immutable lists read from flat buffers.
 */
abstract class _FbList<E> with ListMixin<E> implements List<E> {
  final BufferContext bc;
  final int offset;
  int _length;

  _FbList(this.bc, this.offset);

  @override
  int get length {
    _length ??= bc._getUint32(offset);
    return _length;
  }

  @override
  void set length(int i) =>
      throw new StateError('Attempt to modify immutable list');

  @override
  void operator []=(int i, E e) =>
      throw new StateError('Attempt to modify immutable list');
}

/**
 * List backed by 32-bit unsigned integers.
 */
class _FbUint32List extends _FbList<int> {
  _FbUint32List(BufferContext bc, int offset) : super(bc, offset);

  @override
  int operator [](int i) {
    return bc._getUint32(offset + 4 + 4 * i);
  }
}

/**
 * List backed by 8-bit unsigned integers.
 */
class _FbUint8List extends _FbList<int> {
  _FbUint8List(BufferContext bc, int offset) : super(bc, offset);

  @override
  int operator [](int i) {
    return bc._getUint8(offset + 4 + i);
  }
}

/**
 * Class that describes the structure of a table.
 */
class _VTable {
  final List<int> fieldTails = <int>[];
  final List<int> fieldOffsets = <int>[];

  /**
   * The size of the table that uses this VTable.
   */
  int tableSize;

  /**
   * The tail of this VTable.  It is used to share the same VTable between
   * multiple tables of identical structure.
   */
  int tail;

  int get numOfUint16 => 1 + 1 + fieldTails.length;

  void addField(int field, int offset) {
    while (fieldTails.length <= field) {
      fieldTails.add(null);
    }
    fieldTails[field] = offset;
  }

  /**
   * Return `true` if the [existing] VTable can be used instead of this.
   */
  bool canUseExistingVTable(_VTable existing) {
    assert(tail == null);
    assert(existing.tail != null);
    if (tableSize == existing.tableSize &&
        fieldOffsets.length == existing.fieldOffsets.length) {
      for (int i = 0; i < fieldOffsets.length; i++) {
        if (fieldOffsets[i] != existing.fieldOffsets[i]) {
          return false;
        }
      }
      return true;
    }
    return false;
  }

  /**
   * Fill the [fieldOffsets] field.
   */
  void computeFieldOffsets(int tableTail) {
    assert(fieldOffsets.isEmpty);
    for (int fieldTail in fieldTails) {
      int fieldOffset = fieldTail == null ? 0 : tableTail - fieldTail;
      fieldOffsets.add(fieldOffset);
    }
  }

  /**
   * Outputs this VTable to [buf], which is is expected to be aligned to 16-bit
   * and have at least [numOfUint16] 16-bit words available.
   */
  void output(ByteData buf, int bufOffset) {
    // VTable size.
    buf.setUint16(bufOffset, numOfUint16 * 2, Endian.little);
    bufOffset += 2;
    // Table size.
    buf.setUint16(bufOffset, tableSize, Endian.little);
    bufOffset += 2;
    // Field offsets.
    for (int fieldOffset in fieldOffsets) {
      buf.setUint16(bufOffset, fieldOffset, Endian.little);
      bufOffset += 2;
    }
  }
}
