| // 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 { Data } from './data'; |
| import { Vector } from './vector'; |
| import { Type, Precision, DateUnit, TimeUnit, IntervalUnit, UnionMode } from './enum'; |
| import { DataType, Float, Int, Date_, Interval, Time, Timestamp, Union, } from './type'; |
| |
| export abstract class Visitor { |
| public visitMany(nodes: any[], ...args: any[][]) { |
| return nodes.map((node, i) => this.visit(node, ...args.map((x) => x[i]))); |
| } |
| public visit(...args: any[]) { |
| return this.getVisitFn(args[0], false).apply(this, args); |
| } |
| public getVisitFn(node: any, throwIfNotFound = true) { |
| return getVisitFn(this, node, throwIfNotFound); |
| } |
| public visitNull (_node: any, ..._args: any[]): any { return null; } |
| public visitBool (_node: any, ..._args: any[]): any { return null; } |
| public visitInt (_node: any, ..._args: any[]): any { return null; } |
| public visitFloat (_node: any, ..._args: any[]): any { return null; } |
| public visitUtf8 (_node: any, ..._args: any[]): any { return null; } |
| public visitBinary (_node: any, ..._args: any[]): any { return null; } |
| public visitFixedSizeBinary (_node: any, ..._args: any[]): any { return null; } |
| public visitDate (_node: any, ..._args: any[]): any { return null; } |
| public visitTimestamp (_node: any, ..._args: any[]): any { return null; } |
| public visitTime (_node: any, ..._args: any[]): any { return null; } |
| public visitDecimal (_node: any, ..._args: any[]): any { return null; } |
| public visitList (_node: any, ..._args: any[]): any { return null; } |
| public visitStruct (_node: any, ..._args: any[]): any { return null; } |
| public visitUnion (_node: any, ..._args: any[]): any { return null; } |
| public visitDictionary (_node: any, ..._args: any[]): any { return null; } |
| public visitInterval (_node: any, ..._args: any[]): any { return null; } |
| public visitFixedSizeList (_node: any, ..._args: any[]): any { return null; } |
| public visitMap (_node: any, ..._args: any[]): any { return null; } |
| } |
| |
| /** @ignore */ |
| function getVisitFn<T extends DataType>(visitor: Visitor, node: any, throwIfNotFound = true) { |
| let fn: any = null; |
| let dtype: T['TType'] = Type.NONE; |
| // tslint:disable |
| if (node instanceof Data ) { dtype = inferDType(node.type as T); } |
| else if (node instanceof Vector ) { dtype = inferDType(node.type as T); } |
| else if (node instanceof DataType) { dtype = inferDType(node as T); } |
| else if (typeof (dtype = node) !== 'number') { dtype = Type[node] as any as T['TType']; } |
| |
| switch (dtype) { |
| case Type.Null: fn = visitor.visitNull; break; |
| case Type.Bool: fn = visitor.visitBool; break; |
| case Type.Int: fn = visitor.visitInt; break; |
| case Type.Int8: fn = visitor.visitInt8 || visitor.visitInt; break; |
| case Type.Int16: fn = visitor.visitInt16 || visitor.visitInt; break; |
| case Type.Int32: fn = visitor.visitInt32 || visitor.visitInt; break; |
| case Type.Int64: fn = visitor.visitInt64 || visitor.visitInt; break; |
| case Type.Uint8: fn = visitor.visitUint8 || visitor.visitInt; break; |
| case Type.Uint16: fn = visitor.visitUint16 || visitor.visitInt; break; |
| case Type.Uint32: fn = visitor.visitUint32 || visitor.visitInt; break; |
| case Type.Uint64: fn = visitor.visitUint64 || visitor.visitInt; break; |
| case Type.Float: fn = visitor.visitFloat; break; |
| case Type.Float16: fn = visitor.visitFloat16 || visitor.visitFloat; break; |
| case Type.Float32: fn = visitor.visitFloat32 || visitor.visitFloat; break; |
| case Type.Float64: fn = visitor.visitFloat64 || visitor.visitFloat; break; |
| case Type.Utf8: fn = visitor.visitUtf8; break; |
| case Type.Binary: fn = visitor.visitBinary; break; |
| case Type.FixedSizeBinary: fn = visitor.visitFixedSizeBinary; break; |
| case Type.Date: fn = visitor.visitDate; break; |
| case Type.DateDay: fn = visitor.visitDateDay || visitor.visitDate; break; |
| case Type.DateMillisecond: fn = visitor.visitDateMillisecond || visitor.visitDate; break; |
| case Type.Timestamp: fn = visitor.visitTimestamp; break; |
| case Type.TimestampSecond: fn = visitor.visitTimestampSecond || visitor.visitTimestamp; break; |
| case Type.TimestampMillisecond: fn = visitor.visitTimestampMillisecond || visitor.visitTimestamp; break; |
| case Type.TimestampMicrosecond: fn = visitor.visitTimestampMicrosecond || visitor.visitTimestamp; break; |
| case Type.TimestampNanosecond: fn = visitor.visitTimestampNanosecond || visitor.visitTimestamp; break; |
| case Type.Time: fn = visitor.visitTime; break; |
| case Type.TimeSecond: fn = visitor.visitTimeSecond || visitor.visitTime; break; |
| case Type.TimeMillisecond: fn = visitor.visitTimeMillisecond || visitor.visitTime; break; |
| case Type.TimeMicrosecond: fn = visitor.visitTimeMicrosecond || visitor.visitTime; break; |
| case Type.TimeNanosecond: fn = visitor.visitTimeNanosecond || visitor.visitTime; break; |
| case Type.Decimal: fn = visitor.visitDecimal; break; |
| case Type.List: fn = visitor.visitList; break; |
| case Type.Struct: fn = visitor.visitStruct; break; |
| case Type.Union: fn = visitor.visitUnion; break; |
| case Type.DenseUnion: fn = visitor.visitDenseUnion || visitor.visitUnion; break; |
| case Type.SparseUnion: fn = visitor.visitSparseUnion || visitor.visitUnion; break; |
| case Type.Dictionary: fn = visitor.visitDictionary; break; |
| case Type.Interval: fn = visitor.visitInterval; break; |
| case Type.IntervalDayTime: fn = visitor.visitIntervalDayTime || visitor.visitInterval; break; |
| case Type.IntervalYearMonth: fn = visitor.visitIntervalYearMonth || visitor.visitInterval; break; |
| case Type.FixedSizeList: fn = visitor.visitFixedSizeList; break; |
| case Type.Map: fn = visitor.visitMap; break; |
| } |
| if (typeof fn === 'function') return fn; |
| if (!throwIfNotFound) return () => null; |
| throw new Error(`Unrecognized type '${Type[dtype]}'`); |
| } |
| |
| /** @ignore */ |
| function inferDType<T extends DataType>(type: T): Type { |
| switch (type.typeId) { |
| case Type.Null: return Type.Null; |
| case Type.Int: |
| const { bitWidth, isSigned } = (type as any as Int); |
| switch (bitWidth) { |
| case 8: return isSigned ? Type.Int8 : Type.Uint8 ; |
| case 16: return isSigned ? Type.Int16 : Type.Uint16; |
| case 32: return isSigned ? Type.Int32 : Type.Uint32; |
| case 64: return isSigned ? Type.Int64 : Type.Uint64; |
| } |
| return Type.Int; |
| case Type.Float: |
| switch((type as any as Float).precision) { |
| case Precision.HALF: return Type.Float16; |
| case Precision.SINGLE: return Type.Float32; |
| case Precision.DOUBLE: return Type.Float64; |
| } |
| return Type.Float; |
| case Type.Binary: return Type.Binary; |
| case Type.Utf8: return Type.Utf8; |
| case Type.Bool: return Type.Bool; |
| case Type.Decimal: return Type.Decimal; |
| case Type.Time: |
| switch ((type as any as Time).unit) { |
| case TimeUnit.SECOND: return Type.TimeSecond; |
| case TimeUnit.MILLISECOND: return Type.TimeMillisecond; |
| case TimeUnit.MICROSECOND: return Type.TimeMicrosecond; |
| case TimeUnit.NANOSECOND: return Type.TimeNanosecond; |
| } |
| return Type.Time; |
| case Type.Timestamp: |
| switch ((type as any as Timestamp).unit) { |
| case TimeUnit.SECOND: return Type.TimestampSecond; |
| case TimeUnit.MILLISECOND: return Type.TimestampMillisecond; |
| case TimeUnit.MICROSECOND: return Type.TimestampMicrosecond; |
| case TimeUnit.NANOSECOND: return Type.TimestampNanosecond; |
| } |
| return Type.Timestamp; |
| case Type.Date: |
| switch ((type as any as Date_).unit) { |
| case DateUnit.DAY: return Type.DateDay; |
| case DateUnit.MILLISECOND: return Type.DateMillisecond; |
| } |
| return Type.Date; |
| case Type.Interval: |
| switch ((type as any as Interval).unit) { |
| case IntervalUnit.DAY_TIME: return Type.IntervalDayTime; |
| case IntervalUnit.YEAR_MONTH: return Type.IntervalYearMonth; |
| } |
| return Type.Interval; |
| case Type.Map: return Type.Map; |
| case Type.List: return Type.List; |
| case Type.Struct: return Type.Struct; |
| case Type.Union: |
| switch ((type as any as Union).mode) { |
| case UnionMode.Dense: return Type.DenseUnion; |
| case UnionMode.Sparse: return Type.SparseUnion; |
| } |
| return Type.Union; |
| case Type.FixedSizeBinary: return Type.FixedSizeBinary; |
| case Type.FixedSizeList: return Type.FixedSizeList; |
| case Type.Dictionary: return Type.Dictionary; |
| } |
| throw new Error(`Unrecognized type '${Type[type.typeId]}'`); |
| } |
| |
| export interface Visitor { |
| visitNull (node: any, ...args: any[]): any; |
| visitBool (node: any, ...args: any[]): any; |
| visitInt (node: any, ...args: any[]): any; |
| visitInt8? (node: any, ...args: any[]): any; |
| visitInt16? (node: any, ...args: any[]): any; |
| visitInt32? (node: any, ...args: any[]): any; |
| visitInt64? (node: any, ...args: any[]): any; |
| visitUint8? (node: any, ...args: any[]): any; |
| visitUint16? (node: any, ...args: any[]): any; |
| visitUint32? (node: any, ...args: any[]): any; |
| visitUint64? (node: any, ...args: any[]): any; |
| visitFloat (node: any, ...args: any[]): any; |
| visitFloat16? (node: any, ...args: any[]): any; |
| visitFloat32? (node: any, ...args: any[]): any; |
| visitFloat64? (node: any, ...args: any[]): any; |
| visitUtf8 (node: any, ...args: any[]): any; |
| visitBinary (node: any, ...args: any[]): any; |
| visitFixedSizeBinary (node: any, ...args: any[]): any; |
| visitDate (node: any, ...args: any[]): any; |
| visitDateDay? (node: any, ...args: any[]): any; |
| visitDateMillisecond? (node: any, ...args: any[]): any; |
| visitTimestamp (node: any, ...args: any[]): any; |
| visitTimestampSecond? (node: any, ...args: any[]): any; |
| visitTimestampMillisecond? (node: any, ...args: any[]): any; |
| visitTimestampMicrosecond? (node: any, ...args: any[]): any; |
| visitTimestampNanosecond? (node: any, ...args: any[]): any; |
| visitTime (node: any, ...args: any[]): any; |
| visitTimeSecond? (node: any, ...args: any[]): any; |
| visitTimeMillisecond? (node: any, ...args: any[]): any; |
| visitTimeMicrosecond? (node: any, ...args: any[]): any; |
| visitTimeNanosecond? (node: any, ...args: any[]): any; |
| visitDecimal (node: any, ...args: any[]): any; |
| visitList (node: any, ...args: any[]): any; |
| visitStruct (node: any, ...args: any[]): any; |
| visitUnion (node: any, ...args: any[]): any; |
| visitDenseUnion? (node: any, ...args: any[]): any; |
| visitSparseUnion? (node: any, ...args: any[]): any; |
| visitDictionary (node: any, ...args: any[]): any; |
| visitInterval (node: any, ...args: any[]): any; |
| visitIntervalDayTime? (node: any, ...args: any[]): any; |
| visitIntervalYearMonth? (node: any, ...args: any[]): any; |
| visitFixedSizeList (node: any, ...args: any[]): any; |
| visitMap (node: any, ...args: any[]): any; |
| } |
| |
| // Add these here so they're picked up by the externs creator |
| // in the build, and closure-compiler doesn't minify them away |
| (Visitor.prototype as any).visitInt8 = null; |
| (Visitor.prototype as any).visitInt16 = null; |
| (Visitor.prototype as any).visitInt32 = null; |
| (Visitor.prototype as any).visitInt64 = null; |
| (Visitor.prototype as any).visitUint8 = null; |
| (Visitor.prototype as any).visitUint16 = null; |
| (Visitor.prototype as any).visitUint32 = null; |
| (Visitor.prototype as any).visitUint64 = null; |
| (Visitor.prototype as any).visitFloat16 = null; |
| (Visitor.prototype as any).visitFloat32 = null; |
| (Visitor.prototype as any).visitFloat64 = null; |
| (Visitor.prototype as any).visitDateDay = null; |
| (Visitor.prototype as any).visitDateMillisecond = null; |
| (Visitor.prototype as any).visitTimestampSecond = null; |
| (Visitor.prototype as any).visitTimestampMillisecond = null; |
| (Visitor.prototype as any).visitTimestampMicrosecond = null; |
| (Visitor.prototype as any).visitTimestampNanosecond = null; |
| (Visitor.prototype as any).visitTimeSecond = null; |
| (Visitor.prototype as any).visitTimeMillisecond = null; |
| (Visitor.prototype as any).visitTimeMicrosecond = null; |
| (Visitor.prototype as any).visitTimeNanosecond = null; |
| (Visitor.prototype as any).visitDenseUnion = null; |
| (Visitor.prototype as any).visitSparseUnion = null; |
| (Visitor.prototype as any).visitIntervalDayTime = null; |
| (Visitor.prototype as any).visitIntervalYearMonth = null; |