import * as s from "capnp-ts/src/std/schema.capnp.js" ; import { format } from "capnp-ts/src/util" ; import initTrace from "debug" ; import { CodeGeneratorFileContext } from "./code-generator-file-context" ; import { ConcreteListType } from "./constants" ; import * as E from "./errors" ; import * as util from "./util" ; const trace = initTrace ( "capnpc:file" ) ; trace ( "load" ) ; export function compareCodeOrder ( a , b ) { return a . getCodeOrder ( ) - b . getCodeOrder ( ) ; } export function getConcreteListType ( ctx , type ) { if ( ! type . isList ( ) ) return getJsType ( ctx , type , false ) ; const elementType = type . getList ( ) . getElementType ( ) ; const elementTypeWhich = elementType . which ( ) ; if ( elementTypeWhich === s . Type . LIST ) { return `capnp.PointerList(${ getConcreteListType ( ctx , elementType ) })` ; } else if ( elementTypeWhich === s . Type . STRUCT ) { const structNode = lookupNode ( ctx , elementType . getStruct ( ) . getTypeId ( ) ) ; if ( structNode . getStruct ( ) . getPreferredListEncoding ( ) !== s . ElementSize . INLINE_COMPOSITE ) { throw new Error ( E . GEN_FIELD_NON_INLINE_STRUCT_LIST ) ; } return `capnp.CompositeList(${ getJsType ( ctx , elementType , false ) })` ; } return ConcreteListType [ elementTypeWhich ] ; } export function getDisplayNamePrefix ( node ) { return node . getDisplayName ( ) . substr ( node . getDisplayNamePrefixLength ( ) ) ; } export function getFullClassName ( node ) { return node . getDisplayName ( ) . split ( ":" ) [ 1 ] . split ( "." ) . map ( util . c2t ) . join ( "_" ) ; } export function getJsType ( ctx , type , constructor ) { const whichType = type . which ( ) ; switch ( whichType ) { case s . Type . ANY_POINTER : return "capnp.Pointer" ; case s . Type . BOOL : return "boolean" ; case s . Type . DATA : return "capnp.Data" ; case s . Type . ENUM : return getFullClassName ( lookupNode ( ctx , type . getEnum ( ) . getTypeId ( ) ) ) ; case s . Type . FLOAT32 : case s . Type . FLOAT64 : case s . Type . INT16 : case s . Type . INT32 : case s . Type . INT8 : case s . Type . UINT16 : case s . Type . UINT32 : case s . Type . UINT8 : return "number" ; case s . Type . UINT64 : case s . Type . INT64 : return "bigint" ; case s . Type . INTERFACE : return "capnp.Interface" ; case s . Type . LIST : return `capnp.List${ constructor ? "Ctor" : "" }<${ getJsType ( ctx , type . getList ( ) . getElementType ( ) , false ) }>` ; case s . Type . STRUCT : { const c = getFullClassName ( lookupNode ( ctx , type . getStruct ( ) . getTypeId ( ) ) ) ; return constructor ? `capnp.StructCtor<${ c }>` : c ; } case s . Type . TEXT : return "string" ; case s . Type . VOID : return "capnp.Void" ; default : throw new Error ( format ( E . GEN_UNKNOWN_TYPE , whichType ) ) ; } } export function getUnnamedUnionFields ( node ) { if ( ! node . isStruct ( ) ) return [ ] ; return node . getStruct ( ) . getFields ( ) . filter ( ( f ) => f . getDiscriminantValue ( ) !== s . Field . NO_DISCRIMINANT ) ; } export function hasNode ( ctx , lookup ) { const id = typeof lookup === "bigint" ? lookup : lookup . getId ( ) ; return ctx . nodes . some ( ( n ) => n . getId ( ) === id ) ; } export function loadRequestedFile ( req , file ) { trace ( "compile(%s, %s)" , req , file ) ; const ctx = new CodeGeneratorFileContext ( req , file ) ; const schema = lookupNode ( ctx , file . getId ( ) ) ; ctx . tsPath = schema . getDisplayName ( ) + ".ts" ; return ctx ; } export function lookupNode ( ctx , lookup ) { const id = typeof lookup === "bigint" ? lookup : lookup . getId ( ) ; const node = ctx . nodes . find ( ( n ) => n . getId ( ) === id ) ; if ( node === undefined ) throw new Error ( format ( E . GEN_NODE_LOOKUP_FAIL , id ) ) ; return node ; } param { s . Field } field returns { boolean } export function needsConcreteListClass ( field ) { if ( ! field . isSlot ( ) ) return false ; const slotType = field . getSlot ( ) . getType ( ) ; if ( ! slotType . isList ( ) ) return false ; const elementType = slotType . getList ( ) . getElementType ( ) ; return elementType . isStruct ( ) || elementType . isList ( ) ; }