1/*
2 * [The "BSD licence"]
3 * Copyright (c) 2005-2008 Terence Parr
4 * All rights reserved.
5 *
6 * Conversion to C#:
7 * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 *    derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33namespace Antlr.Runtime.Debug
34{
35
36    public class DebugTokenStream : ITokenStream
37    {
38        protected IDebugEventListener dbg;
39        public ITokenStream input;
40        protected bool initialStreamState = true;
41
42        /** <summary>Track the last mark() call result value for use in rewind().</summary> */
43        protected int lastMarker;
44
45        public DebugTokenStream( ITokenStream input, IDebugEventListener dbg )
46        {
47            this.input = input;
48            DebugListener = dbg;
49            // force TokenStream to get at least first valid token
50            // so we know if there are any hidden tokens first in the stream
51            input.LT( 1 );
52        }
53
54        #region Properties
55
56        public virtual int Index
57        {
58            get
59            {
60                return input.Index;
61            }
62        }
63
64        public virtual int Range
65        {
66            get
67            {
68                return input.Range;
69            }
70        }
71
72        public virtual IDebugEventListener DebugListener
73        {
74            get
75            {
76                return dbg;
77            }
78            set
79            {
80                dbg = value;
81            }
82        }
83
84        #endregion
85
86        public virtual void Consume()
87        {
88            if ( initialStreamState )
89            {
90                ConsumeInitialHiddenTokens();
91            }
92            int a = input.Index;
93            IToken t = input.LT( 1 );
94            input.Consume();
95            int b = input.Index;
96            dbg.ConsumeToken( t );
97            if ( b > a + 1 )
98            {
99                // then we consumed more than one token; must be off channel tokens
100                for ( int i = a + 1; i < b; i++ )
101                {
102                    dbg.ConsumeHiddenToken( input.Get( i ) );
103                }
104            }
105        }
106
107        /** <summary>Consume all initial off-channel tokens</summary> */
108        protected virtual void ConsumeInitialHiddenTokens()
109        {
110            int firstOnChannelTokenIndex = input.Index;
111            for ( int i = 0; i < firstOnChannelTokenIndex; i++ )
112            {
113                dbg.ConsumeHiddenToken( input.Get( i ) );
114            }
115            initialStreamState = false;
116        }
117
118        public virtual IToken LT( int i )
119        {
120            if ( initialStreamState )
121            {
122                ConsumeInitialHiddenTokens();
123            }
124            dbg.LT( i, input.LT( i ) );
125            return input.LT( i );
126        }
127
128        public virtual int LA( int i )
129        {
130            if ( initialStreamState )
131            {
132                ConsumeInitialHiddenTokens();
133            }
134            dbg.LT( i, input.LT( i ) );
135            return input.LA( i );
136        }
137
138        public virtual IToken Get( int i )
139        {
140            return input.Get( i );
141        }
142
143        public virtual int Mark()
144        {
145            lastMarker = input.Mark();
146            dbg.Mark( lastMarker );
147            return lastMarker;
148        }
149
150        public virtual void Rewind( int marker )
151        {
152            dbg.Rewind( marker );
153            input.Rewind( marker );
154        }
155
156        public virtual void Rewind()
157        {
158            dbg.Rewind();
159            input.Rewind( lastMarker );
160        }
161
162        public virtual void Release( int marker )
163        {
164        }
165
166        public virtual void Seek( int index )
167        {
168            // TODO: implement seek in dbg interface
169            // db.seek(index);
170            input.Seek( index );
171        }
172
173        public virtual int Count
174        {
175            get
176            {
177                return input.Count;
178            }
179        }
180
181        public virtual ITokenSource TokenSource
182        {
183            get
184            {
185                return input.TokenSource;
186            }
187        }
188
189        public virtual string SourceName
190        {
191            get
192            {
193                return TokenSource.SourceName;
194            }
195        }
196
197        public override string ToString()
198        {
199            return input.ToString();
200        }
201
202        public virtual string ToString( int start, int stop )
203        {
204            return input.ToString( start, stop );
205        }
206
207        public virtual string ToString( IToken start, IToken stop )
208        {
209            return input.ToString( start, stop );
210        }
211    }
212}
213