Skip to content

Commit 75a4e54

Browse files
committed
feat: best practice
1 parent 32dc010 commit 75a4e54

10 files changed

Lines changed: 164 additions & 202 deletions

File tree

cmd/protoc-gen-csharp-tableau-loader/hub.go

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,12 @@ func generateHub(gen *protogen.Plugin) {
2727
}
2828
g.P(staticHubContent4)
2929
for _, messager := range messagers {
30-
g.P(" Register<Tableau.", messager, ">();")
30+
g.P(" Register<", messager, ">();")
3131
}
3232
g.P(staticHubContent5)
3333
}
3434

35-
const staticHubContent1 = `using System;
36-
using System.Collections.Generic;
37-
using Google.Protobuf;
38-
using System.IO;
39-
35+
const staticHubContent1 = `
4036
namespace Tableau
4137
{
4238
public enum Format
@@ -49,6 +45,7 @@ namespace Tableau
4945
public class LoadOptions
5046
{
5147
public bool IgnoreUnknownFields { get; set; } = false;
48+
public Func<string, byte[]> ReadFunc { get; set; } = File.ReadAllBytes;
5249
}
5350
5451
public interface IMessagerName
@@ -63,7 +60,7 @@ namespace Tableau
6360
public TimeSpan Duration;
6461
}
6562
66-
protected Stats LoadStats = new Stats();
63+
protected Stats LoadStats = new();
6764
6865
public ref Stats GetStats() => ref LoadStats;
6966
@@ -73,26 +70,26 @@ namespace Tableau
7370
7471
public virtual bool ProcessAfterLoadAll(in Hub hub) => true;
7572
76-
internal bool LoadMessageByPath<T>(out T msg, string dir, Format fmt, in LoadOptions? options = null) where T : IMessage<T>, new()
73+
internal static bool LoadMessageByPath<T>(out T msg, string dir, Format fmt, in LoadOptions? options = null) where T : Google.Protobuf.IMessage<T>, new()
7774
{
7875
msg = new T();
7976
string name = msg.Descriptor.Name;
8077
string path = Path.Combine(dir, name + Format2Ext(fmt));
8178
try
8279
{
80+
var readFunc = options is null ? File.ReadAllBytes : options.ReadFunc;
81+
byte[] content = readFunc(path);
8382
switch (fmt)
8483
{
8584
case Format.JSON:
8685
{
87-
string content = File.ReadAllText(path);
88-
var parser = options is null ? JsonParser.Default : new JsonParser(JsonParser.Settings.Default.WithIgnoreUnknownFields(options.IgnoreUnknownFields));
89-
msg = parser.Parse<T>(content);
86+
var parser = options is null ? Google.Protobuf.JsonParser.Default : new Google.Protobuf.JsonParser(Google.Protobuf.JsonParser.Settings.Default.WithIgnoreUnknownFields(options.IgnoreUnknownFields));
87+
msg = parser.Parse<T>(System.Text.Encoding.UTF8.GetString(content));
9088
break;
9189
}
9290
case Format.Bin:
9391
{
94-
byte[] content = File.ReadAllBytes(path);
95-
var parser = new MessageParser<T>(() => new T());
92+
var parser = new Google.Protobuf.MessageParser<T>(() => new T());
9693
msg = parser.ParseFrom(content);
9794
break;
9895
}
@@ -107,14 +104,14 @@ namespace Tableau
107104
return true;
108105
}
109106
110-
internal string Format2Ext(Format fmt)
107+
internal static string Format2Ext(Format fmt)
111108
{
112-
switch (fmt)
109+
return fmt switch
113110
{
114-
case Format.JSON: return ".json";
115-
case Format.Bin: return ".bin";
116-
default: return ".unknown";
117-
}
111+
Format.JSON => ".json",
112+
Format.Bin => ".bin",
113+
_ => ".unknown",
114+
};
118115
}
119116
}
120117
@@ -126,7 +123,7 @@ namespace Tableau
126123
var staticHubContent2 = `
127124
public MessagerContainer(in Dictionary<string, Messager>? messagerMap = null)
128125
{
129-
MessagerMap = messagerMap ?? new Dictionary<string, Messager>();
126+
MessagerMap = messagerMap ?? [];
130127
LastLoadedTime = DateTime.Now;
131128
if (messagerMap != null)
132129
{`
@@ -142,12 +139,10 @@ var staticHubContent3 = ` }
142139
public Func<string, bool>? Filter { get; set; }
143140
}
144141
145-
public class Hub
142+
public class Hub(HubOptions? options = null)
146143
{
147-
private MessagerContainer MessagerContainer = new MessagerContainer();
148-
private readonly HubOptions Options;
149-
150-
public Hub(HubOptions? options = null) => Options = options ?? new HubOptions();
144+
private MessagerContainer MessagerContainer = new();
145+
private readonly HubOptions Options = options ?? new HubOptions();
151146
152147
public bool Load(string dir, Format fmt, in LoadOptions? options = null)
153148
{
@@ -197,7 +192,7 @@ const staticHubContent4 = `
197192
198193
public class Registry
199194
{
200-
internal static readonly Dictionary<string, Func<Messager>> Registrar = new Dictionary<string, Func<Messager>>();
195+
internal static readonly Dictionary<string, Func<Messager>> Registrar = [];
201196
202197
public static void Register<T>() where T : Messager, IMessagerName, new() => Registrar[T.Name()] = () => new T();
203198

cmd/protoc-gen-csharp-tableau-loader/index.go

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,25 @@ func genIndexTypeDef(gen *protogen.Plugin, g *protogen.GeneratedFile, descriptor
2626
keyType := fmt.Sprintf("%s_Index_%sKey", messagerName, index.Name())
2727

2828
// generate key struct
29-
g.P(helper.Indent(2), "public struct ", keyType)
30-
g.P(helper.Indent(2), "{")
31-
for _, field := range index.ColFields {
32-
g.P(helper.Indent(3), "public ", helper.ParseCsharpType(field.FD), " ", helper.ParseIndexFieldNameAsKeyStructFieldName(field.FD), ";")
33-
}
34-
g.P()
3529
var keyParams string
3630
for i, field := range index.ColFields {
3731
keyParams += helper.ParseCsharpType(field.FD) + " " + strcase.ToLowerCamel(helper.ParseIndexFieldNameAsKeyStructFieldName(field.FD))
3832
if i != len(index.ColFields)-1 {
3933
keyParams += ", "
4034
}
4135
}
42-
g.P(helper.Indent(3), "public ", keyType, "(", keyParams, ")")
43-
g.P(helper.Indent(3), "{")
36+
g.P(helper.Indent(2), "public struct ", keyType, "(", keyParams, ")")
37+
g.P(helper.Indent(2), "{")
4438
for _, field := range index.ColFields {
45-
g.P(helper.Indent(4), helper.ParseIndexFieldNameAsKeyStructFieldName(field.FD), " = ", strcase.ToLowerCamel(helper.ParseIndexFieldNameAsKeyStructFieldName(field.FD)), ";")
39+
g.P(helper.Indent(3), "public ", helper.ParseCsharpType(field.FD), " ", helper.ParseIndexFieldNameAsKeyStructFieldName(field.FD), " = ", strcase.ToLowerCamel(helper.ParseIndexFieldNameAsKeyStructFieldName(field.FD)), ";")
4640
}
47-
g.P(helper.Indent(3), "}")
4841
g.P(helper.Indent(2), "}")
4942
g.P()
5043
g.P(helper.Indent(2), "public class ", mapType, " : Dictionary<", keyType, ", List<", helper.ParseCsharpClassType(index.MD), ">> { }")
5144
}
5245
g.P()
5346
indexContainerName := "Index" + strcase.ToCamel(index.Name()) + "Map"
54-
g.P(helper.Indent(2), "private ", mapType, " ", indexContainerName, " = new ", mapType, "();")
47+
g.P(helper.Indent(2), "private readonly ", mapType, " ", indexContainerName, " = [];")
5548
g.P()
5649
}
5750
}
@@ -112,7 +105,7 @@ func genOneIndexLoader(gen *protogen.Plugin, g *protogen.GeneratedFile, depth in
112105
g.P(helper.Indent(depth+3), "{")
113106
g.P(helper.Indent(depth+4), "var key = ", itemName, ";")
114107
g.P(helper.Indent(depth+4), "var list = ", indexContainerName, ".TryGetValue(key, out var existingList) ?")
115-
g.P(helper.Indent(depth+4), "existingList : ", indexContainerName, "[key] = new List<", helper.ParseCsharpClassType(index.MD), ">();")
108+
g.P(helper.Indent(depth+4), "existingList : ", indexContainerName, "[key] = [];")
116109
g.P(helper.Indent(depth+4), "list.Add(", parentDataName, ");")
117110
g.P(helper.Indent(depth+3), "}")
118111
} else {
@@ -129,7 +122,7 @@ func genOneIndexLoader(gen *protogen.Plugin, g *protogen.GeneratedFile, depth in
129122
}
130123
g.P(helper.Indent(depth+3), "var key = ", key, ";")
131124
g.P(helper.Indent(depth+3), "var list = ", indexContainerName, ".TryGetValue(key, out var existingList) ?")
132-
g.P(helper.Indent(depth+3), "existingList : ", indexContainerName, "[key] = new List<", helper.ParseCsharpClassType(index.MD), ">();")
125+
g.P(helper.Indent(depth+3), "existingList : ", indexContainerName, "[key] = [];")
133126
g.P(helper.Indent(depth+3), "list.Add(", parentDataName, ");")
134127
}
135128
} else {
@@ -198,7 +191,7 @@ func generateOneMulticolumnIndex(gen *protogen.Plugin, g *protogen.GeneratedFile
198191
indexContainerName := "Index" + strcase.ToCamel(index.Name()) + "Map"
199192
g.P(helper.Indent(depth+3), "var key = new ", keyType, "(", keyParams, ");")
200193
g.P(helper.Indent(depth+3), "var list = ", indexContainerName, ".TryGetValue(key, out var existingList) ?")
201-
g.P(helper.Indent(depth+3), "existingList : ", indexContainerName, "[key] = new List<", helper.ParseCsharpClassType(index.MD), ">();")
194+
g.P(helper.Indent(depth+3), "existingList : ", indexContainerName, "[key] = [];")
202195
g.P(helper.Indent(depth+3), "list.Add(", parentDataName, ");")
203196
return keys
204197
}

cmd/protoc-gen-csharp-tableau-loader/messager.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protog
6666
if options.NeedGenIndex(message.Desc, options.LangCS) {
6767
genIndexTypeDef(gen, g, indexDescriptor, messagerName)
6868
}
69-
g.P(helper.Indent(2), "private Protoconf.", messagerName, " Data_ = new Protoconf.", messagerName, "();")
69+
g.P(helper.Indent(2), "private Protoconf.", messagerName, " Data_ = new();")
7070
g.P()
7171
g.P(helper.Indent(2), "public static string Name() => Protoconf.", messagerName, ".Descriptor.Name;")
7272
g.P()
@@ -75,7 +75,7 @@ func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protog
7575
g.P(helper.Indent(3), "var start = DateTime.Now;")
7676
g.P(helper.Indent(3), "bool loaded = LoadMessageByPath<Protoconf.", messagerName, ">(out var msg, dir, fmt, options);")
7777
g.P(helper.Indent(3), "Data_ = msg;")
78-
g.P(helper.Indent(3), "bool ok = loaded ? ProcessAfterLoad() : false;")
78+
g.P(helper.Indent(3), "bool ok = loaded && ProcessAfterLoad();")
7979
g.P(helper.Indent(3), "LoadStats.Duration = DateTime.Now - start;")
8080
g.P(helper.Indent(3), "return ok;")
8181
g.P(helper.Indent(2), "}")
@@ -151,11 +151,7 @@ func parseMapValueType(fd protoreflect.FieldDescriptor) string {
151151
return helper.ParseCsharpType(fd.MapValue())
152152
}
153153

154-
const staticMessagerContent1 = `using System;
155-
using System.Collections.Generic;
156-
using Google.Protobuf;
157-
using Google.Protobuf.Collections;
158-
154+
const staticMessagerContent1 = `
159155
namespace Tableau
160156
{`
161157

cmd/protoc-gen-csharp-tableau-loader/ordered_map.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"github.com/iancoleman/strcase"
88
"github.com/tableauio/loader/cmd/protoc-gen-csharp-tableau-loader/helper"
99
"github.com/tableauio/loader/internal/options"
10+
"golang.org/x/text/cases"
11+
"golang.org/x/text/language"
1012
"google.golang.org/protobuf/compiler/protogen"
1113
"google.golang.org/protobuf/reflect/protoreflect"
1214
)
@@ -40,18 +42,15 @@ func genOrderedMapTypeDef(gen *protogen.Plugin, g *protogen.GeneratedFile, md pr
4042
currValueType := helper.ParseCsharpType(fd.MapValue())
4143
nextPrefix := parseOrderedMapPrefix(nextMapFD, messagerFullName)
4244
nextOrderedMap := nextPrefix + orderedMapSuffix
43-
g.P(helper.Indent(2), "public class ", orderedMapValue, " : Tuple<", nextOrderedMap, ", ", currValueType, "?>")
44-
g.P(helper.Indent(2), "{")
45-
g.P(helper.Indent(3), "public ", orderedMapValue, "(", nextOrderedMap, " item1, ", currValueType, "? item2) : base(item1, item2) { }")
46-
g.P(helper.Indent(2), "}")
45+
g.P(helper.Indent(2), "public class ", orderedMapValue, "(", nextOrderedMap, " item1, ", currValueType, "? item2) : Tuple<", nextOrderedMap, ", ", currValueType, "?>(item1, item2) { }")
4746
g.P(helper.Indent(2), "public class ", orderedMap, " : SortedDictionary<", keyType, ", ", orderedMapValue, "> { }")
4847
g.P()
4948
} else {
5049
g.P(helper.Indent(2), "public class ", orderedMap, " : SortedDictionary<", keyType, ", ", parseMapValueType(fd), "> { }")
5150
g.P()
5251
}
5352
if depth == 1 {
54-
g.P(helper.Indent(2), "private ", orderedMap, " OrderedMap = new ", orderedMap, "();")
53+
g.P(helper.Indent(2), "private readonly ", orderedMap, " OrderedMap = [];")
5554
g.P()
5655
}
5756
break
@@ -150,10 +149,12 @@ func genOrderedMapGetters(gen *protogen.Plugin, g *protogen.GeneratedFile, md pr
150149
}
151150
}
152151

152+
var caser = cases.Title(language.Und, cases.NoLower)
153+
153154
func parseOrderedMapPrefix(mapFd protoreflect.FieldDescriptor, messagerFullName string) string {
154155
if mapFd.MapValue().Kind() == protoreflect.MessageKind {
155156
localMsgProtoName := strings.TrimPrefix(string(mapFd.MapValue().Message().FullName()), messagerFullName+".")
156-
return strings.ReplaceAll(localMsgProtoName, ".", "_")
157+
return caser.String(strings.ReplaceAll(localMsgProtoName, ".", "_"))
157158
}
158-
return mapFd.MapValue().Kind().String()
159+
return caser.String(mapFd.MapValue().Kind().String())
159160
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Microsoft Visual Studio Solution File, Format Version 12.00
2+
# Visual Studio Version 17
3+
VisualStudioVersion = 17.5.2.0
4+
MinimumVisualStudioVersion = 10.0.40219.1
5+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Loader", "Loader.csproj", "{E8053C8C-98ED-7494-D874-8E12A72FA028}"
6+
EndProject
7+
Global
8+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
9+
Debug|Any CPU = Debug|Any CPU
10+
Release|Any CPU = Release|Any CPU
11+
EndGlobalSection
12+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
13+
{E8053C8C-98ED-7494-D874-8E12A72FA028}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14+
{E8053C8C-98ED-7494-D874-8E12A72FA028}.Debug|Any CPU.Build.0 = Debug|Any CPU
15+
{E8053C8C-98ED-7494-D874-8E12A72FA028}.Release|Any CPU.ActiveCfg = Release|Any CPU
16+
{E8053C8C-98ED-7494-D874-8E12A72FA028}.Release|Any CPU.Build.0 = Release|Any CPU
17+
EndGlobalSection
18+
GlobalSection(SolutionProperties) = preSolution
19+
HideSolutionNode = FALSE
20+
EndGlobalSection
21+
GlobalSection(ExtensibilityGlobals) = postSolution
22+
SolutionGuid = {80988C2E-15FF-4FCD-B5F0-A75A1AD74321}
23+
EndGlobalSection
24+
EndGlobal

test/csharp-tableau-loader/tableau/HeroConf.cs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33
// - protoc-gen-csharp-tableau-loader v0.1.0
44
// - protoc v3.19.3
55
// source: hero_conf.proto
6-
using System;
7-
using System.Collections.Generic;
8-
using Google.Protobuf;
9-
using Google.Protobuf.Collections;
106

117
namespace Tableau
128
{
@@ -15,15 +11,12 @@ public class HeroConf : Messager, IMessagerName
1511
// OrderedMap types.
1612
public class Hero_Attr_OrderedMap : SortedDictionary<string, Protoconf.HeroConf.Types.Hero.Types.Attr> { }
1713

18-
public class Hero_OrderedMapValue : Tuple<Hero_Attr_OrderedMap, Protoconf.HeroConf.Types.Hero?>
19-
{
20-
public Hero_OrderedMapValue(Hero_Attr_OrderedMap item1, Protoconf.HeroConf.Types.Hero? item2) : base(item1, item2) { }
21-
}
14+
public class Hero_OrderedMapValue(Hero_Attr_OrderedMap item1, Protoconf.HeroConf.Types.Hero? item2) : Tuple<Hero_Attr_OrderedMap, Protoconf.HeroConf.Types.Hero?>(item1, item2) { }
2215
public class Hero_OrderedMap : SortedDictionary<string, Hero_OrderedMapValue> { }
2316

24-
private Hero_OrderedMap OrderedMap = new Hero_OrderedMap();
17+
private readonly Hero_OrderedMap OrderedMap = [];
2518

26-
private Protoconf.HeroConf Data_ = new Protoconf.HeroConf();
19+
private Protoconf.HeroConf Data_ = new();
2720

2821
public static string Name() => Protoconf.HeroConf.Descriptor.Name;
2922

@@ -32,7 +25,7 @@ public override bool Load(string dir, Format fmt, in LoadOptions? options = null
3225
var start = DateTime.Now;
3326
bool loaded = LoadMessageByPath<Protoconf.HeroConf>(out var msg, dir, fmt, options);
3427
Data_ = msg;
35-
bool ok = loaded ? ProcessAfterLoad() : false;
28+
bool ok = loaded && ProcessAfterLoad();
3629
LoadStats.Duration = DateTime.Now - start;
3730
return ok;
3831
}
@@ -67,7 +60,7 @@ protected override bool ProcessAfterLoad()
6760

6861
public class HeroBaseConf : Messager, IMessagerName
6962
{
70-
private Protoconf.HeroBaseConf Data_ = new Protoconf.HeroBaseConf();
63+
private Protoconf.HeroBaseConf Data_ = new();
7164

7265
public static string Name() => Protoconf.HeroBaseConf.Descriptor.Name;
7366

@@ -76,7 +69,7 @@ public override bool Load(string dir, Format fmt, in LoadOptions? options = null
7669
var start = DateTime.Now;
7770
bool loaded = LoadMessageByPath<Protoconf.HeroBaseConf>(out var msg, dir, fmt, options);
7871
Data_ = msg;
79-
bool ok = loaded ? ProcessAfterLoad() : false;
72+
bool ok = loaded && ProcessAfterLoad();
8073
LoadStats.Duration = DateTime.Now - start;
8174
return ok;
8275
}

0 commit comments

Comments
 (0)