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.
277 lines
7.8 KiB
277 lines
7.8 KiB
using System;
|
|
using System.Collections.Generic;
|
|
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();
|
|
|
|
//枚举单独写一个文件,方便共享
|
|
WriteAllEnums(pd);
|
|
|
|
//需要生成class描述的message单独生成一个文件
|
|
WriteMessageClassDesc(pd);
|
|
|
|
Console.WriteLine("generator csharp file {0} success", outfile);
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
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.MessagesMapNeedClassDesc.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;",
|
|
"",
|
|
"namespace " + pd.NameSpace,
|
|
"{",
|
|
""
|
|
);
|
|
fw.Indent();
|
|
|
|
fw.Write("//");
|
|
fw.Write("//class desc");
|
|
fw.Write("//");
|
|
fw.Write("#region ClassDesc");
|
|
fw.Write("");
|
|
|
|
foreach (var message in pd.MessagesMapNeedClassDesc.Values)
|
|
{
|
|
mw.WriteClassDesc(message, fw);
|
|
}
|
|
|
|
fw.Write("");
|
|
fw.Write("#endregion");
|
|
|
|
fw.Outdent();
|
|
fw.Write("}");//namespace
|
|
//fw.Write("");
|
|
//fw.Write("#endif");
|
|
|
|
fw.WriteToFile();
|
|
}
|
|
}
|
|
}
|
|
|