public override void VisitModuleDeclarationSyntax()

in src/Bicep.Core/TypeSystem/TypeAssignmentVisitor.cs [359:440]


        public override void VisitModuleDeclarationSyntax(ModuleDeclarationSyntax syntax)
            => AssignTypeWithDiagnostics(syntax, diagnostics =>
            {
                var declaredType = typeManager.GetDeclaredType(syntax);
                if (declaredType is null)
                {
                    return ErrorType.Empty();
                }

                var singleDeclaredType = declaredType.UnwrapArrayType();

                this.ValidateDecorators(syntax.Decorators, declaredType, diagnostics);

                if (singleDeclaredType is ErrorType)
                {
                    return singleDeclaredType;
                }

                // We need to validate all of the parameters and outputs to make sure they are valid types.
                // This is where we surface errors for 'unknown' resource types.
                if (singleDeclaredType is ModuleType moduleType &&
                    moduleType.Body is ObjectType objectType)
                {
                    if (objectType.Properties.TryGetValue(LanguageConstants.ModuleParamsPropertyName, out var paramsProperty)
                        && paramsProperty.TypeReference.Type is ObjectType paramsType)
                    {
                        foreach (var property in paramsType.Properties.Values)
                        {
                            if (property.TypeReference.Type is ResourceParameterType resourceType)
                            {
                                if (!features.ResourceTypedParamsAndOutputsEnabled)
                                {
                                    diagnostics.Write(DiagnosticBuilder.ForPosition(syntax.Path).ParamOrOutputResourceTypeUnsupported());
                                }

                                if (!resourceType.DeclaringNamespace.ResourceTypeProvider.HasDefinedType(resourceType.TypeReference))
                                {
                                    diagnostics.Write(DiagnosticBuilder.ForPosition(syntax.Path).ModuleParamOrOutputResourceTypeUnavailable(resourceType.TypeReference));
                                }
                            }
                        }
                    }

                    if (objectType.Properties.TryGetValue(LanguageConstants.ModuleOutputsPropertyName, out var outputsProperty)
                        && outputsProperty.TypeReference.Type is ObjectType outputsType)
                    {
                        foreach (var property in outputsType.Properties.Values)
                        {
                            if (property.TypeReference.Type is ResourceType resourceType)
                            {
                                if (!features.ResourceTypedParamsAndOutputsEnabled)
                                {
                                    diagnostics.Write(DiagnosticBuilder.ForPosition(syntax.Path).ParamOrOutputResourceTypeUnsupported());
                                }

                                if (!resourceType.DeclaringNamespace.ResourceTypeProvider.HasDefinedType(resourceType.TypeReference))
                                {
                                    diagnostics.Write(DiagnosticBuilder.ForPosition(syntax.Path).ModuleParamOrOutputResourceTypeUnavailable(resourceType.TypeReference));
                                }
                            }
                        }
                    }
                }

                if (this.binder.GetSymbolInfo(syntax) is ModuleSymbol moduleSymbol && moduleSymbol.TryGetSemanticModel().IsSuccess(out var moduleSemanticModel, out var _))
                {
                    if (moduleSemanticModel.HasErrors())
                    {
                        diagnostics.Write(moduleSemanticModel is ArmTemplateSemanticModel
                            ? DiagnosticBuilder.ForPosition(syntax.Path).ReferencedArmTemplateHasErrors()
                            : DiagnosticBuilder.ForPosition(syntax.Path).ReferencedModuleHasErrors());
                    }

                    diagnostics.WriteMultiple(moduleSemanticModel.Parameters.Values.Select(md => md.TypeReference)
                        .Concat(moduleSemanticModel.Outputs.Select(md => md.TypeReference))
                        .SelectMany(resourceDerivedTypeDiagnosticReporter.ReportResourceDerivedTypeDiagnostics)
                        .Select(builder => builder(DiagnosticBuilder.ForPosition(syntax.Path))));
                }


                return TypeValidator.NarrowTypeAndCollectDiagnostics(typeManager, binder, this.parsingErrorLookup, diagnostics, syntax.Value, declaredType);
            });