Spaces:
Runtime error
Runtime error
| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| import { Field } from '../schema.js'; | |
| import { DataBufferBuilder } from './buffer.js'; | |
| import { Builder, BuilderOptions } from '../builder.js'; | |
| import { Union, SparseUnion, DenseUnion } from '../type.js'; | |
| export interface UnionBuilderOptions<T extends Union = any, TNull = any> extends BuilderOptions<T, TNull> { | |
| valueToChildTypeId?: (builder: UnionBuilder<T, TNull>, value: any, offset: number) => number; | |
| } | |
| /** @ignore */ | |
| export abstract class UnionBuilder<T extends Union, TNull = any> extends Builder<T, TNull> { | |
| protected _typeIds: DataBufferBuilder<Int8Array>; | |
| constructor(options: UnionBuilderOptions<T, TNull>) { | |
| super(options); | |
| this._typeIds = new DataBufferBuilder(new Int8Array(0), 1); | |
| if (typeof options['valueToChildTypeId'] === 'function') { | |
| this._valueToChildTypeId = options['valueToChildTypeId']; | |
| } | |
| } | |
| public get typeIdToChildIndex() { return this.type.typeIdToChildIndex; } | |
| public append(value: T['TValue'] | TNull, childTypeId?: number) { | |
| return this.set(this.length, value, childTypeId); | |
| } | |
| public set(index: number, value: T['TValue'] | TNull, childTypeId?: number) { | |
| if (childTypeId === undefined) { | |
| childTypeId = this._valueToChildTypeId(this, value, index); | |
| } | |
| if (this.setValid(index, this.isValid(value))) { | |
| this.setValue(index, value, childTypeId); | |
| } | |
| return this; | |
| } | |
| public setValue(index: number, value: T['TValue'], childTypeId?: number) { | |
| this._typeIds.set(index, childTypeId!); | |
| const childIndex = this.type.typeIdToChildIndex[childTypeId!]; | |
| const child = this.children[childIndex]; | |
| child?.set(index, value); | |
| } | |
| public addChild(child: Builder, name = `${this.children.length}`) { | |
| const childTypeId = this.children.push(child); | |
| const { type: { children, mode, typeIds } } = this; | |
| const fields = [...children, new Field(name, child.type)]; | |
| this.type = <T>new Union(mode, [...typeIds, childTypeId], fields); | |
| return childTypeId; | |
| } | |
| /** @ignore */ | |
| // @ts-ignore | |
| protected _valueToChildTypeId(builder: UnionBuilder<T, TNull>, value: any, offset: number): number { | |
| throw new Error(`Cannot map UnionBuilder value to child typeId. \ | |
| Pass the \`childTypeId\` as the second argument to unionBuilder.append(), \ | |
| or supply a \`valueToChildTypeId\` function as part of the UnionBuilder constructor options.`); | |
| } | |
| } | |
| /** @ignore */ | |
| export class SparseUnionBuilder<T extends SparseUnion, TNull = any> extends UnionBuilder<T, TNull> { } | |
| /** @ignore */ | |
| export class DenseUnionBuilder<T extends DenseUnion, TNull = any> extends UnionBuilder<T, TNull> { | |
| protected _offsets: DataBufferBuilder<Int32Array>; | |
| constructor(options: UnionBuilderOptions<T, TNull>) { | |
| super(options); | |
| this._offsets = new DataBufferBuilder(new Int32Array(0)); | |
| } | |
| /** @ignore */ | |
| public setValue(index: number, value: T['TValue'], childTypeId?: number) { | |
| const id = this._typeIds.set(index, childTypeId!).buffer[index]; | |
| const child = this.getChildAt(this.type.typeIdToChildIndex[id])!; | |
| const denseIndex = this._offsets.set(index, child.length).buffer[index]; | |
| child?.set(denseIndex, value); | |
| } | |
| } | |