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 {
34    using NonSerialized = System.NonSerializedAttribute;
35    using Regex = System.Text.RegularExpressions.Regex;
36    using Serializable = System.SerializableAttribute;
37
38    [Serializable]
39    public class CommonToken : IToken {
40        int type;
41        int line;
42        int charPositionInLine = -1; // set to invalid position
43        int channel = TokenChannels.Default;
44        [NonSerialized]
45        ICharStream input;
46
47        /** <summary>
48         *  We need to be able to change the text once in a while.  If
49         *  this is non-null, then getText should return this.  Note that
50         *  start/stop are not affected by changing this.
51         *  </summary>
52          */
53        string text;
54
55        /** <summary>What token number is this from 0..n-1 tokens; &lt; 0 implies invalid index</summary> */
56        int index = -1;
57
58        /** <summary>The char position into the input buffer where this token starts</summary> */
59        int start;
60
61        /** <summary>The char position into the input buffer where this token stops</summary> */
62        int stop;
63
64        public CommonToken() {
65        }
66
67        public CommonToken(int type) {
68            this.type = type;
69        }
70
71        public CommonToken(ICharStream input, int type, int channel, int start, int stop) {
72            this.input = input;
73            this.type = type;
74            this.channel = channel;
75            this.start = start;
76            this.stop = stop;
77        }
78
79        public CommonToken(int type, string text) {
80            this.type = type;
81            this.channel = TokenChannels.Default;
82            this.text = text;
83        }
84
85        public CommonToken(IToken oldToken) {
86            text = oldToken.Text;
87            type = oldToken.Type;
88            line = oldToken.Line;
89            index = oldToken.TokenIndex;
90            charPositionInLine = oldToken.CharPositionInLine;
91            channel = oldToken.Channel;
92            input = oldToken.InputStream;
93            if (oldToken is CommonToken) {
94                start = ((CommonToken)oldToken).start;
95                stop = ((CommonToken)oldToken).stop;
96            }
97        }
98
99        #region IToken Members
100        public string Text {
101            get {
102                if (text != null)
103                    return text;
104                if (input == null)
105                    return null;
106
107                if (start < input.Count && stop < input.Count)
108                    text = input.Substring(start, stop - start + 1);
109                else
110                    text = "<EOF>";
111
112                return text;
113            }
114            set {
115                /** Override the text for this token.  getText() will return this text
116                 *  rather than pulling from the buffer.  Note that this does not mean
117                 *  that start/stop indexes are not valid.  It means that that input
118                 *  was converted to a new string in the token object.
119                 */
120                text = value;
121            }
122        }
123
124        public int Type {
125            get {
126                return type;
127            }
128            set {
129                type = value;
130            }
131        }
132
133        public int Line {
134            get {
135                return line;
136            }
137            set {
138                line = value;
139            }
140        }
141
142        public int CharPositionInLine {
143            get {
144                return charPositionInLine;
145            }
146            set {
147                charPositionInLine = value;
148            }
149        }
150
151        public int Channel {
152            get {
153                return channel;
154            }
155            set {
156                channel = value;
157            }
158        }
159
160        public int StartIndex {
161            get {
162                return start;
163            }
164            set {
165                start = value;
166            }
167        }
168
169        public int StopIndex {
170            get {
171                return stop;
172            }
173            set {
174                stop = value;
175            }
176        }
177
178        public int TokenIndex {
179            get {
180                return index;
181            }
182            set {
183                index = value;
184            }
185        }
186
187        public ICharStream InputStream {
188            get {
189                return input;
190            }
191            set {
192                input = value;
193            }
194        }
195
196        #endregion
197
198        public override string ToString() {
199            string channelStr = "";
200            if (channel > 0) {
201                channelStr = ",channel=" + channel;
202            }
203            string txt = Text;
204            if (txt != null) {
205                txt = Regex.Replace(txt, "\n", "\\\\n");
206                txt = Regex.Replace(txt, "\r", "\\\\r");
207                txt = Regex.Replace(txt, "\t", "\\\\t");
208            } else {
209                txt = "<no text>";
210            }
211            return "[@" + TokenIndex + "," + start + ":" + stop + "='" + txt + "',<" + type + ">" + channelStr + "," + line + ":" + CharPositionInLine + "]";
212        }
213
214        [System.Runtime.Serialization.OnSerializing]
215        internal void OnSerializing(System.Runtime.Serialization.StreamingContext context) {
216            if (text == null)
217                text = Text;
218        }
219    }
220}
221