Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.SqlXml / System / Xml / Xsl / XsltOld / InputScopeManager.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="InputScopeManager.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
7
8 namespace System.Xml.Xsl.XsltOld {
9     using Res = System.Xml.Utils.Res;
10     using System;
11     using System.Diagnostics;
12     using System.Xml;
13     using System.Xml.XPath;
14
15     internal class InputScopeManager  {
16         private InputScope     scopeStack;
17         private string         defaultNS = string.Empty;
18         private XPathNavigator navigator;    // We need this nsvigator for document() function implementation
19
20         public InputScopeManager(XPathNavigator navigator, InputScope rootScope) {
21             this.navigator = navigator;
22             this.scopeStack = rootScope;
23         }
24
25         internal InputScope CurrentScope {
26             get { return this.scopeStack; }
27         }
28
29         internal InputScope VariableScope {
30             get {
31                 Debug.Assert(this.scopeStack != null);
32                 Debug.Assert(this.scopeStack.Parent != null);
33                 return this.scopeStack.Parent;
34             }
35         }
36
37         internal InputScopeManager Clone() {
38             InputScopeManager manager = new InputScopeManager(this.navigator, null);
39             manager.scopeStack = this.scopeStack;
40             manager.defaultNS  = this.defaultNS;
41             return manager;
42         }
43
44         public XPathNavigator Navigator {
45             get {return this.navigator;}
46         }
47
48         internal InputScope PushScope() {
49             this.scopeStack = new InputScope(this.scopeStack);
50             return this.scopeStack;
51         }
52
53         internal void PopScope() {
54             Debug.Assert(this.scopeStack != null, "Push/Pop disbalance");
55             if (this.scopeStack == null) {
56                 return;
57             }
58
59             for (NamespaceDecl scope = this.scopeStack.Scopes; scope != null; scope = scope.Next) {
60                 this.defaultNS = scope.PrevDefaultNsUri;
61             }
62
63             this.scopeStack = this.scopeStack.Parent;
64         }
65
66         internal void PushNamespace(string prefix, string nspace) {
67             Debug.Assert(this.scopeStack != null, "PushScope wasn't called");
68             Debug.Assert(prefix != null);
69             Debug.Assert(nspace != null);
70             this.scopeStack.AddNamespace(prefix, nspace, this.defaultNS);
71
72             if (prefix == null || prefix.Length == 0) {
73                 this.defaultNS = nspace;
74             }
75         }
76
77         // CompileContext
78
79         public string DefaultNamespace {
80             get { return this.defaultNS; }
81         }
82
83         private string ResolveNonEmptyPrefix(string prefix) {
84             Debug.Assert(this.scopeStack != null, "PushScope wasn't called");
85             Debug.Assert(!string.IsNullOrEmpty(prefix));
86             if (prefix == "xml") {
87                 return XmlReservedNs.NsXml;
88             }
89             else if (prefix == "xmlns") {
90                 return XmlReservedNs.NsXmlNs;
91             }
92
93             for (InputScope inputScope = this.scopeStack; inputScope != null; inputScope = inputScope.Parent) {
94                 string nspace = inputScope.ResolveNonAtom(prefix);
95                 if (nspace != null) {
96                     return nspace;
97                 }
98             }
99             throw XsltException.Create(Res.Xslt_InvalidPrefix, prefix);
100         }
101
102         public string ResolveXmlNamespace(string prefix) {
103             Debug.Assert(prefix != null);
104             if (prefix.Length == 0) {
105                 return this.defaultNS;
106             }
107             return ResolveNonEmptyPrefix(prefix);
108         }
109
110         public string ResolveXPathNamespace(string prefix) {
111             Debug.Assert(prefix != null);
112             if (prefix.Length == 0) {
113                 return string.Empty;
114             }
115             return ResolveNonEmptyPrefix(prefix);
116         }
117
118         internal void InsertExtensionNamespaces(string[] nsList) {
119             Debug.Assert(this.scopeStack != null, "PushScope wasn't called");
120             Debug.Assert(nsList != null);
121             for (int idx = 0; idx < nsList.Length; idx++) {
122                 this.scopeStack.InsertExtensionNamespace(nsList[idx]);
123             }
124         }
125
126         internal bool IsExtensionNamespace(String nspace) {
127             Debug.Assert(this.scopeStack != null, "PushScope wasn't called");
128             for (InputScope inputScope = this.scopeStack; inputScope != null; inputScope = inputScope.Parent) {
129                 if (inputScope.IsExtensionNamespace( nspace )) {
130                     return true;
131                 }
132             }
133             return false;
134         }
135
136         internal void InsertExcludedNamespaces(string[] nsList) {
137             Debug.Assert(this.scopeStack != null, "PushScope wasn't called");
138             Debug.Assert(nsList != null);
139             for (int idx = 0; idx < nsList.Length; idx++) {
140                 this.scopeStack.InsertExcludedNamespace(nsList[idx]);
141             }
142         }
143
144         internal bool IsExcludedNamespace(String nspace) {
145             Debug.Assert(this.scopeStack != null, "PushScope wasn't called");
146             for (InputScope inputScope = this.scopeStack; inputScope != null; inputScope = inputScope.Parent) {
147                 if (inputScope.IsExcludedNamespace( nspace )) {
148                     return true;
149                 }
150             }
151             return false;
152         }
153     }
154 }
155