import * as os from 'os' ; import { templateKeys } from '../../../common' ; import { assert } from '../../fixed_assert' ; import { DefinitionKind , INamedDefinition } from '../../language/INamedDefinition' ; import * as Json from "../../language/json/JSON" ; import { Span } from '../../language/Span' ; import { CachedValue } from '../../util/CachedValue' ; import { getUserFunctionUsage } from '../../vscodeIntegration/signatureFormatting' ; import { IUsageInfo } from '../../vscodeIntegration/UsageInfoHoverInfo' ; import { IJsonDocument } from "./IJsonDocument" ; import { TemplateScope } from './scopes/TemplateScope' ; import { UserFunctionDefinition } from "./UserFunctionDefinition" ; export function isUserNamespaceDefinition ( definition ) { return definition . definitionKind === DefinitionKind . Namespace ; } /**
 * This class represents the definition of a user-defined namespace in a deployment template.
 */ export class UserFunctionNamespaceDefinition implements INamedDefinition { public readonly definitionKind : DefinitionKind = DefinitionKind . Namespace ; private _members : CachedValue < UserFunctionDefinition [ ] > = new CachedValue < UserFunctionDefinition [ ] > ( ) ; private constructor ( public readonly parentScope , public readonly document , public readonly nameValue , private readonly _value ) { assert ( _value ) ; } public static createIfValid ( parentScope , document , functionValue ) { let nameValue = Json . asStringValue ( functionValue . getPropertyValue ( "namespace" ) ) ; if ( nameValue ) { return new UserFunctionNamespaceDefinition ( parentScope , document , nameValue , functionValue ) ; } return undefined ; } /**
     * Convenient way of seeing what this object represents in the debugger, shouldn't be used for production code
     */ public get __debugDisplay ( ) : string { return this . nameValue . unquotedValue ; } public get span ( ) : Span { return this . _value . span ; } public get members ( ) : UserFunctionDefinition [ ] { return this . _members . getOrCacheValue ( ( ) => { const membersResult = [ ] ; const members = Json . asObjectValue ( this . _value . getPropertyValue ( templateKeys . userFunctionMembers ) ) ; if ( members ) { for ( let member of members . properties ) { let name = member . nameValue ; let value = Json . asObjectValue ( member . value ) ; if ( value ) { let func = new UserFunctionDefinition ( this . parentScope , this . document , this , name , value , member . span ) ; membersResult . push ( func ) ; } } } return membersResult ; } ) ; } public getMemberDefinition ( functionName ) { if ( functionName ) { let functionNameLC = functionName . toLowerCase ( ) ; return this . members . find ( fd => fd . nameValue . toString ( ) . toLowerCase ( ) === functionNameLC ) ; } else { return undefined ; } } public get usageInfo ( ) : IUsageInfo { const ns = this . nameValue . unquotedValue ; const methodsUsage = this . members . map ( md => getUserFunctionUsage ( md , false ) ) ; let description ; if ( methodsUsage . length > 0 ) { description = `Members:${ os . EOL }${ methodsUsage . map ( mu => `* ${ mu }` ) . join ( os . EOL ) }` ; } else { description = `No members` ; } return { usage : ns , friendlyType : "user-defined namespace" , description } ; } }