function autoParenter(data, parent) {
  if (!parent) {
    // Defaults to `data` unless specified otherwise.
    parent = data;
  }
  if (!data) {
    // This allows `autoParenter(undefined)` which again allows
    // `autoParenter(parse())` where the function may return nothing.
    return data;
  }
  const proxy = new Proxy(data, {
    get(target, p) {
      const value = target[p];
      if (Array.isArray(value) && p !== "source") {
        // Wraps the array so that any added items will also automatically
        // get their `parent` values.
        return autoParenter(value, target);
      }
      return value;
    },
    set(target, p, value) {
      // @ts-ignore https://github.com/microsoft/TypeScript/issues/47357
      target[p] = value;
      if (!value) {
        return true;
      } else if (Array.isArray(value)) {
        // Assigning an array will add `parent` to its items.
        for (const item of value) {
          if (typeof item.parent !== "undefined") {
            item.parent = parent;
          }
        }
      } else if (typeof value.parent !== "undefined") {
        value.parent = parent;
      }
      return true;
    },
  });
  return proxy;
}
Returns a proxy that auto-assign `parent` field.
@template {Record<string | symbol, any>} T
@param {T} data
@param {*} [parent] The object that will be assigned to `parent`.
                    If absent, it will be `data` by default.
@return {T}