You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

285 lines
8.1 KiB

1 month ago
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace ProtoCSStruct
{
public class CSharpStructWriter
{
//所有fixed 长度大小的string类,int表示长度,为了减少类型数量,长度必须是8的倍数
private HashSet<int> AllFixStringClass;
//所有repeated struct 的类型
private HashSet<string> AllRepeatedStructSet;
//需要按申明顺序保存
private List<ProtoMessageField> AllRepeatedStructList;
public CSharpStructWriter()
{
AllFixStringClass = new HashSet<int>();
AllRepeatedStructSet = new HashSet<string>();
AllRepeatedStructList = new List<ProtoMessageField>();
}
public void WriteCSStructFile()
{
//固定长度的string类型 FixedRepeatedStruct
WriteAllFixRepeatedClass();
//协议文件
WriteAllProtoFile();
}
private void WriteAllFixRepeatedClass()
{
string outfile = ProtoDescriptorAll.Instance.AllProtoDescriptor[0].OutPutPath + "/FixedRepeatedStruct.cs";
string nameSpace = ProtoDescriptorAll.Instance.AllProtoDescriptor[0].NameSpace;
FileWriter fw = new FileWriter(outfile);
fw.Write(Define.FileHeader);
fw.Write(
"",
"using System;",
"using System.Text;",
"",
"namespace " + nameSpace,
"{",
""
);
fw.Indent();
WriteFixStringClass(fw);
WriteRepeatedStructClass(fw);
fw.Outdent();
fw.Write("}");//namespace
fw.WriteToFile();
Console.WriteLine("generator {0} success", outfile);
}
private void WriteFixStringClass(FileWriter fw)
{
GetAllFixedString();
foreach (var length in AllFixStringClass)
{
FixedStringWriter fsw = new FixedStringWriter();
fsw.Write(length, fw);
}
}
private void WriteRepeatedStructClass(FileWriter fw)
{
GetAllRepeatedStructClass();
foreach (var repeatedstruct in AllRepeatedStructList)
{
RepeatedStructWriter rsw = new RepeatedStructWriter();
rsw.Write(repeatedstruct,fw);
}
}
private void GetAllFixedString()
{
foreach (var pd in ProtoDescriptorAll.Instance.AllProtoDescriptor)
{
foreach (var message in pd.Messages)
{
foreach (var field in message.Fields)
{
if (field.FieldType == FieldType.String)
{
if (AllFixStringClass.Contains(field.StringLength) == false)
{
AllFixStringClass.Add(field.StringLength);
}
}
}
}
}
//AllFixStringClass = AllFixStringClass.OrderBy(o => o).to
}
private void GetAllRepeatedStructClass()
{
foreach (var pd in ProtoDescriptorAll.Instance.AllProtoDescriptor)
{
foreach (var message in pd.Messages)
{
foreach (var field in message.Fields)
{
if (field.IsRepeated == false && field.FieldType != FieldType.Bytes)
{
continue;
}
//生成的repeated class 名字, 类似
string repeatedclassname = field.GetRepeatedFiledTypeNameInCSharp();
if (repeatedclassname != null)
{
if (AllRepeatedStructSet.Contains(repeatedclassname) == false)
{
AllRepeatedStructSet.Add(repeatedclassname);
AllRepeatedStructList.Add(field);
}
}
}
}
}
}
private void WriteAllProtoFile()
{
foreach (var pd in ProtoDescriptorAll.Instance.AllProtoDescriptor)
{
WriteProtoFile(pd);
}
}
private void WriteProtoFile(ProtoDescriptor pd)
{
string outfile = pd.OutPutFile;
string nameSpace = pd.NameSpace;
FileWriter fw = new FileWriter(outfile);
fw.Write(Define.FileHeader);
fw.Write(
"using System;",
"",
"namespace " + nameSpace,
"{",
""
);
fw.Indent();
WriteAllMessage(pd, fw);
fw.Outdent();
fw.Write("}");//namespace
fw.WriteToFile();
Console.WriteLine("generator csharp file {0} success", outfile);
//枚举单独写一个文件,方便共享
WriteAllEnums(pd);
//需要生成class描述的message单独生成一个文件
WriteMessageClassDesc(pd);
}
private void WriteAllEnums(ProtoDescriptor pd)
{
FileWriter fw = new FileWriter(pd.EnumOutPutFile);
fw.Write(Define.FileHeader);
fw.Write(
"using System;",
"",
"namespace " + pd.NameSpace,
"{",
""
);
fw.Indent();
fw.Write("//");
fw.Write("//enum");
fw.Write("//");
fw.Write("#region Enums");
fw.Write("");
EnumWriter ew = new EnumWriter();
foreach (var oneEnum in pd.Enums)
{
ew.Write(oneEnum, fw);
}
fw.Write("");
fw.Write("#endregion");
fw.Outdent();
fw.Write("}");//namespace
fw.WriteToFile();
Console.WriteLine("generator csharp file {0} success", pd.EnumOutPutFile);
}
private void WriteAllMessage(ProtoDescriptor pd, FileWriter fw)
{
MessageWriter mw = new MessageWriter();
fw.Write("//");
fw.Write("//message");
fw.Write("//");
fw.Write("#region Messages");
fw.Write("");
foreach (var message in pd.Messages)
{
mw.Write(message, fw);
}
fw.Write("");
fw.Write("#endregion");
}
private void WriteMessageClassDesc(ProtoDescriptor pd)
{
if (pd.MessagesNeedClassDesc.Count == 0)
{
return;
}
MessageWriter mw = new MessageWriter();
FileWriter fw = new FileWriter(pd.ClassOutPutFile);
fw.Write(Define.FileHeader);
fw.Write(
//"#if ILRUNTIME_MODE",
//"",
"using System;",
"using System.Collections.Generic;",
"using BinarySerialize;",
"using System.IO;",
"",
"namespace " + pd.NameSpace,
"{",
""
);
fw.Indent();
fw.Write("//");
fw.Write("//class desc");
fw.Write("//");
fw.Write("#region ClassDesc");
fw.Write("");
foreach (var message in pd.MessagesNeedClassDesc)
{
mw.WriteClassDesc(message, fw);
}
fw.Write("");
fw.Write("#endregion");
fw.Outdent();
fw.Write("}");//namespace
//fw.Write("");
//fw.Write("#endif");
fw.WriteToFile();
Console.WriteLine("generator csharp file {0} success", pd.ClassOutPutFile);
}
}
}