private void EmitModule(ModuleSymbol moduleSymbol) { writer.WriteStartObject(); this.emitter.EmitProperty("type", NestedDeploymentResourceType); this.emitter.EmitProperty("apiVersion", NestedDeploymentResourceApiVersion); // emit all properties apart from 'params'. In practice, this currrently only allows 'name', but we may choose to allow other top-level resource properties in future. // params requires special handling (see below). var moduleBody = (ObjectSyntax)moduleSymbol.DeclaringModule.Body; this.emitter.EmitObjectProperties(moduleBody, ModulePropertiesToOmit); var scopeData = context.ModuleScopeData[moduleSymbol]; ScopeHelper.EmitModuleScopeProperties(scopeData, emitter); writer.WritePropertyName("properties"); { writer.WriteStartObject(); writer.WritePropertyName("expressionEvaluationOptions"); { writer.WriteStartObject(); this.emitter.EmitProperty("scope", "inner"); writer.WriteEndObject(); } this.emitter.EmitProperty("mode", "Incremental"); EmitModuleParameters(moduleSymbol); writer.WritePropertyName("template"); { var moduleSemanticModel = GetModuleSemanticModel(moduleSymbol); var moduleWriter = new TemplateWriter(writer, moduleSemanticModel); moduleWriter.Write(); } writer.WriteEndObject(); } this.EmitDependsOn(moduleSymbol); writer.WriteEndObject(); }
private void EmitModule(JsonTextWriter jsonWriter, ModuleSymbol moduleSymbol, ExpressionEmitter emitter) { jsonWriter.WriteStartObject(); var body = moduleSymbol.DeclaringModule.Value; switch (body) { case IfConditionSyntax ifCondition: body = ifCondition.Body; emitter.EmitProperty("condition", ifCondition.ConditionExpression); break; case ForSyntax @for: if (@for.Body is IfConditionSyntax loopFilter) { body = loopFilter.Body; emitter.EmitProperty("condition", loopFilter.ConditionExpression); } else { body = @for.Body; } var batchSize = GetBatchSize(moduleSymbol.DeclaringModule); emitter.EmitProperty("copy", () => emitter.EmitCopyObject(moduleSymbol.Name, @for, input: null, batchSize: batchSize)); break; } emitter.EmitProperty("type", NestedDeploymentResourceType); emitter.EmitProperty("apiVersion", NestedDeploymentResourceApiVersion); // emit all properties apart from 'params'. In practice, this currrently only allows 'name', but we may choose to allow other top-level resource properties in future. // params requires special handling (see below). emitter.EmitObjectProperties((ObjectSyntax)body, ModulePropertiesToOmit); var scopeData = context.ModuleScopeData[moduleSymbol]; ScopeHelper.EmitModuleScopeProperties(context.SemanticModel.TargetScope, scopeData, emitter, body); if (scopeData.RequestedScope != ResourceScope.ResourceGroup) { // if we're deploying to a scope other than resource group, we need to supply a location if (this.context.SemanticModel.TargetScope == ResourceScope.ResourceGroup) { // the deployment() object at resource group scope does not contain a property named 'location', so we have to use resourceGroup().location emitter.EmitProperty("location", new FunctionExpression( "resourceGroup", Array.Empty <LanguageExpression>(), new LanguageExpression[] { new JTokenExpression("location") })); } else { // at all other scopes we can just use deployment().location emitter.EmitProperty("location", new FunctionExpression( "deployment", Array.Empty <LanguageExpression>(), new LanguageExpression[] { new JTokenExpression("location") })); } } jsonWriter.WritePropertyName("properties"); { jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName("expressionEvaluationOptions"); { jsonWriter.WriteStartObject(); emitter.EmitProperty("scope", "inner"); jsonWriter.WriteEndObject(); } emitter.EmitProperty("mode", "Incremental"); EmitModuleParameters(jsonWriter, moduleSymbol, emitter); var moduleSemanticModel = GetModuleSemanticModel(moduleSymbol); // If it is a template spec module, emit templateLink instead of template contents. jsonWriter.WritePropertyName(moduleSemanticModel is TemplateSpecSemanticModel ? "templateLink" : "template"); { TemplateWriterFactory.CreateTemplateWriter(moduleSemanticModel, this.settings).Write(jsonWriter); } jsonWriter.WriteEndObject(); } this.EmitDependsOn(jsonWriter, moduleSymbol, emitter, body); // Since we don't want to be mutating the body of the original ObjectSyntax, we create an placeholder body in place // and emit its properties to merge decorator properties. foreach (var(property, val) in AddDecoratorsToBody( moduleSymbol.DeclaringModule, SyntaxFactory.CreateObject(Enumerable.Empty <ObjectPropertySyntax>()), moduleSymbol.Type).ToNamedPropertyValueDictionary()) { emitter.EmitProperty(property, val); } jsonWriter.WriteEndObject(); }
private void EmitModule(ModuleSymbol moduleSymbol) { writer.WriteStartObject(); if (moduleSymbol.DeclaringModule.IfCondition is IfConditionSyntax ifCondition) { this.emitter.EmitProperty("condition", ifCondition.ConditionExpression); } this.emitter.EmitProperty("type", NestedDeploymentResourceType); this.emitter.EmitProperty("apiVersion", NestedDeploymentResourceApiVersion); // emit all properties apart from 'params'. In practice, this currrently only allows 'name', but we may choose to allow other top-level resource properties in future. // params requires special handling (see below). this.emitter.EmitObjectProperties((ObjectSyntax)moduleSymbol.DeclaringModule.Body, ModulePropertiesToOmit); var scopeData = context.ModuleScopeData[moduleSymbol]; ScopeHelper.EmitModuleScopeProperties(scopeData, emitter); if (scopeData.RequestedScope != ResourceScopeType.ResourceGroupScope) { // if we're deploying to a scope other than resource group, we need to supply a location if (this.context.SemanticModel.TargetScope == ResourceScopeType.ResourceGroupScope) { // the deployment() object at resource group scope does not contain a property named 'location', so we have to use resourceGroup().location this.emitter.EmitProperty("location", new FunctionExpression( "resourceGroup", new LanguageExpression[] { }, new LanguageExpression[] { new JTokenExpression("location") })); } else { // at all other scopes we can just use deployment().location this.emitter.EmitProperty("location", new FunctionExpression( "deployment", new LanguageExpression[] { }, new LanguageExpression[] { new JTokenExpression("location") })); } } writer.WritePropertyName("properties"); { writer.WriteStartObject(); writer.WritePropertyName("expressionEvaluationOptions"); { writer.WriteStartObject(); this.emitter.EmitProperty("scope", "inner"); writer.WriteEndObject(); } this.emitter.EmitProperty("mode", "Incremental"); EmitModuleParameters(moduleSymbol); writer.WritePropertyName("template"); { var moduleSemanticModel = GetModuleSemanticModel(moduleSymbol); var moduleWriter = new TemplateWriter(writer, moduleSemanticModel); moduleWriter.Write(); } writer.WriteEndObject(); } this.EmitDependsOn(moduleSymbol); writer.WriteEndObject(); }