function pushSerializeAndPop(
  object,
  serializersNS,
  nodeFactory,
  values,
  objectStack,
  keys,
  thisArg,
) {
  objectStack.push(object);
  serialize(serializersNS, nodeFactory, values, objectStack, keys, thisArg);
  return /** @type {O|undefined} */ (objectStack.pop());
}
@param {O} object Object.
@param {Object<string, Object<string, Serializer>>} serializersNS
    Namespaced serializers.
@param {function(this: T, *, Array<*>, (string|undefined)): (Node|undefined)} nodeFactory
    Node factory. The `nodeFactory` creates the node whose namespace and name
    will be used to choose a node writer from `serializersNS`. This
    separation allows us to decide what kind of node to create, depending on
    the value we want to serialize. An example for this would be different
    geometry writers based on the geometry type.
@param {Array<*>} values Values to serialize. An example would be an array
    of {@link module:ol/Feature~Feature} instances.
@param {Array<*>} objectStack Node stack.
@param {Array<string>} [keys] Keys of the `values`. Will be passed to the
    `nodeFactory`. This is used for serializing object literals where the
    node name relates to the property key. The array length of `keys` has
    to match the length of `values`. For serializing a sequence, `keys`
    determines the order of the sequence.
@param {T} [thisArg] The object to use as `this` for the node factory and
    serializers.
@return {O|undefined} Object.
@template O, T