1
+ using System ;
2
+ using System . IO ;
3
+ using System . Text ;
4
+ using Microsoft . CodeAnalysis ;
5
+ using Microsoft . CodeAnalysis . CSharp ;
6
+ using Microsoft . CodeAnalysis . Text ;
7
+
8
+ namespace GraphQlClientGenerator
9
+ {
10
+ [ Generator ]
11
+ public class GraphQlSourceGenerator : ISourceGenerator
12
+ {
13
+ private static readonly DiagnosticDescriptor DescriptorError =
14
+ new DiagnosticDescriptor (
15
+ "GRAPHQLGEN1000" ,
16
+ "GraphQlClientGenerator error" ,
17
+ "GraphQlClientGenerator error: {0}" ,
18
+ "GraphQlClientGenerator" ,
19
+ DiagnosticSeverity . Error ,
20
+ true ) ;
21
+
22
+ public void Initialize ( GeneratorInitializationContext context )
23
+ {
24
+ }
25
+
26
+ public void Execute ( GeneratorExecutionContext context )
27
+ {
28
+ var compilation = context . Compilation as CSharpCompilation ;
29
+ if ( compilation == null )
30
+ {
31
+ context . ReportDiagnostic (
32
+ Diagnostic . Create (
33
+ DescriptorError ,
34
+ Location . None ,
35
+ DiagnosticSeverity . Error ,
36
+ "incompatible language: " + context . Compilation . Language ) ) ;
37
+
38
+ return ;
39
+ }
40
+
41
+ try
42
+ {
43
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_ServiceUrl" , out var serviceUrl ) ;
44
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_SchemaFileName" , out var schemaFileName ) ;
45
+ var isServiceUrlMissing = String . IsNullOrWhiteSpace ( serviceUrl ) ;
46
+ if ( isServiceUrlMissing && String . IsNullOrWhiteSpace ( schemaFileName ) )
47
+ {
48
+ context . ReportDiagnostic (
49
+ Diagnostic . Create (
50
+ DescriptorError ,
51
+ Location . None ,
52
+ DiagnosticSeverity . Error ,
53
+ "Either \" GraphQlClientGenerator_ServiceUrl\" or \" GraphQlClientGenerator_SchemaFileName\" parameter must be specified. " ) ) ;
54
+
55
+ return ;
56
+ }
57
+
58
+ if ( ! isServiceUrlMissing && ! String . IsNullOrWhiteSpace ( schemaFileName ) )
59
+ {
60
+ context . ReportDiagnostic (
61
+ Diagnostic . Create (
62
+ DescriptorError ,
63
+ Location . None ,
64
+ DiagnosticSeverity . Error ,
65
+ "\" GraphQlClientGenerator_ServiceUrl\" and \" GraphQlClientGenerator_SchemaFileName\" parameters are mutually exclusive. " ) ) ;
66
+
67
+ return ;
68
+ }
69
+
70
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_Namespace" , out var @namespace ) ;
71
+ if ( String . IsNullOrWhiteSpace ( @namespace ) )
72
+ {
73
+ context . ReportDiagnostic (
74
+ Diagnostic . Create (
75
+ DescriptorError ,
76
+ Location . None ,
77
+ DiagnosticSeverity . Error ,
78
+ "\" GraphQlClientGenerator_Namespace\" invalid" ) ) ;
79
+
80
+ return ;
81
+ }
82
+
83
+ var configuration = new GraphQlGeneratorConfiguration { TreatUnknownObjectAsScalar = true } ;
84
+
85
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_ClassPrefix" , out var classPrefix ) ;
86
+ configuration . ClassPrefix = classPrefix ;
87
+
88
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_ClassSuffix" , out var classSuffix ) ;
89
+ configuration . ClassSuffix = classSuffix ;
90
+
91
+ if ( compilation . LanguageVersion >= LanguageVersion . CSharp6 )
92
+ configuration . CSharpVersion = compilation . Options . NullableContextOptions == NullableContextOptions . Disable ? CSharpVersion . Newest : CSharpVersion . NewestWithNullableReferences ;
93
+
94
+ var currentParameterName = "GeneratePartialClasses" ;
95
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_" + currentParameterName , out var generatePartialClassesRaw ) ;
96
+ configuration . GeneratePartialClasses = ! String . IsNullOrWhiteSpace ( generatePartialClassesRaw ) && Convert . ToBoolean ( generatePartialClassesRaw ) ;
97
+
98
+ currentParameterName = "IncludeDeprecatedFields" ;
99
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_" + currentParameterName , out var includeDeprecatedFieldsRaw ) ;
100
+ configuration . IncludeDeprecatedFields = ! String . IsNullOrWhiteSpace ( includeDeprecatedFieldsRaw ) && Convert . ToBoolean ( includeDeprecatedFieldsRaw ) ;
101
+
102
+ currentParameterName = "CommentGeneration" ;
103
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_" + currentParameterName , out var commentGenerationRaw ) ;
104
+ configuration . CommentGeneration =
105
+ String . IsNullOrWhiteSpace ( commentGenerationRaw )
106
+ ? CommentGenerationOption . CodeSummary
107
+ : ( CommentGenerationOption ) Enum . Parse ( typeof ( CommentGenerationOption ) , commentGenerationRaw , true ) ;
108
+
109
+ currentParameterName = "FloatTypeMapping" ;
110
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_" + currentParameterName , out var floatTypeMappingRaw ) ;
111
+ configuration . FloatTypeMapping = String . IsNullOrWhiteSpace ( floatTypeMappingRaw ) ? FloatTypeMapping . Decimal : ( FloatTypeMapping ) Enum . Parse ( typeof ( FloatTypeMapping ) , floatTypeMappingRaw , true ) ;
112
+
113
+ currentParameterName = "BooleanTypeMapping" ;
114
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_" + currentParameterName , out var booleanTypeMappingRaw ) ;
115
+ configuration . BooleanTypeMapping = String . IsNullOrWhiteSpace ( booleanTypeMappingRaw ) ? BooleanTypeMapping . Boolean : ( BooleanTypeMapping ) Enum . Parse ( typeof ( BooleanTypeMapping ) , booleanTypeMappingRaw , true ) ;
116
+
117
+ currentParameterName = "IdTypeMapping" ;
118
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_" + currentParameterName , out var idTypeMappingRaw ) ;
119
+ configuration . IdTypeMapping = String . IsNullOrWhiteSpace ( idTypeMappingRaw ) ? IdTypeMapping . Guid : ( IdTypeMapping ) Enum . Parse ( typeof ( IdTypeMapping ) , idTypeMappingRaw , true ) ;
120
+
121
+ currentParameterName = "JsonPropertyGeneration" ;
122
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_" + currentParameterName , out var jsonPropertyGenerationRaw ) ;
123
+ configuration . JsonPropertyGeneration =
124
+ String . IsNullOrWhiteSpace ( jsonPropertyGenerationRaw )
125
+ ? JsonPropertyGenerationOption . CaseInsensitive
126
+ : ( JsonPropertyGenerationOption ) Enum . Parse ( typeof ( JsonPropertyGenerationOption ) , jsonPropertyGenerationRaw , true ) ;
127
+
128
+ currentParameterName = "CustomClassMapping" ;
129
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_" + currentParameterName , out var customClassMappingRaw ) ;
130
+ if ( ! KeyValueParameterParser . TryGetCustomClassMapping (
131
+ customClassMappingRaw ? . Split ( new [ ] { '|' , ';' , ' ' } , StringSplitOptions . RemoveEmptyEntries ) ,
132
+ out var customMapping ,
133
+ out var customMappingParsingErrorMessage ) )
134
+ {
135
+ context . ReportDiagnostic ( Diagnostic . Create ( DescriptorError , Location . None , DiagnosticSeverity . Error , customMappingParsingErrorMessage ) ) ;
136
+ return ;
137
+ }
138
+
139
+ foreach ( var kvp in customMapping )
140
+ configuration . CustomClassNameMapping . Add ( kvp ) ;
141
+
142
+ currentParameterName = "Headers" ;
143
+ context . AnalyzerConfigOptions . GlobalOptions . TryGetValue ( "build_property.GraphQlClientGenerator_" + currentParameterName , out var headersRaw ) ;
144
+ if ( ! KeyValueParameterParser . TryGetCustomHeaders (
145
+ headersRaw ? . Split ( new [ ] { '|' } , StringSplitOptions . RemoveEmptyEntries ) ,
146
+ out var headers ,
147
+ out var headerParsingErrorMessage ) )
148
+ {
149
+ context . ReportDiagnostic ( Diagnostic . Create ( DescriptorError , Location . None , DiagnosticSeverity . Error , headerParsingErrorMessage ) ) ;
150
+ return ;
151
+ }
152
+
153
+ var schema = GraphQlGenerator . RetrieveSchema ( serviceUrl , headers ) . GetAwaiter ( ) . GetResult ( ) ;
154
+ var generator = new GraphQlGenerator ( configuration ) ;
155
+ var builder = new StringBuilder ( ) ;
156
+ using ( var writer = new StringWriter ( builder ) )
157
+ generator . WriteFullClientCSharpFile ( schema , @namespace , writer ) ;
158
+
159
+ context . AddSource ( "GraphQlClient.cs" , SourceText . From ( builder . ToString ( ) , Encoding . UTF8 ) ) ;
160
+ }
161
+ catch ( Exception exception )
162
+ {
163
+ context . ReportDiagnostic ( Diagnostic . Create ( DescriptorError , Location . None , DiagnosticSeverity . Error , exception . Message ) ) ;
164
+ }
165
+ }
166
+ }
167
+ }
0 commit comments