/**
 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */ import { printIteratorEntries , printIteratorValues } from '../collections' ; import type { Config , NewPlugin , Printer , Refs } from '../types' ; const IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@' ; const IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@' ; const IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@' ; const IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@' ; const IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@' ; const IS_RECORD_SENTINEL = '@@__IMMUTABLE_RECORD__@@' ; const IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@' ; const IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@' ; const IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@' ; const getImmutableName = ( name ) => 'Immutable.' + name ; const printAsLeaf = ( name ) => '[' + name + ']' ; const SPACE = ' ' ; const LAZY = '…' ; const printImmutableEntries = ( val , config , indentation , depth , refs , printer , type ) : string => ++ depth > config . maxDepth ? printAsLeaf ( getImmutableName ( type ) ) : getImmutableName ( type ) + SPACE + '{' + printIteratorEntries ( val . entries ( ) , config , indentation , depth , refs , printer ) + '}' ; function getRecordEntries ( val ) { let i = 0 ; return { next ( ) { if ( i < val . _keys . length ) { const key = val . _keys [ i ++ ] ; return { done : false , value : [ key , val . get ( key ) ] } ; } return { done : true , value : undefined } ; } , } ; } const printImmutableRecord = ( val , config , indentation , depth , refs , printer ) : string => { const name = getImmutableName ( val . _name || 'Record' ) ; return ++ depth > config . maxDepth ? printAsLeaf ( name ) : name + SPACE + '{' + printIteratorEntries ( getRecordEntries ( val ) , config , indentation , depth , refs , printer ) + '}' ; } ; const printImmutableSeq = ( val , config , indentation , depth , refs , printer ) : string => { const name = getImmutableName ( 'Seq' ) ; if ( ++ depth > config . maxDepth ) { return printAsLeaf ( name ) ; } if ( val [ IS_KEYED_SENTINEL ] ) { return ( name + SPACE + '{' + ( val . _iter || val . _object ? printIteratorEntries ( val . entries ( ) , config , indentation , depth , refs , printer ) : LAZY ) + '}' ) ; } return ( name + SPACE + '[' + ( val . _iter || val . _array || val . _collection || val . _iterable ? printIteratorValues ( val . values ( ) , config , indentation , depth , refs , printer ) : LAZY ) + ']' ) ; } ; const printImmutableValues = ( val , config , indentation , depth , refs , printer , type ) : string => ++ depth > config . maxDepth ? printAsLeaf ( getImmutableName ( type ) ) : getImmutableName ( type ) + SPACE + '[' + printIteratorValues ( val . values ( ) , config , indentation , depth , refs , printer ) + ']' ; export const serialize = ( val , config , indentation , depth , refs , printer ) => { if ( val [ IS_MAP_SENTINEL ] ) { return printImmutableEntries ( val , config , indentation , depth , refs , printer , val [ IS_ORDERED_SENTINEL ] ? 'OrderedMap' : 'Map' ) ; } if ( val [ IS_LIST_SENTINEL ] ) { return printImmutableValues ( val , config , indentation , depth , refs , printer , 'List' ) ; } if ( val [ IS_SET_SENTINEL ] ) { return printImmutableValues ( val , config , indentation , depth , refs , printer , val [ IS_ORDERED_SENTINEL ] ? 'OrderedSet' : 'Set' ) ; } if ( val [ IS_STACK_SENTINEL ] ) { return printImmutableValues ( val , config , indentation , depth , refs , printer , 'Stack' ) ; } if ( val [ IS_SEQ_SENTINEL ] ) { return printImmutableSeq ( val , config , indentation , depth , refs , printer ) ; } return printImmutableRecord ( val , config , indentation , depth , refs , printer ) ; } ; export const test = ( val ) => val && ( val [ IS_ITERABLE_SENTINEL ] === true || val [ IS_RECORD_SENTINEL ] === true ) ; const plugin = { serialize , test } ; export default plugin ;