1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using System . IO ;
4
+ using System . Linq ;
5
+ using HotChocolate . Language ;
6
+ using HotChocolate . Language . Utilities ;
7
+
8
+ namespace HotChocolate . Transport . Http ;
9
+
10
+ /// <summary>
11
+ /// This file literal is used in order to allow for file references in <see cref="ObjectValueNode"/>.
12
+ /// </summary>
13
+ public sealed class FileReferenceNode
14
+ : IValueNode < FileReference >
15
+ , IValueNode < string >
16
+ , IEquatable < FileReferenceNode >
17
+ {
18
+ /// <summary>
19
+ /// Creates a new instance of <see cref="FileReferenceNode" />
20
+ /// </summary>
21
+ /// <param name="stream">
22
+ /// The file stream.
23
+ /// </param>
24
+ /// <param name="fileName">
25
+ /// The file name.
26
+ /// </param>
27
+ public FileReferenceNode ( Stream stream , string fileName )
28
+ : this ( new FileReference ( ( ) => stream , fileName ) ) { }
29
+
30
+ /// <summary>
31
+ /// Creates a new instance of <see cref="FileReferenceNode" />
32
+ /// </summary>
33
+ /// <param name="openRead">
34
+ /// The stream factory.
35
+ /// </param>
36
+ /// <param name="fileName">
37
+ /// The file name.
38
+ /// </param>
39
+ public FileReferenceNode ( Func < Stream > openRead , string fileName )
40
+ : this ( new FileReference ( openRead , fileName ) ) { }
41
+
42
+ /// <summary>
43
+ /// Creates a new instance of <see cref="FileReferenceNode" />
44
+ /// </summary>
45
+ /// <param name="value">
46
+ /// The file Reference.
47
+ /// </param>
48
+ public FileReferenceNode ( FileReference value )
49
+ {
50
+ Value = value ?? throw new ArgumentNullException ( nameof ( value ) ) ;
51
+ }
52
+
53
+ /// <summary>
54
+ /// Returns the <see cref="SyntaxKind"/> of the node.
55
+ /// </summary>
56
+ public SyntaxKind Kind => SyntaxKind . StringValue ;
57
+
58
+ /// <summary>
59
+ /// Gets a <see cref="Location"/> of this node in the parsed source text
60
+ /// if available the parser provided this information.
61
+ /// </summary>
62
+ public Location ? Location => null ;
63
+
64
+ /// <summary>
65
+ /// Gets the actual file reference.
66
+ /// </summary>
67
+ public FileReference Value { get ; }
68
+
69
+ object ? IValueNode . Value => Value ;
70
+
71
+ string IValueNode < string > . Value => Value . FileName ;
72
+
73
+ /// <summary>
74
+ /// Gets the children of this node.
75
+ /// </summary>
76
+ /// <returns>
77
+ /// Returns the children of this node..
78
+ /// </returns>
79
+ public IEnumerable < ISyntaxNode > GetNodes ( )
80
+ => Enumerable . Empty < ISyntaxNode > ( ) ;
81
+
82
+ /// <summary>
83
+ /// Determines whether the specified <see cref="IValueNode"/> is equal
84
+ /// to the current <see cref="FileReferenceNode"/>.
85
+ /// </summary>
86
+ /// <param name="other">
87
+ /// The <see cref="IValueNode"/> to compare with the current
88
+ /// <see cref="FileReferenceNode"/>.
89
+ /// </param>
90
+ /// <returns>
91
+ /// <c>true</c> if the specified <see cref="IValueNode"/> is equal
92
+ /// to the current <see cref="FileReferenceNode"/>;
93
+ /// otherwise, <c>false</c>.
94
+ /// </returns>
95
+ public bool Equals ( FileReferenceNode ? other )
96
+ {
97
+ if ( ReferenceEquals ( null , other ) )
98
+ {
99
+ return false ;
100
+ }
101
+
102
+ if ( ReferenceEquals ( this , other ) ||
103
+ ReferenceEquals ( Value , other . Value ) )
104
+ {
105
+ return true ;
106
+ }
107
+
108
+ return false ;
109
+ }
110
+
111
+ /// <summary>
112
+ /// Determines whether the specified <see cref="IValueNode"/> is equal
113
+ /// to the current <see cref="FileReferenceNode"/>.
114
+ /// </summary>
115
+ /// <param name="other">
116
+ /// The <see cref="IValueNode"/> to compare with the current
117
+ /// <see cref="FileReferenceNode"/>.
118
+ /// </param>
119
+ /// <returns>
120
+ /// <c>true</c> if the specified <see cref="IValueNode"/> is equal
121
+ /// to the current <see cref="FileReferenceNode"/>;
122
+ /// otherwise, <c>false</c>.
123
+ /// </returns>
124
+ public bool Equals ( IValueNode ? other )
125
+ {
126
+ if ( ReferenceEquals ( null , other ) )
127
+ {
128
+ return false ;
129
+ }
130
+
131
+ if ( ReferenceEquals ( this , other ) )
132
+ {
133
+ return true ;
134
+ }
135
+
136
+ if ( other is FileReferenceNode file )
137
+ {
138
+ return Equals ( file ) ;
139
+ }
140
+
141
+ return false ;
142
+ }
143
+
144
+ /// <summary>
145
+ /// Determines whether the specified <see cref="object"/> is equal to
146
+ /// the current <see cref="FileReferenceNode"/>.
147
+ /// </summary>
148
+ /// <param name="obj">
149
+ /// The <see cref="object"/> to compare with the current
150
+ /// <see cref="FileReferenceNode"/>.
151
+ /// </param>
152
+ /// <returns>
153
+ /// <c>true</c> if the specified <see cref="object"/> is equal to the
154
+ /// current <see cref="FileReferenceNode"/>; otherwise, <c>false</c>.
155
+ /// </returns>
156
+ public override bool Equals ( object ? obj )
157
+ {
158
+ if ( ReferenceEquals ( null , obj ) )
159
+ {
160
+ return false ;
161
+ }
162
+
163
+ if ( ReferenceEquals ( obj , this ) )
164
+ {
165
+ return true ;
166
+ }
167
+
168
+ return Equals ( obj as FileReferenceNode ) ;
169
+ }
170
+
171
+ /// <summary>
172
+ /// Serves as a hash function for a <see cref="FileReferenceNode"/>
173
+ /// object.
174
+ /// </summary>
175
+ /// <returns>
176
+ /// A hash code for this instance that is suitable for use in
177
+ /// hashing algorithms and data structures such as a hash table.
178
+ /// </returns>
179
+ public override int GetHashCode ( )
180
+ {
181
+ unchecked
182
+ {
183
+ return ( Kind . GetHashCode ( ) * 397 ) ^ ( Value . GetHashCode ( ) * 97 ) ;
184
+ }
185
+ }
186
+
187
+ /// <summary>
188
+ /// Returns the GraphQL syntax representation of this <see cref="ISyntaxNode"/>.
189
+ /// </summary>
190
+ /// <returns>
191
+ /// Returns the GraphQL syntax representation of this <see cref="ISyntaxNode"/>.
192
+ /// </returns>
193
+ public override string ToString ( )
194
+ => ToString ( true ) ;
195
+
196
+ /// <summary>
197
+ /// Returns the GraphQL syntax representation of this <see cref="ISyntaxNode"/>.
198
+ /// </summary>
199
+ /// <param name="indented">
200
+ /// A value that indicates whether the GraphQL output should be formatted,
201
+ /// which includes indenting nested GraphQL tokens, adding
202
+ /// new lines, and adding white space between property names and values.
203
+ /// </param>
204
+ /// <returns>
205
+ /// Returns the GraphQL syntax representation of this <see cref="ISyntaxNode"/>.
206
+ /// </returns>
207
+ public string ToString ( bool indented )
208
+ => SyntaxPrinter . Print ( this , indented ) ;
209
+ }
0 commit comments