import { Block , FieldID , Item , Value , Dictionary , assert , assertDefined , Field , Reference , cast , Text , Choice , CompileError , ID , OptionReference , Path } from "./exports" ; /** Metadata on an Item, containing fields with MetafieldID, and whose names all
 *start with '^' */ export class Metadata extends Block < Metafield > { /** logical container is base item's logical container */ get up ( ) : Item { return this . containingItem . up ; } /** sets a metadata field, which must not already exist. Value must be
     * detached or undefined. */ set ( name , value ? ) { let id = assertDefined ( MetaID . ids [ name ] ) ; assert ( ! this . getMaybe ( id ) ) ; let field = new Metafield ; this . fields . push ( field ) ; field . container = this ; field . id = id ; field . io = 'output' ; field . formulaType = 'none' ; if ( value ) { field . setValue ( value ) ; } return field ; } } /** Special Metadata to contain ^delta Metafield, which is not stored in normal
 * metadata. Stored in Item.delta*/ export class DeltaContainer extends Metadata { get deltaField ( ) { return this . items [ 0 ] ; } } export class Metafield extends Field < MetaID > { /** base field */ get base ( ) : Item { return this . container . containingItem ; } /** Previous item in metadata is previous item of the base data. Except
     * ^payload goes to ^target */ previous ( ) { this . usesPrevious = true ; if ( this . id === MetaID . ids [ '^payload' ] ) { let ref = cast ( this . container . get ( '^target' ) . value , Reference ) ; let target = assertDefined ( ref . target ) ; if ( ref instanceof OptionReference ) { assert ( ref . optionID ) ; let option = target . get ( ref . optionID ) ; assert ( option . container instanceof Choice ) ; return option . get ( '^initial' ) ; } return target ; } return this . container . containingItem . previous ( ) ; } } /** Globally-unique ID of a MetaField. Name starts with '^'. Immutable and
 * interned. */ export class MetaID extends FieldID { private constructor ( name ) { super ( NaN ) ; this . name = name ; } private static define ( names ) { let dict = { } ; names . forEach ( name => { dict [ name ] = new MetaID ( name ) ; } ) ; return dict ; } static ids : Dictionary < MetaID > = MetaID . define ( [ '^literal' , '^reference' , '^code' , '^loop' , '^target' , '^payload' , '^source' , '^call' , '^builtin' , '^initial' , '^export' , '^exportType' , '^writeValue' , '^delta' , '^extend' , '^any' , '^moved' , ] ) ; }