/
OperationDocumentGenerator.cs
127 lines (113 loc) · 4.49 KB
/
OperationDocumentGenerator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using System;
using System.Security.Cryptography;
using System.Text;
using StrawberryShake.CodeGeneration.CSharp.Builders;
using StrawberryShake.CodeGeneration.Descriptors.Operations;
using StrawberryShake.CodeGeneration.Properties;
using StrawberryShake.Tools.Configuration;
using static StrawberryShake.CodeGeneration.Descriptors.NamingConventions;
namespace StrawberryShake.CodeGeneration.CSharp.Generators
{
public class OperationDocumentGenerator : ClassBaseGenerator<OperationDescriptor>
{
protected override void Generate(OperationDescriptor descriptor,
CSharpSyntaxGeneratorSettings settings,
CodeWriter writer,
out string fileName,
out string? path,
out string ns)
{
var documentName = CreateDocumentTypeName(descriptor.RuntimeType.Name);
fileName = documentName;
path = null;
ns = descriptor.RuntimeType.NamespaceWithoutGlobal;
string operationKind = descriptor switch
{
MutationOperationDescriptor => "Mutation",
QueryOperationDescriptor => "Query",
SubscriptionOperationDescriptor => "Subscription",
_ => throw new ArgumentOutOfRangeException(nameof(descriptor))
};
ClassBuilder classBuilder = ClassBuilder
.New()
.SetName(fileName)
.AddImplements(TypeNames.IDocument)
.SetComment(
XmlCommentBuilder
.New()
.SetSummary(
string.Format(
CodeGenerationResources.OperationServiceDescriptor_Description,
descriptor.Name))
.AddCode(descriptor.BodyString));
classBuilder
.AddConstructor()
.SetPrivate();
classBuilder
.AddProperty("Instance")
.SetStatic()
.SetType(documentName)
.SetValue($"new {documentName}()");
classBuilder
.AddProperty("Kind")
.SetType(TypeNames.OperationKind)
.AsLambda($"{TypeNames.OperationKind}.{operationKind}");
if (descriptor.Strategy == RequestStrategy.PersistedQuery)
{
classBuilder
.AddProperty("Body")
.SetType(TypeNames.IReadOnlySpan.WithGeneric(TypeNames.Byte))
.AsLambda($"new {TypeNames.Byte}[0]");
}
else
{
classBuilder
.AddProperty("Body")
.SetType(TypeNames.IReadOnlySpan.WithGeneric(TypeNames.Byte))
.AsLambda(GetByteArray(descriptor.Body));
}
classBuilder
.AddProperty("Hash")
.SetType(TypeNames.DocumentHash)
.SetValue(
$@"new {TypeNames.DocumentHash}(" +
$@"""{descriptor.HashAlgorithm}"", " +
$@"""{descriptor.HashValue}"")");
classBuilder
.AddMethod("ToString")
.SetPublic()
.SetOverride()
.SetReturnType(TypeNames.String)
.AddCode("#if NETCOREAPP3_1_OR_GREATER")
.AddCode(MethodCallBuilder
.New()
.SetReturn()
.SetMethodName(TypeNames.EncodingUtf8, nameof(Encoding.UTF8.GetString))
.AddArgument("Body"))
.AddCode("#else")
.AddCode(MethodCallBuilder
.New()
.SetReturn()
.SetMethodName(TypeNames.EncodingUtf8, nameof(Encoding.UTF8.GetString))
.AddArgument("Body.ToArray()"))
.AddCode("#endif");
classBuilder.Build(writer);
}
private static string GetByteArray(byte[] bytes)
{
var builder = new StringBuilder();
builder.Append($"new {TypeNames.Byte}[]{{ ");
for (var i = 0; i < bytes.Length; i++)
{
builder.Append("0x");
builder.Append(bytes[i].ToString("x2"));
if (i < bytes.Length - 1)
{
builder.Append(", ");
}
}
builder.Append(" }");
return builder.ToString();
}
}
}