private static string? TryGetDescription()

in src/Bicep.LangServer/Handlers/BicepHoverHandler.cs [73:171]


        private static string? TryGetDescription(SymbolResolutionResult result, WildcardImportSymbol symbol)
            => DescriptionHelper.TryGetFromDecorator(result.Context.Compilation.GetEntrypointSemanticModel(), symbol.EnclosingDeclaration);

        private static async Task<MarkedStringsOrMarkupContent?> GetMarkdown(
            HoverParams request,
            SymbolResolutionResult result,
            IModuleDispatcher moduleDispatcher,
            IArtifactRegistryProvider moduleRegistryProvider)
        {
            // all of the generated markdown includes the language id to avoid VS code rendering
            // with multiple borders
            switch (result.Symbol)
            {
                case ExtensionNamespaceSymbol extension:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
                        $"{LanguageConstants.ExtensionKeyword} {extension.Name}", TryGetDescription(result, extension)));

                case MetadataSymbol metadata:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
                        $"metadata {metadata.Name}: {metadata.Type}", TryGetDescription(result, metadata)));

                case ParameterSymbol parameter:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
                        WithTypeModifiers($"param {parameter.Name}: {parameter.Type}", parameter.Type), TryGetDescription(result, parameter)));

                case TypeAliasSymbol declaredType:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
                        WithTypeModifiers($"type {declaredType.Name}: {declaredType.Type}", declaredType.Type), TryGetDescription(result, declaredType)));

                case ImportedTypeSymbol importedType:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
                        WithTypeModifiers($"type {importedType.Name}: {importedType.Type}", importedType.Type),
                        importedType.Description));

                case ImportedVariableSymbol importedVariable:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription($"var {importedVariable.Name}: {importedVariable.Type}", importedVariable.Description));

                case AmbientTypeSymbol ambientType:
                    return AsMarkdown(MarkdownHelper.CodeBlock(WithTypeModifiers($"type {ambientType.Name}: {ambientType.Type}", ambientType.Type)));

                case VariableSymbol variable:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription($"var {variable.Name}: {variable.Type}", TryGetDescription(result, variable)));

                case ResourceSymbol resource:
                    var docsSuffix = TryGetTypeDocumentationLink(resource) is { } typeDocsLink ? MarkdownHelper.GetDocumentationLink(typeDocsLink) : "";
                    var description = TryGetDescription(result, resource);

                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
                        $"resource {resource.Name} {(resource.Type is ResourceType ? $"'{resource.Type}'" : resource.Type)}",
                        $"{MarkdownHelper.AppendNewline(description)}{docsSuffix}"));

                case ModuleSymbol module:
                    return await GetModuleMarkdown(request, result, moduleDispatcher, moduleRegistryProvider, module);

                case TestSymbol test:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription($"test {test.Name}", TryGetDescription(result, test)));
                case OutputSymbol output:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
                        WithTypeModifiers($"output {output.Name}: {output.Type}", output.Type), TryGetDescription(result, output)));

                case BuiltInNamespaceSymbol builtInNamespace:
                    return AsMarkdown(MarkdownHelper.CodeBlock($"{builtInNamespace.Name} namespace"));

                case WildcardImportSymbol wildcardImport:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription($"{wildcardImport.Name} namespace", TryGetDescription(result, wildcardImport)));

                case IFunctionSymbol function when result.Origin is FunctionCallSyntaxBase functionCall:
                    // it's not possible for a non-function call syntax to resolve to a function symbol
                    // but this simplifies the checks
                    return GetFunctionMarkdown(function, functionCall, result.Context.Compilation.GetEntrypointSemanticModel());

                case DeclaredFunctionSymbol function:
                    return AsMarkdown(GetFunctionOverloadMarkdown(function.Overload));

                case ImportedFunctionSymbol importedFunction:
                    return AsMarkdown(GetFunctionOverloadMarkdown(importedFunction.Overload));

                case PropertySymbol property:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(WithTypeModifiers($"{property.Name}: {property.Type}", property.Type), property.Description));

                case LocalVariableSymbol local:
                    return AsMarkdown(MarkdownHelper.CodeBlock($"{local.Name}: {local.Type}"));

                case ParameterAssignmentSymbol parameterAssignment:
                    if (GetDeclaredParameterMetadata(parameterAssignment) is not ParameterMetadata declaredParamMetadata)
                    {
                        return null;
                    }

                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
                        WithTypeModifiers($"param {parameterAssignment.Name}: {declaredParamMetadata.TypeReference.Type}", declaredParamMetadata.TypeReference.Type), declaredParamMetadata.Description));

                case AssertSymbol assert:
                    return AsMarkdown(MarkdownHelper.CodeBlockWithDescription($"assert {assert.Name}: {assert.Type}", TryGetDescription(result, assert)));

                default:
                    return null;
            }
        }