File: Language\Intermediate\DefaultRazorIntermediateNodeBuilder.cs
Web Access
Project: src\src\Razor\src\Compiler\Microsoft.CodeAnalysis.Razor.Compiler\src\Microsoft.CodeAnalysis.Razor.Compiler.csproj (Microsoft.CodeAnalysis.Razor.Compiler)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
#nullable disable
 
using System;
using System.Collections.Generic;
 
namespace Microsoft.AspNetCore.Razor.Language.Intermediate;
 
internal class DefaultRazorIntermediateNodeBuilder : IntermediateNodeBuilder
{
    private readonly List<IntermediateNode> _stack;
    private int _depth;
 
    public DefaultRazorIntermediateNodeBuilder()
    {
        _stack = new List<IntermediateNode>();
    }
 
    public override IntermediateNode Current
    {
        get
        {
            return _depth > 0 ? _stack[_depth - 1] : null;
        }
    }
 
    public override void Add(IntermediateNode node)
    {
        if (node == null)
        {
            throw new ArgumentNullException(nameof(node));
        }
 
        Current.Children.Add(node);
    }
 
    public override void Insert(int index, IntermediateNode node)
    {
        if (index < 0 || index - Current.Children.Count > 0)
        {
            throw new ArgumentOutOfRangeException(nameof(index));
        }
 
        if (index == Current.Children.Count)
        {
            // Allow inserting at 'Children.Count' to be friendlier than List<> typically is.
            Current.Children.Add(node);
        }
        else
        {
            Current.Children.Insert(index, node);
        }
    }
 
    public override IntermediateNode Build()
    {
        IntermediateNode node = null;
        while (_depth > 0)
        {
            node = Pop();
        }
 
        return node;
    }
 
    public override IntermediateNode Pop()
    {
        if (_depth == 0)
        {
            throw new InvalidOperationException(Resources.FormatIntermediateNodeBuilder_PopInvalid(nameof(Pop)));
        }
 
        var node = _stack[--_depth];
        return node;
    }
 
    public override void Push(IntermediateNode node)
    {
        if (node == null)
        {
            throw new ArgumentNullException(nameof(node));
        }
 
        if (_depth >= _stack.Count)
        {
            _stack.Add(node);
        }
        else
        {
            _stack[_depth] = node;
        }
 
        if (_depth > 0)
        {
            var parent = _stack[_depth - 1];
            parent.Children.Add(node);
        }
 
        _depth++;
    }
}