| /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. |
| * Use of this file is governed by the BSD 3-clause license that |
| * can be found in the LICENSE.txt file in the project root. |
| */ |
| using System; |
| using Antlr4.Runtime; |
| using Antlr4.Runtime.Misc; |
| using Antlr4.Runtime.Sharpen; |
| |
| namespace Antlr4.Runtime |
| { |
| [System.Serializable] |
| public class CommonToken : IWritableToken |
| { |
| private const long serialVersionUID = -6708843461296520577L; |
| |
| /// <summary> |
| /// An empty |
| /// <see cref="Tuple{T1, T2}"/> |
| /// which is used as the default value of |
| /// <see cref="source"/> |
| /// for tokens that do not have a source. |
| /// </summary> |
| protected internal static readonly Tuple<ITokenSource, ICharStream> EmptySource = Tuple.Create<ITokenSource, ICharStream>(null, null); |
| |
| /// <summary> |
| /// This is the backing field for the <see cref="Type"/> property. |
| /// </summary> |
| private int _type; |
| |
| /// <summary> |
| /// This is the backing field for the <see cref="Line"/> property. |
| /// </summary> |
| private int _line; |
| |
| /// <summary> |
| /// This is the backing field for the <see cref="Column"/> property. |
| /// </summary> |
| protected internal int charPositionInLine = -1; |
| |
| /// <summary> |
| /// This is the backing field for the <see cref="Channel"/> property. |
| /// </summary> |
| private int _channel = TokenConstants.DefaultChannel; |
| |
| /// <summary> |
| /// This is the backing field for |
| /// <see cref="TokenSource()"/> |
| /// and |
| /// <see cref="InputStream()"/> |
| /// . |
| /// <p> |
| /// These properties share a field to reduce the memory footprint of |
| /// <see cref="CommonToken"/> |
| /// . Tokens created by a |
| /// <see cref="CommonTokenFactory"/> |
| /// from |
| /// the same source and input stream share a reference to the same |
| /// <see cref="Tuple{T1, T2}"/> |
| /// containing these values.</p> |
| /// </summary> |
| [NotNull] |
| protected internal Tuple<ITokenSource, ICharStream> source; |
| |
| /// <summary> |
| /// This is the backing field for the <see cref="Text"/> property. |
| /// </summary> |
| /// <seealso cref="Text"/> |
| private string _text; |
| |
| /// <summary> |
| /// This is the backing field for the <see cref="TokenIndex"/> property. |
| /// </summary> |
| protected internal int index = -1; |
| |
| /// <summary> |
| /// This is the backing field for the <see cref="StartIndex"/> property. |
| /// </summary> |
| protected internal int start; |
| |
| /// <summary> |
| /// This is the backing field for the <see cref="StopIndex"/> property. |
| /// </summary> |
| protected internal int stop; |
| |
| /// <summary> |
| /// Constructs a new |
| /// <see cref="CommonToken"/> |
| /// with the specified token type. |
| /// </summary> |
| /// <param name="type">The token type.</param> |
| public CommonToken(int type) |
| { |
| // set to invalid position |
| this._type = type; |
| this.source = EmptySource; |
| } |
| |
| public CommonToken(Tuple<ITokenSource, ICharStream> source, int type, int channel, int start, int stop) |
| { |
| this.source = source; |
| this._type = type; |
| this._channel = channel; |
| this.start = start; |
| this.stop = stop; |
| if (source.Item1 != null) |
| { |
| this._line = source.Item1.Line; |
| this.charPositionInLine = source.Item1.Column; |
| } |
| } |
| |
| /// <summary> |
| /// Constructs a new |
| /// <see cref="CommonToken"/> |
| /// with the specified token type and |
| /// text. |
| /// </summary> |
| /// <param name="type">The token type.</param> |
| /// <param name="text">The text of the token.</param> |
| public CommonToken(int type, string text) |
| { |
| this._type = type; |
| this._channel = TokenConstants.DefaultChannel; |
| this._text = text; |
| this.source = EmptySource; |
| } |
| |
| /// <summary> |
| /// Constructs a new |
| /// <see cref="CommonToken"/> |
| /// as a copy of another |
| /// <see cref="IToken"/> |
| /// . |
| /// <p> |
| /// If |
| /// <paramref name="oldToken"/> |
| /// is also a |
| /// <see cref="CommonToken"/> |
| /// instance, the newly |
| /// constructed token will share a reference to the |
| /// <see cref="Text()"/> |
| /// field and |
| /// the |
| /// <see cref="Tuple{T1, T2}"/> |
| /// stored in |
| /// <see cref="source"/> |
| /// . Otherwise, |
| /// <see cref="Text()"/> |
| /// will |
| /// be assigned the result of calling |
| /// <see cref="Text()"/> |
| /// , and |
| /// <see cref="source"/> |
| /// will be constructed from the result of |
| /// <see cref="IToken.TokenSource()"/> |
| /// and |
| /// <see cref="IToken.InputStream()"/> |
| /// .</p> |
| /// </summary> |
| /// <param name="oldToken">The token to copy.</param> |
| public CommonToken(IToken oldToken) |
| { |
| _type = oldToken.Type; |
| _line = oldToken.Line; |
| index = oldToken.TokenIndex; |
| charPositionInLine = oldToken.Column; |
| _channel = oldToken.Channel; |
| start = oldToken.StartIndex; |
| stop = oldToken.StopIndex; |
| if (oldToken is Antlr4.Runtime.CommonToken) |
| { |
| _text = ((Antlr4.Runtime.CommonToken)oldToken)._text; |
| source = ((Antlr4.Runtime.CommonToken)oldToken).source; |
| } |
| else |
| { |
| _text = oldToken.Text; |
| source = Tuple.Create(oldToken.TokenSource, oldToken.InputStream); |
| } |
| } |
| |
| public virtual int Type |
| { |
| get |
| { |
| return _type; |
| } |
| set |
| { |
| this._type = value; |
| } |
| } |
| |
| public virtual int Line |
| { |
| get |
| { |
| return _line; |
| } |
| set |
| { |
| this._line = value; |
| } |
| } |
| |
| /// <summary>Explicitly set the text for this token.</summary> |
| /// <remarks> |
| /// Explicitly set the text for this token. If {code text} is not |
| /// <see langword="null"/> |
| /// , then |
| /// <see cref="Text()"/> |
| /// will return this value rather than |
| /// extracting the text from the input. |
| /// </remarks> |
| /// <value> |
| /// The explicit text of the token, or |
| /// <see langword="null"/> |
| /// if the text |
| /// should be obtained from the input along with the start and stop indexes |
| /// of the token. |
| /// </value> |
| public virtual string Text |
| { |
| get |
| { |
| if (_text != null) |
| { |
| return _text; |
| } |
| ICharStream input = InputStream; |
| if (input == null) |
| { |
| return null; |
| } |
| int n = input.Size; |
| if (start < n && stop < n) |
| { |
| return input.GetText(Interval.Of(start, stop)); |
| } |
| else |
| { |
| return "<EOF>"; |
| } |
| } |
| set |
| { |
| this._text = value; |
| } |
| } |
| |
| public virtual int Column |
| { |
| get |
| { |
| return charPositionInLine; |
| } |
| set |
| { |
| int charPositionInLine = value; |
| this.charPositionInLine = charPositionInLine; |
| } |
| } |
| |
| public virtual int Channel |
| { |
| get |
| { |
| return _channel; |
| } |
| set |
| { |
| this._channel = value; |
| } |
| } |
| |
| public virtual int StartIndex |
| { |
| get |
| { |
| return start; |
| } |
| set |
| { |
| int start = value; |
| this.start = start; |
| } |
| } |
| |
| public virtual int StopIndex |
| { |
| get |
| { |
| return stop; |
| } |
| set |
| { |
| int stop = value; |
| this.stop = stop; |
| } |
| } |
| |
| public virtual int TokenIndex |
| { |
| get |
| { |
| return index; |
| } |
| set |
| { |
| int index = value; |
| this.index = index; |
| } |
| } |
| |
| public virtual ITokenSource TokenSource |
| { |
| get |
| { |
| return source.Item1; |
| } |
| } |
| |
| public virtual ICharStream InputStream |
| { |
| get |
| { |
| return source.Item2; |
| } |
| } |
| |
| public override string ToString() |
| { |
| string channelStr = string.Empty; |
| if (_channel > 0) |
| { |
| channelStr = ",channel=" + _channel; |
| } |
| string txt = Text; |
| if (txt != null) |
| { |
| txt = txt.Replace("\n", "\\n"); |
| txt = txt.Replace("\r", "\\r"); |
| txt = txt.Replace("\t", "\\t"); |
| } |
| else |
| { |
| txt = "<no text>"; |
| } |
| return "[@" + TokenIndex + "," + start + ":" + stop + "='" + txt + "',<" + _type + ">" + channelStr + "," + _line + ":" + Column + "]"; |
| } |
| } |
| } |