Exemple #1
0
 public ExpressionEmitter(JsonTextWriter writer, EmitterContext context)
 {
     this.writer    = writer;
     this.context   = context;
     this.converter = new ExpressionConverter(context);
 }
Exemple #2
0
        public static LanguageExpression FormatCrossScopeResourceId(ExpressionConverter expressionConverter, ScopeData scopeData, string fullyQualifiedType, IEnumerable <LanguageExpression> nameSegments)
        {
            var arguments = new List <LanguageExpression>();

            switch (scopeData.RequestedScope)
            {
            case ResourceScopeType.TenantScope:
                arguments.Add(new JTokenExpression(fullyQualifiedType));
                arguments.AddRange(nameSegments);

                return(new FunctionExpression("tenantResourceId", arguments.ToArray(), Array.Empty <LanguageExpression>()));

            case ResourceScopeType.SubscriptionScope:
                if (scopeData.SubscriptionIdProperty != null)
                {
                    arguments.Add(expressionConverter.ConvertExpression(scopeData.SubscriptionIdProperty));
                }
                arguments.Add(new JTokenExpression(fullyQualifiedType));
                arguments.AddRange(nameSegments);

                return(new FunctionExpression("subscriptionResourceId", arguments.ToArray(), Array.Empty <LanguageExpression>()));

            case ResourceScopeType.ResourceGroupScope:
                // We avoid using the 'resourceId' function at all here, because its behavior differs depending on the scope that it is called FROM.
                LanguageExpression scope;
                if (scopeData.SubscriptionIdProperty == null)
                {
                    if (scopeData.ResourceGroupProperty == null)
                    {
                        scope = new FunctionExpression("resourceGroup", Array.Empty <LanguageExpression>(), new LanguageExpression[] { new JTokenExpression("id") });
                    }
                    else
                    {
                        var subscriptionId = new FunctionExpression("subscription", Array.Empty <LanguageExpression>(), new LanguageExpression[] { new JTokenExpression("subscriptionId") });
                        var resourceGroup  = expressionConverter.ConvertExpression(scopeData.ResourceGroupProperty);
                        scope = ExpressionConverter.GenerateResourceGroupScope(subscriptionId, resourceGroup);
                    }
                }
                else
                {
                    if (scopeData.ResourceGroupProperty == null)
                    {
                        throw new NotImplementedException($"Cannot format resourceId with non-null subscription and null resourceGroup");
                    }

                    var subscriptionId = expressionConverter.ConvertExpression(scopeData.SubscriptionIdProperty);
                    var resourceGroup  = expressionConverter.ConvertExpression(scopeData.ResourceGroupProperty);
                    scope = ExpressionConverter.GenerateResourceGroupScope(subscriptionId, resourceGroup);
                }

                // We've got to DIY it, unfortunately. The resourceId() function behaves differently when used at different scopes, so is unsuitable here.
                return(ExpressionConverter.GenerateScopedResourceId(scope, fullyQualifiedType, nameSegments));

            case ResourceScopeType.ManagementGroupScope:
                if (scopeData.ManagementGroupNameProperty != null)
                {
                    var managementGroupScope = expressionConverter.GenerateManagementGroupResourceId(scopeData.ManagementGroupNameProperty, true);

                    return(ExpressionConverter.GenerateScopedResourceId(managementGroupScope, fullyQualifiedType, nameSegments));
                }

                // We need to do things slightly differently for Management Groups, because there is no IL to output for "Give me a fully-qualified resource id at the current scope",
                // and we don't even have a mechanism for reliably getting the current scope (e.g. something like 'deployment().scope'). There are plans to add a managementGroupResourceId function,
                // but until we have it, we should generate unqualified resource Ids. There should not be a risk of collision, because we do not allow mixing of resource scopes in a single bicep file.
                return(ExpressionConverter.GenerateUnqualifiedResourceId(fullyQualifiedType, nameSegments));

            default:
                throw new NotImplementedException($"Cannot format resourceId for scope {scopeData.RequestedScope}");
            }
        }
Exemple #3
0
        public void EmitResourceIdReference(ModuleSymbol moduleSymbol, SyntaxBase?indexExpression, SyntaxBase newContext)
        {
            var converterForContext = this.converter.CreateConverterForIndexReplacement(ExpressionConverter.GetModuleNameSyntax(moduleSymbol), indexExpression, newContext);

            var resourceIdExpression = converterForContext.GetFullyQualifiedResourceId(moduleSymbol);
            var serialized           = ExpressionSerializer.SerializeExpression(resourceIdExpression);

            writer.WriteValue(serialized);
        }