• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 // Protocol Buffers - Google's data interchange format
3 // Copyright 2008 Google Inc.  All rights reserved.
4 //
5 // Use of this source code is governed by a BSD-style
6 // license that can be found in the LICENSE file or at
7 // https://developers.google.com/open-source/licenses/bsd
8 #endregion
9 
10 using System;
11 
12 namespace Google.Protobuf
13 {
14     internal sealed class JsonToken : IEquatable<JsonToken>
15     {
16         internal static JsonToken Null { get; } = new JsonToken(TokenType.Null);
17         internal static JsonToken False { get; } = new JsonToken(TokenType.False);
18         internal static JsonToken True { get; } = new JsonToken(TokenType.True);
19         internal static JsonToken StartObject { get; } = new JsonToken(TokenType.StartObject);
20         internal static JsonToken EndObject { get; } = new JsonToken(TokenType.EndObject);
21         internal static JsonToken StartArray { get; } = new JsonToken(TokenType.StartArray);
22         internal static JsonToken EndArray { get; } = new JsonToken(TokenType.EndArray);
23         internal static JsonToken EndDocument { get; } = new JsonToken(TokenType.EndDocument);
24 
Name(string name)25         internal static JsonToken Name(string name)
26         {
27             return new JsonToken(TokenType.Name, stringValue: name);
28         }
29 
Value(string value)30         internal static JsonToken Value(string value)
31         {
32             return new JsonToken(TokenType.StringValue, stringValue: value);
33         }
34 
Value(double value)35         internal static JsonToken Value(double value)
36         {
37             return new JsonToken(TokenType.Number, numberValue: value);
38         }
39 
40         internal enum TokenType
41         {
42             Null,
43             False,
44             True,
45             StringValue,
46             Number,
47             Name,
48             StartObject,
49             EndObject,
50             StartArray,
51             EndArray,
52             EndDocument
53         }
54 
55         // A value is a string, number, array, object, null, true or false
56         // Arrays and objects have start/end
57         // A document consists of a value
58         // Objects are name/value sequences.
59 
60         private readonly TokenType type;
61         private readonly string stringValue;
62         private readonly double numberValue;
63 
64         internal TokenType Type => type;
65         internal string StringValue => stringValue;
66         internal double NumberValue => numberValue;
67 
JsonToken(TokenType type, string stringValue = null, double numberValue = 0)68         private JsonToken(TokenType type, string stringValue = null, double numberValue = 0)
69         {
70             this.type = type;
71             this.stringValue = stringValue;
72             this.numberValue = numberValue;
73         }
74 
75         public override bool Equals(object obj) => Equals(obj as JsonToken);
76 
GetHashCode()77         public override int GetHashCode()
78         {
79             unchecked
80             {
81                 int hash = 17;
82                 hash = hash * 31 + (int) type;
83                 hash = hash * 31 + stringValue == null ? 0 : stringValue.GetHashCode();
84                 hash = hash * 31 + numberValue.GetHashCode();
85                 return hash;
86             }
87         }
88 
ToString()89         public override string ToString()
90         {
91             return type switch
92             {
93                 TokenType.Null => "null",
94                 TokenType.True => "true",
95                 TokenType.False => "false",
96                 TokenType.Name => $"name ({stringValue})",
97                 TokenType.StringValue => $"value ({stringValue})",
98                 TokenType.Number => $"number ({numberValue})",
99                 TokenType.StartObject => "start-object",
100                 TokenType.EndObject => "end-object",
101                 TokenType.StartArray => "start-array",
102                 TokenType.EndArray => "end-array",
103                 TokenType.EndDocument => "end-document",
104                 _ => throw new InvalidOperationException($"Token is of unknown type {type}"),
105             };
106         }
107 
Equals(JsonToken other)108         public bool Equals(JsonToken other)
109         {
110             if (other is null)
111             {
112                 return false;
113             }
114             // Note use of other.numberValue.Equals rather than ==, so that NaN compares appropriately.
115             return other.type == type && other.stringValue == stringValue && other.numberValue.Equals(numberValue);
116         }
117     }
118 }
119