1 //
2 // Commons.Xml.Relaxng.Derivative.RdpPatterns.cs
3 //
4 // Author:
5 //	Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
6 //
7 // 2003 Atsushi Enomoto "No rights reserved."
8 //
9 // Copyright (c) 2004 Novell Inc.
10 // All rights reserved
11 //
12 
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33 
34 using System;
35 using System.Collections;
36 using System.Xml;
37 using Commons.Xml.Relaxng;
38 
39 using LabelList = System.Collections.Hashtable;
40 
41 
42 namespace Commons.Xml.Relaxng.Derivative
43 {
RdpApplyAfterHandler(RdpPattern p)44 	public delegate RdpPattern RdpApplyAfterHandler (RdpPattern p);
45 
46 	// abstract Pattern. Note that in README the classes in this namespace
47 	// is explicitly written as not for public use (and hidden in monodoc
48 	// for now).
49 	public abstract class RdpPattern
50 	{
51 		public static readonly RdpPattern Anything;
52 
RdpPattern()53 		static RdpPattern ()
54 		{
55 			RdpPattern anyAtts = new RdpList (new RdpAttribute (RdpAnyName.Instance, RdpText.Instance));
56 			RdpElement anyElement = new RdpElement (RdpAnyName.Instance, null);
57 			Anything = new RdpChoice (RdpEmpty.Instance, new RdpChoice (anyAtts, new RdpChoice (RdpText.Instance, new RdpList (anyElement))));
58 			anyElement.Children = Anything;
59 		}
60 
61 		internal bool nullableComputed;
62 		internal bool isNullable;
63 		Hashtable patternPool;
64 
debug()65 		internal string debug ()
66 		{
67 			return RdpUtil.DebugRdpPattern (this, new Hashtable ());
68 		}
69 
70 		public abstract RelaxngPatternType PatternType { get; }
71 
72 		public abstract RdpContentType ContentType { get; }
73 
setupTable(Type type, RdpPattern p)74 		private Hashtable setupTable (Type type, RdpPattern p)
75 		{
76 			if (patternPool == null) // could be null for RdpElement etc.
77 				patternPool = new Hashtable ();
78 
79 			Hashtable typePool = (Hashtable) patternPool [type];
80 			if (typePool == null) {
81 				typePool = new Hashtable ();
82 				patternPool [type] = typePool;
83 			}
84 			Hashtable pTable = (Hashtable) typePool [p];
85 			if (pTable == null) {
86 				pTable = new Hashtable ();
87 				typePool [p] = pTable;
88 			}
89 			return pTable;
90 		}
91 
MakeFlip(RdpBinaryFunction func, RdpPattern p)92 		internal RdpFlip MakeFlip (RdpBinaryFunction func, RdpPattern p)
93 		{
94 			if (patternPool == null) // could be null for RdpElement etc.
95 				patternPool = new Hashtable ();
96 
97 			// Though this method takes function argument, all
98 			// p1 callers have different pattern types, so we don't
99 			// have to distinguish tables by func.
100 
101 			Hashtable table = patternPool [func] as Hashtable;
102 			if (table == null) {
103 				table = new Hashtable ();
104 				patternPool [func] = table;
105 			}
106 			RdpFlip f = table [p] as RdpFlip;
107 			if (f != null)
108 				return f;
109 			f = new RdpFlip (func, p);
110 			table [p] = f;
111 			return f;
112 		}
113 
MakeChoiceLeaf(RdpPattern p)114 		public RdpChoice MakeChoiceLeaf (RdpPattern p)
115 		{
116 			if (patternPool == null) // could be null for RdpElement etc.
117 				patternPool = new Hashtable ();
118 			Hashtable leaves = (Hashtable) patternPool [typeof (RdpEmpty)];
119 			if (leaves == null) {
120 				leaves = new Hashtable ();
121 				patternPool [typeof (RdpEmpty)] = leaves;
122 			}
123 			RdpChoice leaf = leaves [p] as RdpChoice;
124 			if (leaf == null) {
125 				leaf = new RdpChoice (RdpEmpty.Instance, p);
126 				leaf.setInternTable (patternPool);
127 				leaves [p] = leaf;
128 			}
129 			return leaf;
130 		}
131 
MakeChoice(RdpPattern p1, RdpPattern p2)132 		public RdpPattern MakeChoice (RdpPattern p1, RdpPattern p2)
133 		{
134 			if (p1.PatternType == RelaxngPatternType.NotAllowed)
135 				return p2;
136 			if (p2.PatternType == RelaxngPatternType.NotAllowed)
137 				return p1;
138 			if (p1 == p2)
139 				return p1;
140 			// choice-leaves support
141 			if (p1.PatternType == RelaxngPatternType.Empty)
142 				return MakeChoiceLeaf (p2);
143 			if (p2.PatternType == RelaxngPatternType.Empty)
144 				return MakeChoiceLeaf (p1);
145 
146 			if (p1.GetHashCode () > p2.GetHashCode ()) {
147 				RdpPattern tmp = p1;
148 				p1 = p2;
149 				p2 = tmp;
150 			}
151 
152 			Hashtable p1Table = setupTable (typeof (RdpChoice), p1);
153 			if (p1Table [p2] == null) {
154 				RdpChoice c = new RdpChoice (p1, p2);
155 				c.setInternTable (this.patternPool);
156 				p1Table [p2] = c;
157 			}
158 			return (RdpChoice) p1Table [p2];
159 		}
160 
MakeGroup(RdpPattern p1, RdpPattern p2)161 		public RdpPattern MakeGroup (RdpPattern p1, RdpPattern p2)
162 		{
163 			if (p1.PatternType == RelaxngPatternType.Empty)
164 				return p2;
165 
166 			Hashtable p1Table = setupTable (typeof (RdpGroup), p1);
167 			if (p1Table [p2] == null) {
168 				RdpGroup g = new RdpGroup (p1, p2);
169 				g.setInternTable (this.patternPool);
170 				p1Table [p2] = g;
171 			}
172 			return (RdpGroup) p1Table [p2];
173 		}
174 
MakeInterleave(RdpPattern p1, RdpPattern p2)175 		public RdpInterleave MakeInterleave (RdpPattern p1, RdpPattern p2)
176 		{
177 			if (p1.GetHashCode () > p2.GetHashCode ()) {
178 				RdpPattern tmp = p1;
179 				p1 = p2;
180 				p2 = tmp;
181 			}
182 
183 			Hashtable p1Table = setupTable (typeof (RdpInterleave), p1);
184 			if (p1Table [p2] == null) {
185 				RdpInterleave i = new RdpInterleave (p1, p2);
186 				i.setInternTable (this.patternPool);
187 				p1Table [p2] = i;
188 			}
189 			return (RdpInterleave) p1Table [p2];
190 		}
191 
MakeAfter(RdpPattern p1, RdpPattern p2)192 		public RdpAfter MakeAfter (RdpPattern p1, RdpPattern p2)
193 		{
194 			Hashtable p1Table = setupTable (typeof (RdpAfter), p1);
195 			if (p1Table [p2] == null) {
196 				RdpAfter a = new RdpAfter (p1, p2);
197 				a.setInternTable (this.patternPool);
198 				p1Table [p2] = a;
199 			}
200 			return (RdpAfter) p1Table [p2];
201 		}
202 
MakeOneOrMore(RdpPattern p)203 		public RdpOneOrMore MakeOneOrMore (RdpPattern p)
204 		{
205 			if (patternPool == null) // could be null for RdpElement etc.
206 				patternPool = new Hashtable ();
207 
208 			Hashtable pTable = (Hashtable) patternPool [typeof (RdpOneOrMore)];
209 			if (pTable == null) {
210 				pTable = new Hashtable ();
211 				patternPool [typeof (RdpOneOrMore)] = pTable;
212 			}
213 			if (pTable [p] == null) {
214 				RdpOneOrMore oom = new RdpOneOrMore (p);
215 				oom.setInternTable (patternPool);
216 				pTable [p] = oom;
217 			}
218 			return (RdpOneOrMore) pTable [p];
219 		}
220 
setInternTable(Hashtable ht)221 		internal void setInternTable (Hashtable ht)
222 		{
223 			if (this.patternPool != null)
224 				return;
225 			this.patternPool = ht;
226 
227 			Hashtable pt = ht [GetType ()] as Hashtable;
228 			if (pt == null) {
229 				pt = new Hashtable ();
230 				ht [GetType ()] = pt;
231 			}
232 
233 			RdpAbstractSingleContent single =
234 				this as RdpAbstractSingleContent;
235 			if (single != null) {
236 				if (pt [single.Child] == null) {
237 					pt [single.Child] = this;
238 					single.Child.setInternTable (ht);
239 				}
240 				return;
241 			}
242 
243 			RdpAbstractBinary binary =
244 				this as RdpAbstractBinary;
245 			if (binary != null) {
246 				Hashtable lTable = setupTable (GetType (), binary.LValue);
247 				if (lTable [binary.RValue] == null) {
248 					lTable [binary.RValue] = this;
249 					binary.LValue.setInternTable (ht);
250 					binary.RValue.setInternTable (ht);
251 				}
252 				return;
253 			}
254 
255 			// For rest patterns, only check recursively, without pooling.
256 			RdpAttribute attr = this as RdpAttribute;
257 			if (attr != null) {
258 				attr.Children.setInternTable (ht);
259 				return;
260 			}
261 			RdpElement el = this as RdpElement;
262 			if (el != null) {
263 				el.Children.setInternTable (ht);
264 				return;
265 			}
266 			RdpDataExcept dex= this as RdpDataExcept;
267 			if (dex != null) {
268 				dex.Except.setInternTable (ht);
269 				return;
270 			}
271 
272 			switch (PatternType) {
273 			case RelaxngPatternType.Empty:
274 			case RelaxngPatternType.NotAllowed:
275 			case RelaxngPatternType.Text:
276 			case RelaxngPatternType.Data:
277 			case RelaxngPatternType.Value:
278 				return;
279 			}
280 
281 #if REPLACE_IN_ADVANCE
282 			throw new InvalidOperationException ();
283 #endif
284 		}
285 
MarkReachableDefs()286 		internal abstract void MarkReachableDefs ();
287 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)288 		internal abstract void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept);
289 
290 		// This method is to detect text pattern inside interleave child.
ContainsText()291 		internal abstract bool ContainsText ();
292 
ExpandRef(Hashtable defs)293 		internal virtual RdpPattern ExpandRef (Hashtable defs)
294 		{
295 			return this;
296 		}
297 
ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)298 		internal virtual RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
299 		{
300 			return this;
301 		}
302 
303 		public abstract bool Nullable { get; }
304 
305 		internal virtual bool IsTextValueDependent {
306 			get { return false; }
307 		}
308 
309 		internal virtual bool IsContextDependent {
310 			get { return false; }
311 		}
312 
313 		// fills QName collection
GetLabels(LabelList elements, LabelList attributes)314 		public void GetLabels (LabelList elements, LabelList attributes)
315 		{
316 			GetLabels (elements, attributes, false);
317 		}
318 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)319 		public abstract void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass);
320 
AddNameLabel(LabelList names, RdpNameClass nc)321 		internal void AddNameLabel (LabelList names, RdpNameClass nc)
322 		{
323 			RdpName name = nc as RdpName;
324 			if (name != null) {
325 				XmlQualifiedName qname = new XmlQualifiedName (
326 					name.LocalName, name.NamespaceURI);
327 				names [qname] = qname;
328 				return;
329 			}
330 			RdpNameClassChoice choice = nc as RdpNameClassChoice;
331 			if (choice != null) {
332 				AddNameLabel (names, choice.LValue);
333 				AddNameLabel (names, choice.RValue);
334 				return;
335 			}
336 			// For NsName and AnyName, do nothing.
337 		}
338 
339 		#region Derivative
TextDeriv(string s, XmlReader reader)340 		public virtual RdpPattern TextDeriv (string s, XmlReader reader)
341 		{
342 			return RdpNotAllowed.Instance;
343 		}
344 
TextDeriv(string s, XmlReader reader, MemoizationStore memo)345 		internal virtual RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
346 		{
347 			return TextDeriv (s, reader);
348 		}
349 
EmptyTextDeriv(MemoizationStore memo)350 		internal virtual RdpPattern EmptyTextDeriv (MemoizationStore memo)
351 		{
352 			return TextDeriv (String.Empty, null, memo);
353 		}
354 
TextOnlyDeriv()355 		internal virtual RdpPattern TextOnlyDeriv ()
356 		{
357 			return this;
358 		}
359 
TextOnlyDeriv(MemoizationStore store)360 		internal virtual RdpPattern TextOnlyDeriv (MemoizationStore store)
361 		{
362 			return this;
363 		}
364 
MixedTextDeriv()365 		internal virtual RdpPattern MixedTextDeriv ()
366 		{
367 			return RdpNotAllowed.Instance;
368 		}
369 
MixedTextDeriv(MemoizationStore memo)370 		internal virtual RdpPattern MixedTextDeriv (MemoizationStore memo)
371 		{
372 			return RdpNotAllowed.Instance;
373 		}
374 
ListDeriv(string [] list, int index, XmlReader reader)375 		public RdpPattern ListDeriv (string [] list, int index, XmlReader reader)
376 		{
377 			return listDerivInternal (list, 0, reader);
378 		}
379 
listDerivInternal(string [] list, int start, XmlReader reader)380 		private RdpPattern listDerivInternal (string [] list, int start, XmlReader reader)
381 		{
382 			if (list.Length <= start)
383 				return this;
384 			else if (list [start].Length == 0)
385 				return listDerivInternal (list, start + 1, reader);
386 			else
387 				return this.TextDeriv (list [start].Trim (RdpUtil.WhitespaceChars), reader).listDerivInternal (list, start + 1, reader);
388 		}
389 
390 		// Choice(this, p)
Choice(RdpPattern p)391 		public virtual RdpPattern Choice (RdpPattern p)
392 		{
393 			if (p is RdpNotAllowed)
394 				return this;
395 			else if (this is RdpNotAllowed)
396 				return p;
397 			else
398 				return MakeChoice (this, p);
399 		}
400 
401 		// Group(this, p)
Group(RdpPattern p)402 		public virtual RdpPattern Group (RdpPattern p)
403 		{
404 			if (p is RdpNotAllowed || this is RdpNotAllowed)
405 				return RdpNotAllowed.Instance;
406 			else if (p is RdpEmpty)
407 				return this;
408 			else if (this is RdpEmpty)
409 				return p;
410 			else
411 				return MakeGroup (this, p);
412 		}
413 
414 		// Interleave(this, p)
Interleave(RdpPattern p)415 		public virtual RdpPattern Interleave (RdpPattern p)
416 		{
417 			if (p is RdpNotAllowed || this is RdpNotAllowed)
418 				return RdpNotAllowed.Instance;
419 			else if (p is RdpEmpty)
420 				return this;
421 			else if (this is RdpEmpty)
422 				return p;
423 			else
424 				return MakeInterleave (this, p);
425 		}
426 
427 		// After(this, p)
After(RdpPattern p)428 		public virtual RdpPattern After (RdpPattern p)
429 		{
430 			if (this is RdpNotAllowed || p is RdpNotAllowed)
431 				return RdpNotAllowed.Instance;
432 			else
433 				return MakeAfter (this, p);
434 		}
435 
436 
437 		// applyAfter((f, p1=this), p2)
ApplyAfter(RdpApplyAfterHandler h)438 		public virtual RdpPattern ApplyAfter (RdpApplyAfterHandler h)
439 		{
440 			throw new Exception ("INTERNAL ERROR: should not happen. This is " + this);
441 		}
442 
443 		// startTagOpenDeriv (this, qname)
444 		// startTagOpenDeriv _ qn = NotAllowed (default)
StartTagOpenDeriv(string name, string ns)445 		public virtual RdpPattern StartTagOpenDeriv (string name, string ns)
446 		{
447 			return RdpNotAllowed.Instance;
448 		}
449 
StartTagOpenDeriv(string name, string ns, MemoizationStore memo)450 		internal virtual RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
451 		{
452 			return StartTagOpenDeriv (name, ns);
453 		}
454 
455 		// attDeriv(ctx, this, att)
456 		// attDeriv _ _ _ = NotAllowed
AttDeriv(string name, string ns, string value, XmlReader reader)457 		public virtual RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
458 		{
459 			return RdpNotAllowed.Instance;
460 		}
461 
StartAttDeriv(string name, string ns)462 		public virtual RdpPattern StartAttDeriv (string name, string ns)
463 		{
464 			return RdpNotAllowed.Instance;
465 		}
466 
StartAttDeriv(string name, string ns, MemoizationStore memo)467 		internal virtual RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
468 		{
469 			return StartAttDeriv (name, ns);
470 		}
471 
EndAttDeriv()472 		public virtual RdpPattern EndAttDeriv ()
473 		{
474 			return RdpNotAllowed.Instance;
475 		}
476 
EndAttDeriv(MemoizationStore memo)477 		internal virtual RdpPattern EndAttDeriv (MemoizationStore memo)
478 		{
479 			return EndAttDeriv ();
480 		}
481 
ValueMatch(string s, XmlReader reader)482 		public bool ValueMatch (string s, XmlReader reader)
483 		{
484 			return Nullable && Util.IsWhitespace (s) ||
485 				TextDeriv (s, reader).Nullable;
486 		}
487 
StartTagCloseDeriv()488 		public virtual RdpPattern StartTagCloseDeriv ()
489 		{
490 			return this;
491 		}
492 
StartTagCloseDeriv(MemoizationStore memo)493 		internal virtual RdpPattern StartTagCloseDeriv (MemoizationStore memo)
494 		{
495 			return StartTagCloseDeriv ();
496 		}
497 
OneOrMore()498 		public RdpPattern OneOrMore ()
499 		{
500 			if (PatternType == RelaxngPatternType.NotAllowed)
501 				return RdpNotAllowed.Instance;
502 			else
503 				return MakeOneOrMore (this);
504 		}
505 
EndTagDeriv()506 		public virtual RdpPattern EndTagDeriv ()
507 		{
508 			return RdpNotAllowed.Instance;
509 		}
510 
EndTagDeriv(MemoizationStore memo)511 		internal virtual RdpPattern EndTagDeriv (MemoizationStore memo)
512 		{
513 			return EndTagDeriv ();
514 		}
515 		#endregion
516 	}
517 
518 	// Empty
519 	public class RdpEmpty : RdpPattern
520 	{
RdpEmpty()521 		public RdpEmpty () {}
RdpEmpty()522 		static RdpEmpty ()
523 		{
524 			instance = new RdpEmpty ();
525 		}
526 
527 		public override bool Nullable {
528 			get { return true; }
529 		}
530 
531 		internal override bool IsTextValueDependent {
532 			get { return false; }
533 		}
534 
535 		internal override bool IsContextDependent {
536 			get { return false; }
537 		}
538 
539 		static RdpEmpty instance;
540 		public static RdpEmpty Instance {
541 			get { return instance; }
542 		}
543 
544 		public override RelaxngPatternType PatternType {
545 			get { return RelaxngPatternType.Empty; }
546 		}
547 
548 		public override RdpContentType ContentType {
549 			get { return RdpContentType.Empty; }
550 		}
551 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)552 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
553 		{
554 			// do nothing
555 		}
556 
MarkReachableDefs()557 		internal override void MarkReachableDefs ()
558 		{
559 			// do nothing
560 		}
561 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)562 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
563 		{
564 			if (dataExcept)
565 				throw new RelaxngException ("empty cannot appear under except of a data pattern.");
566 		}
567 
ContainsText()568 		internal override bool ContainsText()
569 		{
570 			return false;
571 		}
572 	}
573 
574 	// NotAllowed
575 	public class RdpNotAllowed : RdpPattern
576 	{
RdpNotAllowed()577 		public RdpNotAllowed () {}
RdpNotAllowed()578 		static RdpNotAllowed ()
579 		{
580 			instance = new RdpNotAllowed ();
581 		}
582 
583 		static RdpNotAllowed instance;
584 		public static RdpNotAllowed Instance {
585 			get { return instance; }
586 		}
587 
588 		public override bool Nullable {
589 			get { return false; }
590 		}
591 
592 		internal override bool IsTextValueDependent {
593 			get { return false; }
594 		}
595 
596 		internal override bool IsContextDependent {
597 			get { return false; }
598 		}
599 
ApplyAfter(RdpApplyAfterHandler h)600 		public override RdpPattern ApplyAfter (RdpApplyAfterHandler h)
601 		{
602 			return RdpNotAllowed.Instance;
603 		}
604 
605 		public override RelaxngPatternType PatternType {
606 			get { return RelaxngPatternType.NotAllowed; }
607 		}
608 
609 		public override RdpContentType ContentType {
610 			get { return RdpContentType.Empty; }
611 		}
612 
MarkReachableDefs()613 		internal override void MarkReachableDefs ()
614 		{
615 			// do nothing
616 		}
617 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)618 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
619 		{
620 			// do nothing
621 		}
622 
ContainsText()623 		internal override bool ContainsText()
624 		{
625 			return false;
626 		}
627 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)628 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
629 		{
630 			// FIXME: Supposed to clear something here?
631 		}
632 	}
633 
634 	// Text
635 	public class RdpText : RdpPattern
636 	{
637 		static RdpText instance;
638 		public static RdpText Instance {
639 			get { return instance; }
640 		}
641 
RdpText()642 		public RdpText () {}
RdpText()643 		static RdpText ()
644 		{
645 			instance = new RdpText ();
646 		}
647 
648 		public override bool Nullable {
649 			get { return true; }
650 		}
651 
652 		internal override bool IsTextValueDependent {
653 			get { return false; }
654 		}
655 
656 		internal override bool IsContextDependent {
657 			get { return false; }
658 		}
659 
660 		public override RelaxngPatternType PatternType {
661 			get { return RelaxngPatternType.Text; }
662 		}
663 
664 		public override RdpContentType ContentType {
665 			get { return RdpContentType.Complex; }
666 		}
667 
TextDeriv(string s, XmlReader reader)668 		public override RdpPattern TextDeriv (string s, XmlReader reader)
669 		{
670 			return this;
671 		}
672 
EmptyTextDeriv(MemoizationStore memo)673 		internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
674 		{
675 			return this;
676 		}
677 
MixedTextDeriv()678 		internal override RdpPattern MixedTextDeriv ()
679 		{
680 			return this;
681 		}
682 
MixedTextDeriv(MemoizationStore memo)683 		internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
684 		{
685 			return this;
686 		}
687 
MarkReachableDefs()688 		internal override void MarkReachableDefs ()
689 		{
690 			// do nothing
691 		}
692 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)693 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
694 		{
695 			if (list)
696 				throw new RelaxngException ("text is not allowed under a list.");
697 			if (dataExcept)
698 				throw new RelaxngException ("text is not allowed under except of a list.");
699 		}
700 
ContainsText()701 		internal override bool ContainsText()
702 		{
703 			return true;
704 		}
705 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)706 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
707 		{
708 			// do nothing
709 		}
710 	}
711 
712 	// AbstractBinary
713 	public abstract class RdpAbstractBinary : RdpPattern
714 	{
RdpAbstractBinary(RdpPattern l, RdpPattern r)715 		public RdpAbstractBinary (RdpPattern l, RdpPattern r)
716 		{
717 			this.l = l;
718 			this.r = r;
719 		}
720 
721 		RdpPattern l;
722 		public RdpPattern LValue {
723 			get { return l; }
724 			set { l = value; }
725 		}
726 
727 		RdpPattern r;
728 		public RdpPattern RValue {
729 			get { return r; }
730 			set { r = value; }
731 		}
732 
733 		RdpContentType computedContentType = RdpContentType.Invalid;
734 		public override RdpContentType ContentType {
735 			get {
736 				if (computedContentType == RdpContentType.Invalid) {
737 					if (l.ContentType == RdpContentType.Empty)
738 						computedContentType = r.ContentType;
739 					else if (r.ContentType == RdpContentType.Empty)
740 						computedContentType = l.ContentType;
741 					else if ((l.ContentType & RdpContentType.Simple) != 0 || ((r.ContentType & RdpContentType.Simple) != 0))
742 						throw new RelaxngException ("The content type of this group is invalid.");
743 					else
744 						computedContentType = RdpContentType.Complex;
745 				}
746 				return computedContentType;
747 			}
748 		}
749 
750 		bool expanded;
ExpandRef(Hashtable defs)751 		internal override RdpPattern ExpandRef (Hashtable defs)
752 		{
753 			if (!expanded) {
754 				l = l.ExpandRef (defs);
755 				r = r.ExpandRef (defs);
756 			}
757 			return this;
758 		}
759 
ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)760 		internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
761 		{
762 			if (visited.Contains (this))
763 				return this;
764 			visited.Add (this, this);
765 
766 			if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
767 				RValue.PatternType == RelaxngPatternType.NotAllowed) {
768 				result = true;
769 				return RdpNotAllowed.Instance;
770 			} else if (LValue.PatternType == RelaxngPatternType.Empty) {
771 				result = true;
772 				return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
773 			} else if (RValue.PatternType == RelaxngPatternType.Empty) {
774 				result = true;
775 				return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
776 			} else {
777 				LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
778 				RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
779 				return this;
780 			}
781 		}
782 
MarkReachableDefs()783 		internal override void MarkReachableDefs ()
784 		{
785 			l.MarkReachableDefs ();
786 			r.MarkReachableDefs ();
787 		}
788 
ContainsText()789 		internal override bool ContainsText()
790 		{
791 			return l.ContainsText () || r.ContainsText ();
792 		}
793 
794 		// 7.3 (group/interleave attribute names) and
795 		// part of 7.4 (interleave element names)
796 		// FIXME: Actually it should be done against the correct
797 		// simplified grammar, expanding all refs.
CheckNameOverlap(bool checkElements)798 		internal void CheckNameOverlap (bool checkElements)
799 		{
800 			if (RdpUtil.NamesOverlap (LValue, RValue, checkElements))
801 				throw new RelaxngException ("Duplicate attributes inside a group or an interleave is not allowed.");
802 			return;
803 		}
804 	}
805 
806 	// Choice
807 	public class RdpChoice : RdpAbstractBinary
808 	{
RdpChoice(RdpPattern l, RdpPattern r)809 		public RdpChoice (RdpPattern l, RdpPattern r) : base (l, r)
810 		{
811 		}
812 
813 		public override bool Nullable {
814 			get {
815 				if (!nullableComputed) {
816 					isNullable =
817 						LValue.Nullable || RValue.Nullable;
818 					nullableComputed = true;
819 				}
820 				return isNullable;
821 			}
822 		}
823 
824 		bool isTextValueDependentComputed;
825 		bool isTextValueDependent;
826 
827 		internal override bool IsTextValueDependent {
828 			get {
829 				if (!isTextValueDependentComputed) {
830 					isTextValueDependent = LValue.IsTextValueDependent || RValue.IsTextValueDependent;
831 					isTextValueDependentComputed = true;
832 				}
833 				return isTextValueDependent;
834 			}
835 		}
836 
837 		bool isContextDependentComputed;
838 		bool isContextDependent;
839 
840 		internal override bool IsContextDependent {
841 			get {
842 				if (!isContextDependentComputed) {
843 					isContextDependent = LValue.IsContextDependent || RValue.IsContextDependent;
844 					isContextDependentComputed = true;
845 				}
846 				return isContextDependent;
847 			}
848 		}
849 
850 		public override RelaxngPatternType PatternType {
851 			get { return RelaxngPatternType.Choice; }
852 		}
853 
854 		RdpContentType computedContentType = RdpContentType.Invalid;
855 		public override RdpContentType ContentType {
856 			get {
857 				if (computedContentType == RdpContentType.Invalid) {
858 					if (LValue.ContentType == RdpContentType.Simple ||
859 						RValue.ContentType == RdpContentType.Simple)
860 						computedContentType = RdpContentType.Simple;
861 					else
862 						computedContentType = base.ContentType;
863 				}
864 				return computedContentType;
865 			}
866 		}
867 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)868 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
869 		{
870 			LValue.GetLabels (elements, attributes, collectNameClass);
871 			RValue.GetLabels (elements, attributes, collectNameClass);
872 		}
873 
874 
ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)875 		internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
876 		{
877 			if (visited.Contains (this))
878 				return this;
879 			visited.Add (this, this);
880 
881 			if (LValue.PatternType == RelaxngPatternType.NotAllowed &&
882 				RValue.PatternType == RelaxngPatternType.NotAllowed) {
883 				result = true;
884 				return RdpNotAllowed.Instance;
885 			} else if (LValue.PatternType == RelaxngPatternType.NotAllowed) {
886 				result = true;
887 				return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
888 			} else if (RValue.PatternType == RelaxngPatternType.NotAllowed) {
889 				result = true;
890 				return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
891 			} else if (LValue.PatternType == RelaxngPatternType.Empty &&
892 				RValue.PatternType == RelaxngPatternType.Empty) {
893 				result = true;
894 				return RdpEmpty.Instance;
895 			} else if (RValue.PatternType == RelaxngPatternType.Empty) {
896 				result = true;
897 				RValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
898 				LValue = RdpEmpty.Instance;
899 				return this;
900 			} else {
901 				LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
902 				RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
903 				return this;
904 			}
905 		}
906 
TextDeriv(string s, XmlReader reader)907 		public override RdpPattern TextDeriv (string s, XmlReader reader)
908 		{
909 			return LValue.TextDeriv (s, reader).Choice (RValue.TextDeriv (s, reader));
910 		}
911 
TextDeriv(string s, XmlReader reader, MemoizationStore memo)912 		internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
913 		{
914 			return memo.TextDeriv (LValue, s, reader).Choice (memo.TextDeriv (RValue, s, reader));
915 		}
916 
EmptyTextDeriv(MemoizationStore memo)917 		internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
918 		{
919 			return memo.EmptyTextDeriv (LValue)
920 				.Choice (memo.EmptyTextDeriv (RValue));
921 		}
922 
TextOnlyDeriv()923 		internal override RdpPattern TextOnlyDeriv ()
924 		{
925 			return LValue.TextOnlyDeriv ().Choice (
926 				RValue.TextOnlyDeriv ());
927 		}
928 
TextOnlyDeriv(MemoizationStore memo)929 		internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
930 		{
931 			return memo.TextOnlyDeriv (LValue).Choice (
932 				memo.TextOnlyDeriv (RValue));
933 		}
934 
MixedTextDeriv()935 		internal override RdpPattern MixedTextDeriv ()
936 		{
937 			return LValue.MixedTextDeriv ().Choice (
938 				RValue.MixedTextDeriv ());
939 		}
940 
MixedTextDeriv(MemoizationStore memo)941 		internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
942 		{
943 			return memo.MixedTextDeriv (LValue).Choice (
944 				memo.MixedTextDeriv (RValue));
945 		}
946 
ApplyAfter(RdpApplyAfterHandler handler)947 		public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
948 		{
949 //			return handler (LValue).Choice (handler (RValue));
950 			return LValue.ApplyAfter (handler).Choice (RValue.ApplyAfter (handler));
951 		}
952 
StartTagOpenDeriv(string name, string ns)953 		public override RdpPattern StartTagOpenDeriv (string name, string ns)
954 		{
955 #if UseStatic
956 			return RdpUtil.Choice (
957 				RdpUtil.StartTagOpenDeriv (LValue, qname),
958 				RdpUtil.StartTagOpenDeriv (RValue, qname));
959 #else
960 			RdpPattern lDeriv = LValue.StartTagOpenDeriv (name, ns);
961 			return lDeriv.Choice (RValue.StartTagOpenDeriv (name, ns));
962 #endif
963 		}
964 
StartTagOpenDeriv(string name, string ns, MemoizationStore memo)965 		internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
966 		{
967 			RdpPattern lDeriv = memo.StartTagOpenDeriv (LValue, name, ns);
968 			return lDeriv.Choice (memo.StartTagOpenDeriv (RValue, name, ns));
969 		}
970 
971 		// attDeriv cx (Choice p1 p2) att =
972 		//  choice (attDeriv cx p1 att) (attDeriv cx p2 att)
AttDeriv(string name, string ns, string value, XmlReader reader)973 		public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
974 		{
975 			return LValue.AttDeriv (name, ns, value, reader)
976 				.Choice (RValue.AttDeriv (name, ns, value, reader));
977 		}
978 
StartAttDeriv(string name, string ns)979 		public override RdpPattern StartAttDeriv (string name, string ns)
980 		{
981 			RdpPattern lDeriv = LValue.StartAttDeriv (name, ns);
982 			return lDeriv.Choice (RValue.StartAttDeriv (name, ns));
983 		}
984 
StartAttDeriv(string name, string ns, MemoizationStore memo)985 		internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
986 		{
987 			return memo.StartAttDeriv (LValue, name, ns)
988 				.Choice (memo.StartAttDeriv (RValue, name, ns));
989 		}
990 
EndAttDeriv()991 		public override RdpPattern EndAttDeriv ()
992 		{
993 			return LValue.EndAttDeriv ().Choice (RValue.EndAttDeriv ());
994 		}
995 
EndAttDeriv(MemoizationStore memo)996 		internal override RdpPattern EndAttDeriv (MemoizationStore memo)
997 		{
998 			return memo.EndAttDeriv (LValue).Choice (memo.EndAttDeriv (RValue));
999 		}
1000 
1001 		// startTagCloseDeriv (Choice p1 p2) =
1002 		//  choice (startTagCloseDeriv p1) (startTagCloseDeriv p2)
StartTagCloseDeriv()1003 		public override RdpPattern StartTagCloseDeriv ()
1004 		{
1005 			return LValue.StartTagCloseDeriv ()
1006 				.Choice (RValue.StartTagCloseDeriv ());
1007 		}
1008 
StartTagCloseDeriv(MemoizationStore memo)1009 		internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1010 		{
1011 			return memo.StartTagCloseDeriv (LValue)
1012 				.Choice (memo.StartTagCloseDeriv (RValue));
1013 		}
1014 
EndTagDeriv()1015 		public override RdpPattern EndTagDeriv ()
1016 		{
1017 			return LValue.EndTagDeriv ().Choice (RValue.EndTagDeriv ());
1018 		}
1019 
EndTagDeriv(MemoizationStore memo)1020 		internal override RdpPattern EndTagDeriv (MemoizationStore memo)
1021 		{
1022 			return memo.EndTagDeriv (LValue).Choice (memo.EndTagDeriv (RValue));
1023 		}
1024 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1025 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1026 		{
1027 			LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1028 			RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1029 		}
1030 	}
1031 
1032 	// Interleave
1033 	public class RdpInterleave : RdpAbstractBinary
1034 	{
RdpInterleave(RdpPattern l, RdpPattern r)1035 		public RdpInterleave (RdpPattern l, RdpPattern r) : base (l, r)
1036 		{
1037 		}
1038 
1039 		public override bool Nullable {
1040 			get {
1041 				if (!nullableComputed) {
1042 					isNullable =
1043 						LValue.Nullable && RValue.Nullable;
1044 					nullableComputed = true;
1045 				}
1046 				return isNullable;
1047 			}
1048 		}
1049 
1050 		internal override bool IsTextValueDependent {
1051 			get { return LValue.IsTextValueDependent || RValue.IsTextValueDependent; }
1052 		}
1053 
1054 		internal override bool IsContextDependent {
1055 			get { return LValue.IsContextDependent || RValue.IsContextDependent; }
1056 		}
1057 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1058 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1059 		{
1060 			LValue.GetLabels (elements, attributes, collectNameClass);
1061 			RValue.GetLabels (elements, attributes, collectNameClass);
1062 		}
1063 
ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)1064 		internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1065 		{
1066 			if (visited.Contains (this))
1067 				return this;
1068 			visited.Add (this, this);
1069 
1070 			if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
1071 				RValue.PatternType == RelaxngPatternType.NotAllowed) {
1072 				result = true;
1073 				return RdpNotAllowed.Instance;
1074 			} else {
1075 				LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
1076 				RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
1077 				return this;
1078 			}
1079 		}
1080 
TextDeriv(string s, XmlReader reader)1081 		public override RdpPattern TextDeriv (string s, XmlReader reader)
1082 		{
1083 			return LValue.TextDeriv (s, reader).Interleave (RValue)
1084 				.Choice (LValue.Interleave (RValue.TextDeriv (s, reader)));
1085 		}
1086 
TextDeriv(string s, XmlReader reader, MemoizationStore memo)1087 		internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1088 		{
1089 			return memo.TextDeriv (LValue, s, reader).Interleave (RValue)
1090 				.Choice (LValue.Interleave (memo.TextDeriv (RValue, s, reader)));
1091 		}
1092 
EmptyTextDeriv(MemoizationStore memo)1093 		internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1094 		{
1095 			return memo.EmptyTextDeriv (LValue).Interleave (RValue)
1096 				.Choice (LValue.Interleave (memo.EmptyTextDeriv (RValue)));
1097 		}
1098 
TextOnlyDeriv()1099 		internal override RdpPattern TextOnlyDeriv ()
1100 		{
1101 			return LValue.TextOnlyDeriv ().Interleave (
1102 				RValue.TextOnlyDeriv ());
1103 		}
1104 
TextOnlyDeriv(MemoizationStore memo)1105 		internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1106 		{
1107 			return memo.TextOnlyDeriv (LValue).Interleave (
1108 				memo.TextOnlyDeriv (RValue));
1109 		}
1110 
MixedTextDeriv()1111 		internal override RdpPattern MixedTextDeriv ()
1112 		{
1113 			return LValue.MixedTextDeriv ().Interleave (RValue).Choice (
1114 				LValue.Interleave (RValue.MixedTextDeriv ()));
1115 		}
1116 
MixedTextDeriv(MemoizationStore memo)1117 		internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1118 		{
1119 			return memo.MixedTextDeriv (LValue).Interleave (RValue).Choice (
1120 				LValue.Interleave (memo.MixedTextDeriv (RValue)));
1121 		}
1122 
1123 		// => choice (applyAfter (flip interleave p2) (startTagOpenDeriv p1 qn)) (applyAfter (interleave p1) (startTagOpenDeriv p2 qn)
1124 		// => p1.startTagOpenDeriv(qn).applyAfter (flip interleave p2).choice (p2.startTagOpenDeriv(qn).applyAfter (interleave p1) )
StartTagOpenDeriv(string name, string ns)1125 		public override RdpPattern StartTagOpenDeriv (string name, string ns)
1126 		{
1127 			RdpPattern handledL = LValue.StartTagOpenDeriv (name, ns);
1128 			RdpPattern handledR = RValue.StartTagOpenDeriv (name, ns);
1129 			RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1130 			RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1131 			RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1132 			return choiceL.Choice (choiceR);
1133 		}
1134 
StartTagOpenDeriv(string name, string ns, MemoizationStore memo)1135 		internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1136 		{
1137 			RdpPattern handledL = memo.StartTagOpenDeriv (LValue, name, ns);
1138 			RdpPattern handledR = memo.StartTagOpenDeriv (RValue, name, ns);
1139 			RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1140 			RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1141 			RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1142 			return choiceL.Choice (choiceR);
1143 		}
1144 
1145 		// attDeriv cx (Interleave p1 p2) att =
1146 		//  choice (interleave (attDeriv cx p1 att) p2)
1147 		//         (interleave p1 (attDeriv cx p2 att))
AttDeriv(string name, string ns, string value, XmlReader reader)1148 		public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1149 		{
1150 			return LValue.AttDeriv (name, ns, value, reader)
1151 				.Interleave (RValue)
1152 				.Choice (LValue.Interleave (
1153 					RValue.AttDeriv (name, ns, value, reader)));
1154 		}
1155 
StartAttDeriv(string name, string ns)1156 		public override RdpPattern StartAttDeriv (string name, string ns)
1157 		{
1158 			RdpPattern handledL = LValue.StartAttDeriv (name, ns);
1159 			RdpPattern handledR = RValue.StartAttDeriv (name, ns);
1160 			RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1161 			RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1162 			RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1163 			return choiceL.Choice (choiceR);
1164 		}
1165 
StartAttDeriv(string name, string ns, MemoizationStore memo)1166 		internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1167 		{
1168 			RdpPattern handledL = memo.StartAttDeriv (LValue, name, ns);
1169 			RdpPattern handledR = memo.StartAttDeriv (RValue, name, ns);
1170 			RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1171 			RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1172 			RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1173 			return choiceL.Choice (choiceR);
1174 		}
1175 
1176 		// startTagCloseDeriv (Interleave p1 p2) =
1177 		//  interleave (startTagCloseDeriv p1) (startTagCloseDeriv p2)
StartTagCloseDeriv()1178 		public override RdpPattern StartTagCloseDeriv ()
1179 		{
1180 			return LValue.StartTagCloseDeriv ()
1181 				.Interleave (RValue.StartTagCloseDeriv ());
1182 		}
1183 
StartTagCloseDeriv(MemoizationStore memo)1184 		internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1185 		{
1186 			return memo.StartTagCloseDeriv (LValue)
1187 				.Interleave (memo.StartTagCloseDeriv (RValue));
1188 		}
1189 
1190 		public override RelaxngPatternType PatternType {
1191 			get { return RelaxngPatternType.Interleave; }
1192 		}
1193 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1194 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1195 		{
1196 			if (list)
1197 				throw new RelaxngException ("interleave is not allowed under a list.");
1198 			if (dataExcept)
1199 				throw new RelaxngException ("interleave is not allowed under except of a data.");
1200 
1201 			// 7.1
1202 			LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
1203 			RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
1204 
1205 			// unique name analysis - 7.3 and part of 7.4
1206 			CheckNameOverlap (true);
1207 
1208 			// (2) text/text prohibited
1209 			if (LValue.ContainsText () && RValue.ContainsText ())
1210 				throw new RelaxngException ("Both branches of the interleave contains a text pattern.");
1211 		}
1212 	}
1213 
1214 	// Group
1215 	public class RdpGroup : RdpAbstractBinary
1216 	{
RdpGroup(RdpPattern l, RdpPattern r)1217 		public RdpGroup (RdpPattern l, RdpPattern r) : base (l, r)
1218 		{
1219 		}
1220 
1221 		public override bool Nullable {
1222 			get {
1223 				if (!nullableComputed) {
1224 					isNullable =
1225 						LValue.Nullable && RValue.Nullable;
1226 					nullableComputed = true;
1227 				}
1228 				return isNullable;
1229 			}
1230 		}
1231 
1232 		internal override bool IsTextValueDependent {
1233 			get { return LValue.IsTextValueDependent || (LValue.Nullable ? RValue.IsTextValueDependent : false); }
1234 		}
1235 
1236 		internal override bool IsContextDependent {
1237 			get { return LValue.IsContextDependent || (LValue.Nullable ? RValue.IsContextDependent : false); }
1238 		}
1239 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1240 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1241 		{
1242 			LValue.GetLabels (elements, attributes, collectNameClass);
1243 			if (LValue.Nullable)
1244 				RValue.GetLabels (elements, attributes, collectNameClass);
1245 			else
1246 				RValue.GetLabels (null, attributes, collectNameClass);
1247 		}
1248 
TextDeriv(string s, XmlReader reader)1249 		public override RdpPattern TextDeriv (string s, XmlReader reader)
1250 		{
1251 			RdpPattern p = LValue.TextDeriv (s, reader);
1252 			p = (p.PatternType == RelaxngPatternType.NotAllowed) ?
1253 				p : p.Group (RValue);
1254 			return LValue.Nullable ?
1255 				p.Choice (RValue.TextDeriv (s, reader)) : p;
1256 		}
1257 
TextDeriv(string s, XmlReader reader, MemoizationStore memo)1258 		internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1259 		{
1260 			RdpPattern p = memo.TextDeriv (LValue, s, reader);
1261 			p = (p.PatternType == RelaxngPatternType.NotAllowed) ?
1262 				p : p.Group (RValue);
1263 			return LValue.Nullable ?
1264 				p.Choice (memo.TextDeriv (RValue, s, reader)) : p;
1265 		}
1266 
EmptyTextDeriv(MemoizationStore memo)1267 		internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1268 		{
1269 			RdpPattern p = memo.EmptyTextDeriv (LValue);
1270 			p = p.PatternType == RelaxngPatternType.NotAllowed ?
1271 				p : p.Group (RValue);
1272 			return LValue.Nullable ?
1273 				p.Choice (memo.EmptyTextDeriv (RValue)) : p;
1274 		}
1275 
TextOnlyDeriv()1276 		internal override RdpPattern TextOnlyDeriv ()
1277 		{
1278 			RdpPattern p = LValue.TextOnlyDeriv ();
1279 			return p.PatternType == RelaxngPatternType.NotAllowed ?
1280 				p : p.Group (RValue.TextOnlyDeriv ());
1281 		}
1282 
TextOnlyDeriv(MemoizationStore memo)1283 		internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1284 		{
1285 			RdpPattern p = memo.TextOnlyDeriv (LValue);
1286 			return p.PatternType == RelaxngPatternType.NotAllowed ?
1287 				p : p.Group (memo.TextOnlyDeriv (RValue));
1288 		}
1289 
MixedTextDeriv()1290 		internal override RdpPattern MixedTextDeriv ()
1291 		{
1292 			RdpPattern p = LValue.MixedTextDeriv ().Group (RValue);
1293 			return LValue.Nullable ?
1294 				p.Choice (RValue.MixedTextDeriv ()) : p;
1295 		}
1296 
MixedTextDeriv(MemoizationStore memo)1297 		internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1298 		{
1299 			RdpPattern p = memo.MixedTextDeriv (LValue).Group (RValue);
1300 			return LValue.Nullable ?
1301 				p.Choice (memo.MixedTextDeriv (RValue)) : p;
1302 		}
1303 
1304 		// startTagOpenDeriv (Group p1 p2) qn =
1305 		//  let x = applyAfter (flip group p2) (startTagOpenDeriv p1 qn)
1306 		//  in if nullable p1 then
1307 		//       choice x (startTagOpenDeriv p2 qn)
1308 		//     else
1309 		//       x
StartTagOpenDeriv(string name, string ns)1310 		public override RdpPattern StartTagOpenDeriv (string name, string ns)
1311 		{
1312 			RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
1313 			RdpFlip f = MakeFlip (RdpUtil.GroupFunction, RValue);
1314 			RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1315 			if (LValue.Nullable)
1316 				return x.Choice (RValue.StartTagOpenDeriv (name, ns));
1317 			else
1318 				return x;
1319 		}
1320 
StartTagOpenDeriv(string name, string ns, MemoizationStore memo)1321 		internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1322 		{
1323 			RdpPattern handled = memo.StartTagOpenDeriv (LValue, name, ns);
1324 			RdpFlip f = MakeFlip (RdpUtil.GroupFunction, RValue);
1325 			RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1326 			if (LValue.Nullable)
1327 				return x.Choice (memo.StartTagOpenDeriv (RValue, name, ns));
1328 			else
1329 				return x;
1330 		}
1331 
1332 		// attDeriv cx (Group p1 p2) att =
1333 		//  choice (group (attDeriv cx p1 att) p2)
1334 		//         (group p1 (attDeriv cx p2 att))
AttDeriv(string name, string ns, string value, XmlReader reader)1335 		public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1336 		{
1337 			return LValue.AttDeriv (name, ns, value, reader).Group (RValue)
1338 				.Choice (LValue.Group (
1339 					RValue.AttDeriv (name, ns, value, reader)));
1340 		}
1341 
1342 		// startAttDeriv (group p1 p2) == startAttDeriv (interleave p1 p2)
StartAttDeriv(string name, string ns)1343 		public override RdpPattern StartAttDeriv (string name, string ns)
1344 		{
1345 			RdpPattern handledL = LValue.StartAttDeriv (name, ns);
1346 			RdpPattern handledR = RValue.StartAttDeriv (name, ns);
1347 			RdpFlip flipL = MakeFlip (RdpUtil.GroupFunction, RValue);
1348 			RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1349 			RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Group));
1350 			return choiceL.Choice (choiceR);
1351 		}
1352 
StartAttDeriv(string name, string ns, MemoizationStore memo)1353 		internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1354 		{
1355 			RdpPattern handledL = memo.StartAttDeriv (LValue, name, ns);
1356 			RdpPattern handledR = memo.StartAttDeriv (RValue, name, ns);
1357 			RdpFlip flipL = MakeFlip (RdpUtil.GroupFunction, RValue);
1358 			RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1359 			RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Group));
1360 			return choiceL.Choice (choiceR);
1361 		}
1362 
1363 		// startTagCloseDeriv (Group p1 p2) =
1364 		//  group (startTagCloseDeriv p1) (startTagCloseDeriv p2)
StartTagCloseDeriv()1365 		public override RdpPattern StartTagCloseDeriv ()
1366 		{
1367 			RdpPattern p = LValue.StartTagCloseDeriv ();
1368 			return p.PatternType == RelaxngPatternType.NotAllowed ?
1369 				p : p.Group (RValue.StartTagCloseDeriv ());
1370 		}
1371 
StartTagCloseDeriv(MemoizationStore memo)1372 		internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1373 		{
1374 			RdpPattern p = memo.StartTagCloseDeriv (LValue);
1375 			return p.PatternType == RelaxngPatternType.NotAllowed ?
1376 				p : p.Group (memo.StartTagCloseDeriv (RValue));
1377 		}
1378 
1379 		public override RelaxngPatternType PatternType {
1380 			get { return RelaxngPatternType.Group; }
1381 		}
1382 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1383 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1384 		{
1385 			if (dataExcept)
1386 				throw new RelaxngException ("interleave is not allowed under except of a data.");
1387 
1388 			LValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
1389 			RValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
1390 
1391 			// 7.3
1392 			CheckNameOverlap (false);
1393 		}
1394 	}
1395 
1396 	public abstract class RdpAbstractSingleContent : RdpPattern
1397 	{
1398 		RdpPattern child;
1399 		bool isExpanded;
1400 
ExpandRef(Hashtable defs)1401 		internal override RdpPattern ExpandRef (Hashtable defs)
1402 		{
1403 			if (!isExpanded)
1404 				child = child.ExpandRef (defs);
1405 			return this;
1406 		}
1407 
RdpAbstractSingleContent(RdpPattern p)1408 		public RdpAbstractSingleContent (RdpPattern p)
1409 		{
1410 			this.child = p;
1411 		}
1412 
1413 		public RdpPattern Child {
1414 			get { return child; }
1415 			set { child = value; }
1416 		}
1417 
MarkReachableDefs()1418 		internal override void MarkReachableDefs ()
1419 		{
1420 			child.MarkReachableDefs ();
1421 		}
1422 
ContainsText()1423 		internal override bool ContainsText()
1424 		{
1425 			return child.ContainsText ();
1426 		}
1427 	}
1428 
1429 	// OneOrMore
1430 	public class RdpOneOrMore : RdpAbstractSingleContent
1431 	{
RdpOneOrMore(RdpPattern p)1432 		public RdpOneOrMore (RdpPattern p) : base (p)
1433 		{
1434 		}
1435 
1436 		public override RelaxngPatternType PatternType {
1437 			get { return RelaxngPatternType.OneOrMore; }
1438 		}
1439 
1440 		public override RdpContentType ContentType {
1441 			get {
1442 				if (Child.ContentType == RdpContentType.Simple)
1443 					throw new RelaxngException ("Invalid content type was found.");
1444 				return Child.ContentType;
1445 			}
1446 		}
1447 
1448 		public override bool Nullable {
1449 			get { return Child.Nullable; }
1450 		}
1451 
1452 		internal override bool IsTextValueDependent {
1453 			get { return Child.IsTextValueDependent; }
1454 		}
1455 
1456 		internal override bool IsContextDependent {
1457 			get { return Child.IsContextDependent; }
1458 		}
1459 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1460 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1461 		{
1462 			Child.GetLabels (elements, attributes, collectNameClass);
1463 		}
1464 
ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)1465 		internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1466 		{
1467 			if (visited.Contains (this))
1468 				return this;
1469 			visited.Add (this, this);
1470 
1471 			if (Child.PatternType == RelaxngPatternType.NotAllowed) {
1472 				result = true;
1473 				return RdpNotAllowed.Instance;
1474 			} else if (Child.PatternType == RelaxngPatternType.Empty)
1475 				return RdpEmpty.Instance;
1476 			else {
1477 				Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
1478 				return this;
1479 			}
1480 		}
1481 
TextDeriv(string s, XmlReader reader)1482 		public override RdpPattern TextDeriv (string s, XmlReader reader)
1483 		{
1484 			RdpPattern p = Child.TextDeriv (s, reader);
1485 			return p.PatternType == RelaxngPatternType.NotAllowed ?
1486 				p : p.Group (this.Choice (RdpEmpty.Instance));
1487 		}
1488 
TextDeriv(string s, XmlReader reader, MemoizationStore memo)1489 		internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1490 		{
1491 			RdpPattern p = memo.TextDeriv (Child, s, reader);
1492 			return p.PatternType == RelaxngPatternType.NotAllowed ?
1493 				p : p.Group (this.Choice (RdpEmpty.Instance));
1494 		}
1495 
EmptyTextDeriv(MemoizationStore memo)1496 		internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1497 		{
1498 			RdpPattern p = memo.EmptyTextDeriv (Child);
1499 			return p.PatternType == RelaxngPatternType.NotAllowed ?
1500 				p : p.Group (this.Choice (RdpEmpty.Instance));
1501 		}
1502 
TextOnlyDeriv()1503 		internal override RdpPattern TextOnlyDeriv ()
1504 		{
1505 			return Child.TextOnlyDeriv ().OneOrMore ();
1506 		}
1507 
TextOnlyDeriv(MemoizationStore memo)1508 		internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1509 		{
1510 			return memo.TextOnlyDeriv (Child).OneOrMore ();
1511 		}
1512 
MixedTextDeriv()1513 		internal override RdpPattern MixedTextDeriv ()
1514 		{
1515 			RdpPattern p = Child.MixedTextDeriv ();
1516 			return p.PatternType == RelaxngPatternType.NotAllowed ?
1517 				p : p.Group (this.Choice (RdpEmpty.Instance));
1518 		}
1519 
MixedTextDeriv(MemoizationStore memo)1520 		internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1521 		{
1522 			RdpPattern p = memo.MixedTextDeriv (Child);
1523 			return p.PatternType == RelaxngPatternType.NotAllowed ?
1524 				p : p.Group (this.Choice (RdpEmpty.Instance));
1525 		}
1526 
1527 		// attDeriv cx (OneOrMore p) att =
1528 		//  group (attDeriv cx p att) (choice (OneOrMore p) Empty)
AttDeriv(string name, string ns, string value, XmlReader reader)1529 		public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1530 		{
1531 			RdpPattern p = Child.AttDeriv (name, ns, value, reader);
1532 			return p.PatternType == RelaxngPatternType.NotAllowed ?
1533 				p : p.Group (Choice (RdpEmpty.Instance));
1534 		}
1535 
1536 		// startTagOpenDeriv (OneOrMore p) qn =
1537 		//  applyAfter (flip group (choice (OneOrMore p) Empty))
1538 		//             (startTagOpenDeriv p qn)
StartTagOpenDeriv(string name, string ns)1539 		public override RdpPattern StartTagOpenDeriv (string name, string ns)
1540 		{
1541 			RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1542 			RdpPattern handled = Child.StartTagOpenDeriv (name, ns);
1543 			RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1544 			return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1545 		}
1546 
StartTagOpenDeriv(string name, string ns, MemoizationStore memo)1547 		internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1548 		{
1549 			RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1550 			RdpPattern handled = memo.StartTagOpenDeriv (Child, name, ns);
1551 			RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1552 			return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1553 		}
1554 
StartAttDeriv(string name, string ns)1555 		public override RdpPattern StartAttDeriv (string name, string ns)
1556 		{
1557 			RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1558 			RdpPattern handled = Child.StartAttDeriv (name, ns);
1559 			RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1560 			return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1561 		}
1562 
StartAttDeriv(string name, string ns, MemoizationStore memo)1563 		internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1564 		{
1565 			RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1566 			RdpPattern handled = memo.StartAttDeriv (Child, name, ns);
1567 			RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1568 			return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1569 		}
1570 
1571 		// startTagCloseDeriv (OneOrMore p) =
1572 		//  oneOrMore (startTagCloseDeriv p)
StartTagCloseDeriv()1573 		public override RdpPattern StartTagCloseDeriv ()
1574 		{
1575 #if UseStatic
1576 			return RdpUtil.OneOrMore (
1577 				RdpUtil.StartTagCloseDeriv (children));
1578 #else
1579 			return Child.StartTagCloseDeriv ().OneOrMore ();
1580 #endif
1581 		}
1582 
StartTagCloseDeriv(MemoizationStore memo)1583 		internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1584 		{
1585 			return memo.StartTagCloseDeriv (Child).OneOrMore ();
1586 		}
1587 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1588 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1589 		{
1590 			if (dataExcept)
1591 				throw new RelaxngException ("oneOrMore is not allowed under except of a data.");
1592 			this.Child.CheckConstraints (attribute, true, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1593 		}
1594 	}
1595 
1596 	// List
1597 	public class RdpList : RdpAbstractSingleContent
1598 	{
RdpList(RdpPattern p)1599 		public RdpList (RdpPattern p) : base (p)
1600 		{
1601 		}
1602 
ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)1603 		internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1604 		{
1605 			if (visited.Contains (this))
1606 				return this;
1607 			visited.Add (this, this);
1608 
1609 			if (Child.PatternType == RelaxngPatternType.NotAllowed) {
1610 				result = true;
1611 				return RdpNotAllowed.Instance;
1612 			} else {
1613 				Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
1614 				return this;
1615 			}
1616 		}
1617 
1618 		public override bool Nullable {
1619 			get { return false; }
1620 		}
1621 
1622 		internal override bool IsTextValueDependent {
1623 			get { return true; }
1624 		}
1625 
1626 		internal override bool IsContextDependent {
1627 			get { return Child.IsContextDependent; }
1628 		}
1629 
1630 		public override RelaxngPatternType PatternType {
1631 			get { return RelaxngPatternType.List; }
1632 		}
1633 
1634 		public override RdpContentType ContentType {
1635 			get { return RdpContentType.Simple; }
1636 		}
1637 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1638 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1639 		{
1640 			Child.GetLabels (elements, attributes, collectNameClass);
1641 		}
1642 
TextDeriv(string s, XmlReader reader)1643 		public override RdpPattern TextDeriv (string s, XmlReader reader)
1644 		{
1645 			s = Util.NormalizeWhitespace (s);
1646 
1647 			RdpPattern p = Child.ListDeriv (s.Split (RdpUtil.WhitespaceChars), 0, reader);
1648 			if (p.Nullable)
1649 				return RdpEmpty.Instance;
1650 			else
1651 				return RdpNotAllowed.Instance;
1652 		}
1653 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1654 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1655 		{
1656 			if (list)
1657 				throw new RelaxngException ("list is not allowed uner another list.");
1658 			if (dataExcept)
1659 				throw new RelaxngException ("list is not allowed under except of a data.");
1660 			this.Child.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, true, dataExcept);
1661 		}
1662 	}
1663 
1664 	// Data
1665 	public class RdpData : RdpPattern
1666 	{
RdpData(RdpDatatype dt)1667 		public RdpData (RdpDatatype dt)
1668 		{
1669 			this.dt = dt;
1670 		}
1671 
1672 		RdpDatatype dt;
1673 		public RdpDatatype Datatype {
1674 			get { return dt; }
1675 		}
1676 
1677 		public override bool Nullable {
1678 			get { return false; }
1679 		}
1680 
1681 		internal override bool IsTextValueDependent {
1682 			get { return true; }
1683 		}
1684 
1685 		internal override bool IsContextDependent {
1686 			get { return dt.IsContextDependent; }
1687 		}
1688 
1689 		public override RelaxngPatternType PatternType {
1690 			get { return RelaxngPatternType.Data; }
1691 		}
1692 
1693 		public override RdpContentType ContentType {
1694 			get { return RdpContentType.Simple; }
1695 		}
1696 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1697 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1698 		{
1699 			// do nothing.
1700 		}
1701 
TextDeriv(string s, XmlReader reader)1702 		public override RdpPattern TextDeriv (string s, XmlReader reader)
1703 		{
1704 			if (dt.IsAllowed (s, reader))
1705 				return RdpEmpty.Instance;
1706 			else
1707 				return RdpNotAllowed.Instance;
1708 		}
1709 
MarkReachableDefs()1710 		internal override void MarkReachableDefs ()
1711 		{
1712 			// do nothing
1713 		}
1714 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1715 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1716 		{
1717 			// do nothing
1718 		}
1719 
ContainsText()1720 		internal override bool ContainsText()
1721 		{
1722 			return false;
1723 		}
1724 	}
1725 
1726 	// DataExcept
1727 	public class RdpDataExcept : RdpData
1728 	{
RdpDataExcept(RdpDatatype dt, RdpPattern except)1729 		public RdpDataExcept (RdpDatatype dt, RdpPattern except)
1730 			: base (dt)
1731 		{
1732 			this.except = except;
1733 		}
1734 
1735 		RdpPattern except;
1736 		public RdpPattern Except {
1737 			get { return except; }
1738 			set { except = value; }
1739 		}
1740 
1741 		public override RelaxngPatternType PatternType {
1742 			get { return RelaxngPatternType.DataExcept; }
1743 		}
1744 
1745 		public override RdpContentType ContentType {
1746 			get {
1747 				RdpContentType c = except.ContentType; // conformance required for except pattern.
1748 				return RdpContentType.Simple;
1749 			}
1750 		}
1751 
ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)1752 		internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1753 		{
1754 			if (visited.Contains (this))
1755 				return this;
1756 			visited.Add (this, this);
1757 
1758 			if (except.PatternType == RelaxngPatternType.NotAllowed) {
1759 				result = true;
1760 				return new RdpData (this.Datatype);
1761 			} else {
1762 				except = except.ReduceEmptyAndNotAllowed (ref result, visited);
1763 				return this;
1764 			}
1765 		}
1766 
TextDeriv(string s, XmlReader reader)1767 		public override RdpPattern TextDeriv (string s, XmlReader reader)
1768 		{
1769 			if (Datatype.IsAllowed (s, reader) && !except.TextDeriv (s, reader).Nullable)
1770 				return RdpEmpty.Instance;
1771 			else
1772 				return RdpNotAllowed.Instance;
1773 		}
1774 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1775 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1776 		{
1777 			this.except.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, true);
1778 		}
1779 
ContainsText()1780 		internal override bool ContainsText()
1781 		{
1782 			return except.ContainsText ();
1783 		}
1784 	}
1785 
1786 	// Value
1787 	public class RdpValue : RdpPattern
1788 	{
RdpValue(RdpDatatype dt, string value)1789 		public RdpValue (RdpDatatype dt, string value)
1790 		{
1791 			this.dt = dt;
1792 			this.value = value;
1793 		}
1794 
1795 		RdpDatatype dt;
1796 		public RdpDatatype Datatype {
1797 			get { return dt; }
1798 		}
1799 
1800 		string value;
1801 		public string Value {
1802 			get { return value; }
1803 		}
1804 
1805 		public override bool Nullable {
1806 			get { return false; }
1807 		}
1808 
1809 		internal override bool IsTextValueDependent {
1810 			get { return true; }
1811 		}
1812 
1813 		internal override bool IsContextDependent {
1814 			get { return dt.IsContextDependent; }
1815 		}
1816 
1817 		public override RelaxngPatternType PatternType {
1818 			get { return RelaxngPatternType.Value; }
1819 		}
1820 
1821 		public override RdpContentType ContentType {
1822 			get { return RdpContentType.Simple; }
1823 		}
1824 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1825 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1826 		{
1827 			// do nothing
1828 		}
1829 
1830 		string cachedValue;
1831 		RdpPattern cachedPattern;
1832 
TextDeriv(string s, XmlReader reader)1833 		public override RdpPattern TextDeriv (string s, XmlReader reader)
1834 		{
1835 			if (s == cachedValue && !IsContextDependent)
1836 				return cachedPattern;
1837 			cachedPattern = TextDerivCore (s, reader);
1838 			cachedValue = s;
1839 			return cachedPattern;
1840 		}
1841 
TextDerivCore(string s, XmlReader reader)1842 		RdpPattern TextDerivCore (string s, XmlReader reader)
1843 		{
1844 			if (dt.IsTypeEqual (value, s, reader))
1845 				return RdpEmpty.Instance;
1846 			else
1847 				return RdpNotAllowed.Instance;
1848 		}
1849 
MarkReachableDefs()1850 		internal override void MarkReachableDefs ()
1851 		{
1852 			// do nothing
1853 		}
1854 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1855 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1856 		{
1857 			// nothing to be checked
1858 		}
1859 
ContainsText()1860 		internal override bool ContainsText()
1861 		{
1862 			return false;
1863 		}
1864 	}
1865 
1866 	// Attribute
1867 	public class RdpAttribute : RdpPattern
1868 	{
RdpAttribute(RdpNameClass nameClass, RdpPattern p)1869 		public RdpAttribute (RdpNameClass nameClass, RdpPattern p)
1870 		{
1871 			this.nameClass = nameClass;
1872 			this.children = p;
1873 		}
1874 
1875 		RdpNameClass nameClass;
1876 		public RdpNameClass NameClass {
1877 			get { return nameClass; }
1878 		}
1879 
1880 		RdpPattern children;
1881 		public RdpPattern Children {
1882 			get { return children; }
1883 			set { children = value; }
1884 		}
1885 
1886 		public override bool Nullable {
1887 			get { return false; }
1888 		}
1889 
1890 		internal override bool IsTextValueDependent {
1891 			get { return false; }
1892 		}
1893 
1894 		internal override bool IsContextDependent {
1895 			get { return false; }
1896 		}
1897 
1898 		public override RelaxngPatternType PatternType {
1899 			get { return RelaxngPatternType.Attribute; }
1900 		}
1901 
1902 		public override RdpContentType ContentType {
1903 			get { return RdpContentType.Empty; }
1904 		}
1905 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1906 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1907 		{
1908 			if (attributes != null) {
1909 				if (collectNameClass)
1910 					attributes [NameClass] = NameClass;
1911 				else
1912 					AddNameLabel (attributes, NameClass);
1913 			}
1914 		}
1915 
1916 		bool isExpanded;
ExpandRef(Hashtable defs)1917 		internal override RdpPattern ExpandRef (Hashtable defs)
1918 		{
1919 			if (!isExpanded) {
1920 				isExpanded = true;
1921 				children = children.ExpandRef (defs);
1922 			}
1923 			return this;
1924 		}
1925 
ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)1926 		internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1927 		{
1928 			if (visited.Contains (this))
1929 				return this;
1930 			visited.Add (this, this);
1931 
1932 			if (children.PatternType == RelaxngPatternType.NotAllowed) {
1933 				result = true;
1934 				return RdpNotAllowed.Instance;
1935 			} else {
1936 				children = children.ReduceEmptyAndNotAllowed (ref result, visited);
1937 				return this;
1938 			}
1939 		}
1940 
1941 		// attDeriv cx (Attribute nc p) (AttributeNode qn s) =
1942 		//  if contains nc qn && valueMatch cx p s then Empty else NotAllowed
AttDeriv(string name, string ns, string value, XmlReader reader)1943 		public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1944 		{
1945 			// If value is null, then does not check ValueMatch.
1946 #if UseStatic
1947 			if (RdpUtil.Contains (this.nameClass, att.QName)
1948 				&& (value == null || RdpUtil.ValueMatch (ctx, this.children, att.Value)))
1949 				return RdpEmpty.Instance;
1950 			else
1951 				return RdpNotAllowed.Instance;
1952 #else
1953 			if (nameClass.Contains (name, ns) &&
1954 				(value == null || children.ValueMatch (value, reader)))
1955 				return RdpEmpty.Instance;
1956 			else
1957 				return RdpNotAllowed.Instance;
1958 #endif
1959 		}
1960 
StartAttDeriv(string name, string ns)1961 		public override RdpPattern StartAttDeriv (string name, string ns)
1962 		{
1963 			return nameClass.Contains (name, ns) ?
1964 				children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance;
1965 		}
1966 
StartAttDeriv(string name, string ns, MemoizationStore memo)1967 		internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1968 		{
1969 			return nameClass.Contains (name, ns) ?
1970 				children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance;
1971 		}
1972 
1973 		// startTagCloseDeriv (Attribute _ _) = NotAllowed
StartTagCloseDeriv()1974 		public override RdpPattern StartTagCloseDeriv ()
1975 		{
1976 			return RdpNotAllowed.Instance;
1977 		}
1978 
StartTagCloseDeriv(MemoizationStore memo)1979 		internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1980 		{
1981 			return RdpNotAllowed.Instance;
1982 		}
1983 
MarkReachableDefs()1984 		internal override void MarkReachableDefs ()
1985 		{
1986 			children.MarkReachableDefs ();
1987 		}
1988 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1989 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1990 		{
1991 			// 7.1.1 and 7.1.2
1992 			if (attribute || oneOrMoreGroup || oneOrMoreInterleave || list || dataExcept)
1993 				throw new RelaxngException ("Not allowed attribute occurence was specified in the pattern.");
1994 
1995 			// latter part of 7.3
1996 			if (!oneOrMore && NameClass.HasInfiniteName)
1997 				throw new RelaxngException ("Attributes that has an infinite name class must be repeatable.");
1998 
1999 			this.Children.CheckConstraints (true, oneOrMore, false, false, false, false);
2000 		}
2001 
ContainsText()2002 		internal override bool ContainsText()
2003 		{
2004 			// This method is to detect text pattern inside interleave child.
2005 			// return children.ContainsText ();
2006 			return false;
2007 		}
2008 	}
2009 
2010 	// Element
2011 	public class RdpElement : RdpPattern
2012 	{
RdpElement(RdpNameClass nameClass, RdpPattern p)2013 		public RdpElement (RdpNameClass nameClass, RdpPattern p)
2014 		{
2015 			this.nameClass = nameClass;
2016 			this.children = p;
2017 		}
2018 
2019 		RdpNameClass nameClass;
2020 		public RdpNameClass NameClass {
2021 			get { return nameClass; }
2022 		}
2023 
2024 		RdpPattern children;
2025 		public RdpPattern Children {
2026 			get { return children; }
2027 			set { children = value; }
2028 		}
2029 
2030 		public override bool Nullable {
2031 			get { return false; }
2032 		}
2033 
2034 		internal override bool IsTextValueDependent {
2035 			get { return false; }
2036 		}
2037 
2038 		internal override bool IsContextDependent {
2039 			get { return false; }
2040 		}
2041 
2042 		public override RelaxngPatternType PatternType {
2043 			get { return RelaxngPatternType.Element; }
2044 		}
2045 
2046 		bool contentTypeCheckDone;
2047 		public override RdpContentType ContentType {
2048 			get {
2049 				if (!contentTypeCheckDone) {
2050 					contentTypeCheckDone = true;
2051 					RdpContentType ct = children.ContentType; // conformance required.
2052 				}
2053 				return RdpContentType.Complex;
2054 			}
2055 		}
2056 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)2057 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
2058 		{
2059 			if (elements != null) {
2060 				if (collectNameClass)
2061 					elements [NameClass] = NameClass;
2062 				else
2063 					AddNameLabel (elements, NameClass);
2064 			}
2065 		}
2066 
2067 
2068 		bool isExpanded;
2069 		short expanding; // FIXME: It is totally not required, but there is
2070 		// some bugs in simplification and without it it causes infinite loop.
ExpandRef(Hashtable defs)2071 		internal override RdpPattern ExpandRef (Hashtable defs)
2072 		{
2073 			if (!isExpanded) {
2074 				isExpanded = true;
2075 				if (expanding == 100)
2076 					throw new RelaxngException (String.Format ("Invalid recursion was found. Name is {0}", nameClass));
2077 				expanding++;
2078 				children = children.ExpandRef (defs);
2079 				expanding--;
2080 			}
2081 			return this;
2082 		}
2083 
ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)2084 		internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
2085 		{
2086 			if (visited.Contains (this))
2087 				return this;
2088 			visited.Add (this, this);
2089 
2090 			children = children.ReduceEmptyAndNotAllowed (ref result, visited);
2091 			return this;
2092 		}
2093 
TextOnlyDeriv()2094 		internal override RdpPattern TextOnlyDeriv ()
2095 		{
2096 			return RdpNotAllowed.Instance;
2097 		}
2098 
TextOnlyDeriv(MemoizationStore memo)2099 		internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
2100 		{
2101 			return RdpNotAllowed.Instance;
2102 		}
2103 
StartTagOpenDeriv(string name, string ns)2104 		public override RdpPattern StartTagOpenDeriv (string name, string ns)
2105 		{
2106 #if UseStatic
2107 			if (RdpUtil.Contains (this.nameClass, qname))
2108 				return RdpUtil.After (this.Children, RdpEmpty.Instance);
2109 			else
2110 				return RdpNotAllowed.Instance;
2111 #else
2112 			return nameClass.Contains (name, ns) ?
2113 				children.After (RdpEmpty.Instance) :
2114 				RdpNotAllowed.Instance;
2115 #endif
2116 		}
2117 
StartTagOpenDeriv(string name, string ns, MemoizationStore memo)2118 		internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
2119 		{
2120 			return nameClass.Contains (name, ns) ?
2121 				children.After (RdpEmpty.Instance) :
2122 				RdpNotAllowed.Instance;
2123 		}
2124 
MarkReachableDefs()2125 		internal override void MarkReachableDefs ()
2126 		{
2127 			children.MarkReachableDefs ();
2128 		}
2129 
2130 		bool constraintsChecked;
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)2131 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
2132 		{
2133 			if (constraintsChecked)
2134 				return;
2135 			constraintsChecked = true;
2136 			if (attribute || list || dataExcept)
2137 				throw new RelaxngException ("Not allowed element occurence was specified in the pattern.");
2138 			this.Children.CheckConstraints (false, false, false, oneOrMoreInterleave, false, false);
2139 		}
2140 
ContainsText()2141 		internal override bool ContainsText()
2142 		{
2143 			return false;
2144 		}
2145 	}
2146 
2147 	// After
2148 	public class RdpAfter : RdpAbstractBinary
2149 	{
RdpAfter(RdpPattern l, RdpPattern r)2150 		public RdpAfter (RdpPattern l, RdpPattern r) : base (l, r)
2151 		{
2152 		}
2153 
2154 		public override bool Nullable {
2155 			get { return false; }
2156 		}
2157 
2158 		internal override bool IsTextValueDependent {
2159 			get { return LValue.IsTextValueDependent; }
2160 		}
2161 
2162 		internal override bool IsContextDependent {
2163 			get { return LValue.IsContextDependent; }
2164 		}
2165 
GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)2166 		public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
2167 		{
2168 			LValue.GetLabels (elements, attributes, collectNameClass);
2169 		}
2170 
TextDeriv(string s, XmlReader reader)2171 		public override RdpPattern TextDeriv (string s, XmlReader reader)
2172 		{
2173 			return LValue.TextDeriv (s, reader).After (RValue);
2174 		}
2175 
TextDeriv(string s, XmlReader reader, MemoizationStore memo)2176 		internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
2177 		{
2178 			return memo.TextDeriv (LValue, s, reader).After (RValue);
2179 		}
2180 
EmptyTextDeriv(MemoizationStore memo)2181 		internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
2182 		{
2183 			return memo.EmptyTextDeriv (LValue).After (RValue);
2184 		}
2185 
TextOnlyDeriv()2186 		internal override RdpPattern TextOnlyDeriv ()
2187 		{
2188 			return LValue.TextOnlyDeriv ().After (RValue);
2189 		}
2190 
TextOnlyDeriv(MemoizationStore memo)2191 		internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
2192 		{
2193 			return memo.TextOnlyDeriv (LValue).After (RValue);
2194 		}
2195 
MixedTextDeriv()2196 		internal override RdpPattern MixedTextDeriv ()
2197 		{
2198 			return LValue.MixedTextDeriv ().After (RValue);
2199 		}
2200 
MixedTextDeriv(MemoizationStore memo)2201 		internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
2202 		{
2203 			return memo.MixedTextDeriv (LValue).After (RValue);
2204 		}
2205 
2206 		// startTagOpenDeriv (After p1 p2) qn =
2207 		//   applyAfter (flip after p2) (startTagOpenDeriv p1 qn)
StartTagOpenDeriv(string name, string ns)2208 		public override RdpPattern StartTagOpenDeriv (string name, string ns)
2209 		{
2210 			RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
2211 			RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2212 			return handled.ApplyAfter (new RdpApplyAfterHandler (
2213 				f.Apply));
2214 		}
2215 
StartTagOpenDeriv(string name, string ns, MemoizationStore memo)2216 		internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
2217 		{
2218 			RdpPattern handled = memo.StartTagOpenDeriv (LValue, name, ns);
2219 			RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2220 			return handled.ApplyAfter (new RdpApplyAfterHandler (
2221 				f.Apply));
2222 		}
2223 
ApplyAfter(RdpApplyAfterHandler handler)2224 		public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
2225 		{
2226 			return LValue.After (handler (RValue));
2227 		}
2228 
2229 		// attDeriv cx (After p1 p2) att =
2230 		//  after (attDeriv cx p1 att) p2
AttDeriv(string name, string ns, string value, XmlReader reader)2231 		public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
2232 		{
2233 			return LValue.AttDeriv (name, ns, value, reader).After (RValue);
2234 		}
2235 
StartAttDeriv(string name, string ns)2236 		public override RdpPattern StartAttDeriv (string name, string ns)
2237 		{
2238 			RdpPattern handled = LValue.StartAttDeriv (name, ns);
2239 			RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2240 			return handled.ApplyAfter (new RdpApplyAfterHandler (
2241 				f.Apply));
2242 		}
2243 
StartAttDeriv(string name, string ns, MemoizationStore memo)2244 		internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
2245 		{
2246 			RdpPattern handled = memo.StartAttDeriv (LValue, name, ns);
2247 			RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2248 			return handled.ApplyAfter (new RdpApplyAfterHandler (
2249 				f.Apply));
2250 		}
2251 
EndAttDeriv()2252 		public override RdpPattern EndAttDeriv ()
2253 		{
2254 			return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
2255 		}
2256 
StartTagCloseDeriv()2257 		public override RdpPattern StartTagCloseDeriv ()
2258 		{
2259 			return LValue.StartTagCloseDeriv ().After (RValue);
2260 		}
2261 
StartTagCloseDeriv(MemoizationStore memo)2262 		internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
2263 		{
2264 			return memo.StartTagCloseDeriv (LValue).After (RValue);
2265 		}
2266 
EndTagDeriv()2267 		public override RdpPattern EndTagDeriv ()
2268 		{
2269 			return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
2270 		}
2271 
2272 		public override RelaxngPatternType PatternType {
2273 			get { return RelaxngPatternType.After; }
2274 		}
2275 
MarkReachableDefs()2276 		internal override void MarkReachableDefs ()
2277 		{
2278 			throw new InvalidOperationException ();
2279 		}
2280 
CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)2281 		internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
2282 		{
2283 			throw new InvalidOperationException ();
2284 		}
2285 
ContainsText()2286 		internal override bool ContainsText ()
2287 		{
2288 			throw new InvalidOperationException ();
2289 		}
2290 	}
2291 }
2292 
2293