【特性】支持生成 proto定义文件和proto二进制数据
parent
b8e794d528
commit
66ba09e8a0
|
|
@ -126,6 +126,11 @@ namespace Luban.Common.Utils
|
|||
return MakeGoNamespace(module) + name;
|
||||
}
|
||||
|
||||
public static string MakePbFullName(string module, string name)
|
||||
{
|
||||
return MakeGoNamespace(module) + name;
|
||||
}
|
||||
|
||||
public static string MakeNamespace(string module, string subModule)
|
||||
{
|
||||
if (module.Length == 0)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,300 @@
|
|||
using Google.Protobuf;
|
||||
using Luban.Job.Cfg.Datas;
|
||||
using Luban.Job.Cfg.DataSources;
|
||||
using Luban.Job.Cfg.DataVisitors;
|
||||
using Luban.Job.Cfg.Defs;
|
||||
using Luban.Job.Common.Generate;
|
||||
using Luban.Job.Common.Types;
|
||||
using Luban.Job.Common.TypeVisitors;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Luban.Job.Cfg.DataExporters
|
||||
{
|
||||
class ProtobufExportor : IDataActionVisitor<CodedOutputStream>
|
||||
{
|
||||
public static ProtobufExportor Ins { get; } = new();
|
||||
|
||||
public void WriteList(DefTable table, List<Record> datas, MemoryStream x)
|
||||
{
|
||||
var cos = new CodedOutputStream(x);
|
||||
foreach (var d in datas)
|
||||
{
|
||||
cos.WriteTag(1, WireFormat.WireType.LengthDelimited);
|
||||
d.Data.Apply(this, cos);
|
||||
}
|
||||
cos.Flush();
|
||||
}
|
||||
|
||||
public void Accept(DBool type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteBool(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DByte type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteInt32(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DShort type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteInt32(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DFshort type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteInt32(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DInt type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteInt32(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DFint type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteSFixed32(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DLong type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteInt64(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DFlong type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteSFixed64(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DFloat type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteFloat(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DDouble type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteDouble(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DEnum type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteInt32(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DDateTime type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteInt32(type.GetUnixTime(DefAssembly.LocalAssebmly.TimeZone));
|
||||
}
|
||||
|
||||
public void Accept(DString type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteString(type.Value);
|
||||
}
|
||||
|
||||
public void Accept(DBytes type, CodedOutputStream x)
|
||||
{
|
||||
x.WriteBytes(ByteString.CopyFrom(type.Value));
|
||||
}
|
||||
|
||||
public void Accept(DText type, CodedOutputStream x)
|
||||
{
|
||||
// 此处与 binary格式不同. binary格式还包含了key
|
||||
// 意味pb格式是无法支持动态本土化的。
|
||||
var ass = DefAssembly.LocalAssebmly;
|
||||
x.WriteString(type.GetText(ass.ExportTextTable, ass.NotConvertTextSet));
|
||||
}
|
||||
|
||||
private MemoryStream AllocMemoryStream()
|
||||
{
|
||||
return new MemoryStream();
|
||||
}
|
||||
|
||||
private void FreeMemoryStream(MemoryStream cos)
|
||||
{
|
||||
cos.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public void Accept(DVector2 type, CodedOutputStream x)
|
||||
{
|
||||
var ms = AllocMemoryStream();
|
||||
var temp = new CodedOutputStream(ms);
|
||||
temp.WriteTag(1, WireFormat.WireType.Fixed32);
|
||||
temp.WriteFloat(type.Value.X);
|
||||
temp.WriteTag(2, WireFormat.WireType.Fixed32);
|
||||
temp.WriteFloat(type.Value.Y);
|
||||
temp.Flush();
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
x.WriteBytes(ByteString.FromStream(ms));
|
||||
FreeMemoryStream(ms);
|
||||
}
|
||||
|
||||
public void Accept(DVector3 type, CodedOutputStream x)
|
||||
{
|
||||
var ms = AllocMemoryStream();
|
||||
var temp = new CodedOutputStream(ms);
|
||||
temp.WriteTag(1, WireFormat.WireType.Fixed32);
|
||||
temp.WriteFloat(type.Value.X);
|
||||
temp.WriteTag(2, WireFormat.WireType.Fixed32);
|
||||
temp.WriteFloat(type.Value.Y);
|
||||
temp.WriteTag(3, WireFormat.WireType.Fixed32);
|
||||
temp.WriteFloat(type.Value.Z);
|
||||
temp.Flush();
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
x.WriteBytes(ByteString.FromStream(ms));
|
||||
FreeMemoryStream(ms);
|
||||
}
|
||||
|
||||
public void Accept(DVector4 type, CodedOutputStream x)
|
||||
{
|
||||
var ms = AllocMemoryStream();
|
||||
var temp = new CodedOutputStream(ms);
|
||||
temp.WriteTag(1, WireFormat.WireType.Fixed32);
|
||||
temp.WriteFloat(type.Value.X);
|
||||
temp.WriteTag(2, WireFormat.WireType.Fixed32);
|
||||
temp.WriteFloat(type.Value.Y);
|
||||
temp.WriteTag(3, WireFormat.WireType.Fixed32);
|
||||
temp.WriteFloat(type.Value.Z);
|
||||
temp.WriteTag(4, WireFormat.WireType.Fixed32);
|
||||
temp.WriteFloat(type.Value.W);
|
||||
temp.Flush();
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
x.WriteBytes(ByteString.FromStream(ms));
|
||||
FreeMemoryStream(ms);
|
||||
}
|
||||
|
||||
public void Accept(DBean type, CodedOutputStream x)
|
||||
{
|
||||
var bean = type.Type;
|
||||
if (bean.IsAbstractType)
|
||||
{
|
||||
x.WriteTag(type.ImplType.AutoId, WireFormat.WireType.LengthDelimited);
|
||||
}
|
||||
|
||||
var ms = AllocMemoryStream();
|
||||
var temp = new CodedOutputStream(ms);
|
||||
|
||||
var defFields = type.ImplType.HierarchyFields;
|
||||
int index = 0;
|
||||
foreach (var field in type.Fields)
|
||||
{
|
||||
var defField = (DefField)defFields[index++];
|
||||
if (!defField.NeedExport)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var fieldType = defField.CType;
|
||||
if (field == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch (field)
|
||||
{
|
||||
case DArray arr:
|
||||
{
|
||||
WriteList(fieldType.ElementType, defField.AutoId, arr.Datas, temp);
|
||||
break;
|
||||
}
|
||||
case DList list:
|
||||
{
|
||||
WriteList(fieldType.ElementType, defField.AutoId, list.Datas, temp);
|
||||
break;
|
||||
}
|
||||
case DSet set:
|
||||
{
|
||||
WriteList(fieldType.ElementType, defField.AutoId, set.Datas, temp);
|
||||
break;
|
||||
}
|
||||
case DMap map:
|
||||
{
|
||||
WriteMap(map, defField.AutoId, temp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
temp.WriteTag(defField.AutoId, defField.CType.Apply(ProtobufWireTypeVisitor.Ins));
|
||||
field.Apply(this, temp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
temp.Flush();
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
var bs = ByteString.FromStream(ms);
|
||||
x.WriteBytes(bs);
|
||||
FreeMemoryStream(ms);
|
||||
}
|
||||
|
||||
private void WriteList(TType elementType, int fieldId, List<DType> datas, CodedOutputStream x)
|
||||
{
|
||||
if (elementType.Apply(IsProtobufPackedType.Ins))
|
||||
{
|
||||
x.WriteTag(fieldId, WireFormat.WireType.LengthDelimited);
|
||||
var ms = AllocMemoryStream();
|
||||
var temp = new CodedOutputStream(ms);
|
||||
foreach (var data in datas)
|
||||
{
|
||||
data.Apply(this, temp);
|
||||
}
|
||||
temp.Flush();
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
x.WriteBytes(ByteString.FromStream(ms));
|
||||
FreeMemoryStream(ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
var eleWireType = elementType.Apply(ProtobufWireTypeVisitor.Ins);
|
||||
foreach (var data in datas)
|
||||
{
|
||||
x.WriteTag(fieldId, eleWireType);
|
||||
data.Apply(this, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Accept(DArray type, CodedOutputStream x)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Accept(DList type, CodedOutputStream x)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Accept(DSet type, CodedOutputStream x)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void WriteMap(DMap type, int fieldId, CodedOutputStream x)
|
||||
{
|
||||
var keyType = type.Type.KeyType;
|
||||
var valueType = type.Type.ValueType;
|
||||
var ms = AllocMemoryStream();
|
||||
foreach (var e in type.Datas)
|
||||
{
|
||||
x.WriteTag(fieldId, WireFormat.WireType.LengthDelimited);
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
var temp = new CodedOutputStream(ms);
|
||||
temp.WriteTag(1, keyType.Apply(ProtobufWireTypeVisitor.Ins));
|
||||
e.Key.Apply(this, temp);
|
||||
temp.WriteTag(2, valueType.Apply(ProtobufWireTypeVisitor.Ins));
|
||||
e.Value.Apply(this, temp);
|
||||
temp.Flush();
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
x.WriteBytes(ByteString.FromStream(ms));
|
||||
|
||||
}
|
||||
FreeMemoryStream(ms);
|
||||
}
|
||||
|
||||
public void Accept(DMap type, CodedOutputStream x)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -28,9 +28,17 @@ namespace Luban.Job.Cfg.DataVisitors
|
|||
|
||||
void Accept(DString type, T x);
|
||||
|
||||
void Accept(DText type, T x);
|
||||
|
||||
void Accept(DBytes type, T x);
|
||||
|
||||
void Accept(DText type, T x);
|
||||
void Accept(DVector2 type, T x);
|
||||
|
||||
void Accept(DVector3 type, T x);
|
||||
|
||||
void Accept(DVector4 type, T x);
|
||||
|
||||
void Accept(DDateTime type, T x);
|
||||
|
||||
void Accept(DBean type, T x);
|
||||
|
||||
|
|
@ -41,14 +49,6 @@ namespace Luban.Job.Cfg.DataVisitors
|
|||
void Accept(DSet type, T x);
|
||||
|
||||
void Accept(DMap type, T x);
|
||||
|
||||
void Accept(DVector2 type, T x);
|
||||
|
||||
void Accept(DVector3 type, T x);
|
||||
|
||||
void Accept(DVector4 type, T x);
|
||||
|
||||
void Accept(DDateTime type, T x);
|
||||
}
|
||||
|
||||
public interface IDataActionVisitor<T1, T2>
|
||||
|
|
@ -75,11 +75,19 @@ namespace Luban.Job.Cfg.DataVisitors
|
|||
|
||||
void Accept(DEnum type, T1 x, T2 y);
|
||||
|
||||
void Accept(DDateTime type, T1 x, T2 y);
|
||||
|
||||
void Accept(DString type, T1 x, T2 y);
|
||||
|
||||
void Accept(DText type, T1 x, T2 y);
|
||||
|
||||
void Accept(DBytes type, T1 x, T2 y);
|
||||
|
||||
void Accept(DText type, T1 x, T2 y);
|
||||
void Accept(DVector2 type, T1 x, T2 y);
|
||||
|
||||
void Accept(DVector3 type, T1 x, T2 y);
|
||||
|
||||
void Accept(DVector4 type, T1 x, T2 y);
|
||||
|
||||
void Accept(DBean type, T1 x, T2 y);
|
||||
|
||||
|
|
@ -90,13 +98,5 @@ namespace Luban.Job.Cfg.DataVisitors
|
|||
void Accept(DSet type, T1 x, T2 y);
|
||||
|
||||
void Accept(DMap type, T1 x, T2 y);
|
||||
|
||||
void Accept(DVector2 type, T1 x, T2 y);
|
||||
|
||||
void Accept(DVector3 type, T1 x, T2 y);
|
||||
|
||||
void Accept(DVector4 type, T1 x, T2 y);
|
||||
|
||||
void Accept(DDateTime type, T1 x, T2 y);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ namespace Luban.Job.Cfg.Defs
|
|||
|
||||
public List<DefField> ExportFields { get; private set; }
|
||||
|
||||
public int AutoId { get; set; }
|
||||
|
||||
public bool IsDefineEquals(DefBean b)
|
||||
{
|
||||
return DeepCompareTypeDefine.Ins.Compare(this, b, new Dictionary<DefTypeBase, bool>(), new HashSet<DefTypeBase>());
|
||||
|
|
@ -196,6 +198,18 @@ namespace Luban.Job.Cfg.Defs
|
|||
}
|
||||
}
|
||||
DefField.CompileFields(this, HierarchyFields, false);
|
||||
|
||||
var allocAutoIds = this.HierarchyFields.Select(f => f.Id).ToHashSet();
|
||||
|
||||
int nextAutoId = 1;
|
||||
foreach (var f in this.HierarchyFields)
|
||||
{
|
||||
while (!allocAutoIds.Add(nextAutoId))
|
||||
{
|
||||
++nextAutoId;
|
||||
}
|
||||
f.AutoId = nextAutoId;
|
||||
}
|
||||
}
|
||||
|
||||
public override void PostCompile()
|
||||
|
|
@ -204,6 +218,14 @@ namespace Luban.Job.Cfg.Defs
|
|||
{
|
||||
field.PostCompile();
|
||||
}
|
||||
if (this.IsAbstractType && this.ParentDefType == null)
|
||||
{
|
||||
int nextAutoId = 0;
|
||||
foreach (DefBean c in this.HierarchyNotAbstractChildren)
|
||||
{
|
||||
c.AutoId = ++nextAutoId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ namespace Luban.Job.Cfg.Defs
|
|||
|
||||
public TBean ValueTType { get; private set; }
|
||||
|
||||
public TType Type { get; private set; }
|
||||
|
||||
public DefField IndexField { get; private set; }
|
||||
|
||||
public int IndexFieldIdIndex { get; private set; }
|
||||
|
|
@ -86,6 +88,7 @@ namespace Luban.Job.Cfg.Defs
|
|||
case ETableMode.ONE:
|
||||
{
|
||||
KeyTType = null;
|
||||
Type = ValueTType;
|
||||
break;
|
||||
}
|
||||
case ETableMode.MAP:
|
||||
|
|
@ -113,6 +116,7 @@ namespace Luban.Job.Cfg.Defs
|
|||
IndexFieldIdIndex = 0;
|
||||
}
|
||||
KeyTType = IndexField.CType;
|
||||
Type = TMap.Create(false, null, KeyTType, ValueTType, false);
|
||||
break;
|
||||
}
|
||||
default: throw new Exception($"unknown mode:'{Mode}'");
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ namespace Luban.Job.Cfg.Generate
|
|||
[Render("data_lua")]
|
||||
[Render("data_xml")]
|
||||
[Render("data_yaml")]
|
||||
[Render("data_protobuf")]
|
||||
class DataScatterRender : DataRenderBase
|
||||
{
|
||||
public override void Render(GenContext ctx)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,5 @@ namespace Luban.Job.Cfg.Generate
|
|||
var md5 = CacheFileUtil.GenMd5AndAddCache(file, string.Join('\n', content));
|
||||
ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 });
|
||||
}
|
||||
|
||||
public abstract string RenderAll(List<DefTypeBase> types);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
using Luban.Common.Protos;
|
||||
using Luban.Job.Cfg.Defs;
|
||||
using Luban.Job.Common.Defs;
|
||||
using Luban.Job.Common.Generate;
|
||||
using Luban.Job.Common.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Luban.Job.Cfg.Generate
|
||||
{
|
||||
[Render("code_protobuf")]
|
||||
[Render("code_protobuf2")]
|
||||
class Protobuf2SchemaRender : ProtobufSchemaRenderBase
|
||||
{
|
||||
protected override string RenderTemplateDir => "pb2";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using Luban.Job.Common.Generate;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Luban.Job.Cfg.Generate
|
||||
{
|
||||
[Render("code_protobuf3")]
|
||||
class Protobuf3SchemaRender : ProtobufSchemaRenderBase
|
||||
{
|
||||
protected override string RenderTemplateDir => "pb3";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
using Luban.Common.Protos;
|
||||
using Luban.Job.Cfg.Defs;
|
||||
using Luban.Job.Common.Defs;
|
||||
using Luban.Job.Common.Generate;
|
||||
using Luban.Job.Common.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Luban.Job.Cfg.Generate
|
||||
{
|
||||
abstract class ProtobufSchemaRenderBase : TemplateCodeRenderBase
|
||||
{
|
||||
protected override string CommonRenderTemplateDir => "pb";
|
||||
|
||||
public override void Render(GenContext ctx)
|
||||
{
|
||||
DefAssembly.LocalAssebmly.CurrentLanguage = Common.ELanguage.LUA;
|
||||
var file = RenderFileUtil.GetFileOrDefault(ctx.GenArgs.OutputCodeMonolithicFile, "config.proto");
|
||||
var content = this.RenderAll(ctx.ExportTypes);
|
||||
var md5 = CacheFileUtil.GenMd5AndAddCache(file, string.Join('\n', content));
|
||||
ctx.GenCodeFilesInOutputCodeDir.Add(new FileInfo() { FilePath = file, MD5 = md5 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -52,5 +52,21 @@ namespace Luban.Job.Cfg.Generate
|
|||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual string RenderAll(List<DefTypeBase> types)
|
||||
{
|
||||
var enums = types.Where(t => t is DefEnum).ToList();
|
||||
var beans = types.Where(t => t is DefBean).ToList();
|
||||
var tables = types.Where(t => t is DefTable).ToList();
|
||||
|
||||
var template = StringTemplateUtil.GetTemplate($"config/{RenderTemplateDir}/all");
|
||||
var result = template.RenderCode(new {
|
||||
Namespace = DefAssembly.LocalAssebmly.TopModule,
|
||||
Enums = enums.Select(e => Render((DefEnum)e)).ToList(),
|
||||
Beans = beans.Select(b => Render((DefBean)b)).ToList(),
|
||||
Tables = tables.Select(t => Render((DefTable)t)).ToList(),
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,12 @@ namespace Luban.Job.Cfg.Utils
|
|||
}
|
||||
return string.Join('\n', content);
|
||||
}
|
||||
case "data_protobuf":
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
ProtobufExportor.Ins.WriteList(table, records, ms);
|
||||
return DataUtil.StreamToBytes(ms);
|
||||
}
|
||||
//case "data_erlang":
|
||||
//{
|
||||
// var content = new StringBuilder();
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.19.1" />
|
||||
<PackageReference Include="Scriban" Version="4.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -13,9 +13,11 @@ namespace Luban.Job.Common.Defs
|
|||
|
||||
public DefTypeBase HostType { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
public int Id { get; protected set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Name { get; protected set; }
|
||||
|
||||
public int AutoId { get; set; }
|
||||
|
||||
public string ConventionName
|
||||
{
|
||||
|
|
@ -44,6 +46,7 @@ namespace Luban.Job.Common.Defs
|
|||
case ELanguage.TYPESCRIPT: cn = TypeUtil.ToCamelCase(Name); break;
|
||||
case ELanguage.PYTHON: cn = TypeUtil.ToUnderScores(Name); break;
|
||||
case ELanguage.RUST: cn = TypeUtil.ToUnderScores(Name); break;
|
||||
case ELanguage.PROTOBUF: cn = Name; break;
|
||||
default: throw new Exception($"unknown language:{curLan}");
|
||||
}
|
||||
break;
|
||||
|
|
@ -91,6 +94,7 @@ namespace Luban.Job.Common.Defs
|
|||
{
|
||||
HostType = host;
|
||||
Id = f.Id + idOffset;
|
||||
AutoId = Id;
|
||||
Name = f.Name;
|
||||
Type = f.Type;
|
||||
Comment = f.Comment;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ namespace Luban.Job.Common.Defs
|
|||
|
||||
public string RustFullName => TypeUtil.MakeRustFullName(Namespace, Name);
|
||||
|
||||
public string PbFullName => TypeUtil.MakePbFullName(Namespace, Name);
|
||||
|
||||
public string Comment { get; protected set; }
|
||||
|
||||
public string EscapeComment => DefUtil.EscapeCommentByCurrentLanguage(Comment);
|
||||
|
|
|
|||
|
|
@ -205,6 +205,46 @@ namespace Luban.Job.Common.Defs
|
|||
return type.Apply(GoDeserializeBinVisitor.Ins, name, bufName, err);
|
||||
}
|
||||
|
||||
public static string ProtobufDefineType(TType type)
|
||||
{
|
||||
return type.Apply(ProtobufTypeNameVisitor.Ins);
|
||||
}
|
||||
|
||||
public static string ProtobufPreDecorator(TType type)
|
||||
{
|
||||
if (type.IsNullable)
|
||||
{
|
||||
return "optional";
|
||||
}
|
||||
else if (type.IsCollection)
|
||||
{
|
||||
if (type is TMap)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "repeated";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return "required";
|
||||
}
|
||||
}
|
||||
|
||||
public static string ProtobufSuffixOptions(TType type)
|
||||
{
|
||||
if (type.IsCollection && !(type is TMap))
|
||||
{
|
||||
return $"[packed = {(type.ElementType.Apply(IsProtobufPackedType.Ins) ? "true" : "false")}]";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasTag(dynamic obj, string attrName)
|
||||
{
|
||||
return obj.HasTag(attrName);
|
||||
|
|
|
|||
|
|
@ -13,5 +13,6 @@ namespace Luban.Job.Common
|
|||
PYTHON,
|
||||
ERLANG,
|
||||
RUST,
|
||||
PROTOBUF,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
using Luban.Job.Common.Types;
|
||||
using Luban.Job.Common.TypeVisitors;
|
||||
|
||||
namespace Luban.Job.Common.TypeVisitors
|
||||
{
|
||||
public class IsProtobufPackedType : AllTrueVisitor
|
||||
{
|
||||
public static IsProtobufPackedType Ins { get; } = new();
|
||||
|
||||
|
||||
public override bool Accept(TString type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Accept(TText type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Accept(TBytes type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Accept(TVector2 type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Accept(TVector3 type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Accept(TVector4 type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Accept(TEnum type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Accept(TBean type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Accept(TArray type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Accept(TList type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Accept(TSet type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Accept(TMap type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
using Luban.Job.Common.Types;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Luban.Job.Common.TypeVisitors
|
||||
{
|
||||
public class ProtobufTypeNameVisitor : ITypeFuncVisitor<string>
|
||||
{
|
||||
public static ProtobufTypeNameVisitor Ins { get; } = new();
|
||||
|
||||
public string Accept(TBool type)
|
||||
{
|
||||
return "bool";
|
||||
}
|
||||
|
||||
public string Accept(TByte type)
|
||||
{
|
||||
return "int32";
|
||||
}
|
||||
|
||||
public string Accept(TShort type)
|
||||
{
|
||||
return "int32";
|
||||
}
|
||||
|
||||
public string Accept(TFshort type)
|
||||
{
|
||||
return "int32";
|
||||
}
|
||||
|
||||
public string Accept(TInt type)
|
||||
{
|
||||
return "int32";
|
||||
}
|
||||
|
||||
public string Accept(TFint type)
|
||||
{
|
||||
return "sfixed32";
|
||||
}
|
||||
|
||||
public string Accept(TLong type)
|
||||
{
|
||||
return "int64";
|
||||
}
|
||||
|
||||
public string Accept(TFlong type)
|
||||
{
|
||||
return "sfixed64";
|
||||
}
|
||||
|
||||
public string Accept(TFloat type)
|
||||
{
|
||||
return "float";
|
||||
}
|
||||
|
||||
public string Accept(TDouble type)
|
||||
{
|
||||
return "double";
|
||||
}
|
||||
|
||||
public string Accept(TEnum type)
|
||||
{
|
||||
return type.DefineEnum.PbFullName;
|
||||
}
|
||||
|
||||
public string Accept(TString type)
|
||||
{
|
||||
return "string";
|
||||
}
|
||||
|
||||
public string Accept(TText type)
|
||||
{
|
||||
return "string";
|
||||
}
|
||||
|
||||
public string Accept(TBytes type)
|
||||
{
|
||||
return "bytes";
|
||||
}
|
||||
|
||||
public string Accept(TVector2 type)
|
||||
{
|
||||
return "Vector2";
|
||||
}
|
||||
|
||||
public string Accept(TVector3 type)
|
||||
{
|
||||
return "Vector3";
|
||||
}
|
||||
|
||||
public string Accept(TVector4 type)
|
||||
{
|
||||
return "Vector4";
|
||||
}
|
||||
|
||||
public string Accept(TDateTime type)
|
||||
{
|
||||
return "int32";
|
||||
}
|
||||
|
||||
public string Accept(TBean type)
|
||||
{
|
||||
return type.Bean.GoFullName;
|
||||
}
|
||||
|
||||
public string Accept(TArray type)
|
||||
{
|
||||
return $"{type.ElementType.Apply(this)}";
|
||||
}
|
||||
|
||||
public string Accept(TList type)
|
||||
{
|
||||
return $"{type.ElementType.Apply(this)}";
|
||||
}
|
||||
|
||||
public string Accept(TSet type)
|
||||
{
|
||||
return $"{type.ElementType.Apply(this)}";
|
||||
}
|
||||
|
||||
public string Accept(TMap type)
|
||||
{
|
||||
string key = type.KeyType is TEnum ? "int32" : (type.KeyType.Apply(this));
|
||||
return $"map<{key}, {type.ValueType.Apply(this)}>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
using Google.Protobuf;
|
||||
using Luban.Job.Common.Types;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Luban.Job.Common.TypeVisitors
|
||||
{
|
||||
public class ProtobufWireTypeVisitor : ITypeFuncVisitor<WireFormat.WireType>
|
||||
{
|
||||
public static ProtobufWireTypeVisitor Ins { get; } = new();
|
||||
|
||||
public WireFormat.WireType Accept(TBool type)
|
||||
{
|
||||
return WireFormat.WireType.Varint;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TByte type)
|
||||
{
|
||||
return WireFormat.WireType.Varint;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TShort type)
|
||||
{
|
||||
return WireFormat.WireType.Varint;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TFshort type)
|
||||
{
|
||||
return WireFormat.WireType.Varint;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TInt type)
|
||||
{
|
||||
return WireFormat.WireType.Varint;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TFint type)
|
||||
{
|
||||
return WireFormat.WireType.Fixed32;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TLong type)
|
||||
{
|
||||
return WireFormat.WireType.Varint;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TFlong type)
|
||||
{
|
||||
return WireFormat.WireType.Fixed64;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TFloat type)
|
||||
{
|
||||
return WireFormat.WireType.Fixed32;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TDouble type)
|
||||
{
|
||||
return WireFormat.WireType.Fixed64;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TEnum type)
|
||||
{
|
||||
return WireFormat.WireType.Varint;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TString type)
|
||||
{
|
||||
return WireFormat.WireType.LengthDelimited;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TText type)
|
||||
{
|
||||
return WireFormat.WireType.LengthDelimited;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TBytes type)
|
||||
{
|
||||
return WireFormat.WireType.LengthDelimited;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TVector2 type)
|
||||
{
|
||||
return WireFormat.WireType.LengthDelimited;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TVector3 type)
|
||||
{
|
||||
return WireFormat.WireType.LengthDelimited;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TVector4 type)
|
||||
{
|
||||
return WireFormat.WireType.LengthDelimited;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TDateTime type)
|
||||
{
|
||||
return WireFormat.WireType.Varint;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TBean type)
|
||||
{
|
||||
return WireFormat.WireType.LengthDelimited;
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TArray type)
|
||||
{
|
||||
//return WireFormat.WireType.LengthDelimited;
|
||||
throw new System.NotSupportedException();
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TList type)
|
||||
{
|
||||
throw new System.NotSupportedException();
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TSet type)
|
||||
{
|
||||
throw new System.NotSupportedException();
|
||||
}
|
||||
|
||||
public WireFormat.WireType Accept(TMap type)
|
||||
{
|
||||
return WireFormat.WireType.LengthDelimited;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ namespace Luban.Job.Common.Types
|
|||
return new TArray(isNullable, tags, elementType);
|
||||
}
|
||||
|
||||
public TType ElementType { get; }
|
||||
public override TType ElementType { get; }
|
||||
|
||||
private TArray(bool isNullable, Dictionary<string, string> tags, TType elementType) : base(isNullable, tags)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace Luban.Job.Common.Types
|
|||
return new TList(isNullable, tags, elementType, isArrayList);
|
||||
}
|
||||
|
||||
public TType ElementType { get; }
|
||||
public override TType ElementType { get; }
|
||||
|
||||
public bool IsArrayList { get; }
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace Luban.Job.Common.Types
|
|||
return new TSet(isNullable, tags, elementType, isOrdered);
|
||||
}
|
||||
|
||||
public TType ElementType { get; }
|
||||
public override TType ElementType { get; }
|
||||
|
||||
public bool IsOrderSet { get; }
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ namespace Luban.Job.Common.Types
|
|||
|
||||
public virtual bool IsBean => false;
|
||||
|
||||
public virtual TType ElementType => null;
|
||||
|
||||
public abstract void Apply<T>(ITypeActionVisitor<T> visitor, T x);
|
||||
public abstract void Apply<T1, T2>(ITypeActionVisitor<T1, T2> visitor, T1 x, T2 y);
|
||||
public abstract TR Apply<TR>(ITypeFuncVisitor<TR> visitor);
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ namespace Luban.Job.Common.Utils
|
|||
case ELanguage.TYPESCRIPT:
|
||||
case ELanguage.PYTHON:
|
||||
case ELanguage.RUST:
|
||||
case ELanguage.PROTOBUF:
|
||||
#if !LUBAN_LITE
|
||||
return System.Web.HttpUtility.HtmlEncode(comment).Replace("\n", "<br/>");
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ namespace Luban.Job.Common.Utils
|
|||
case ELanguage.JS: return fullName + ".js";
|
||||
case ELanguage.TYPESCRIPT: return fullName.Replace('.', '/') + ".ts";
|
||||
case ELanguage.RUST: return fullName.Replace('.', '_') + ".rs";
|
||||
case ELanguage.PROTOBUF: return fullName.Replace('.', '_') + ".pb";
|
||||
default: throw new NotSupportedException();
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +72,7 @@ namespace Luban.Job.Common.Utils
|
|||
{ "javascript", ELanguage.JS },
|
||||
{ "erlang", ELanguage.ERLANG },
|
||||
{ "rust", ELanguage.RUST },
|
||||
{ "pb", ELanguage.PROTOBUF },
|
||||
};
|
||||
|
||||
public static ELanguage GetLanguage(string genType)
|
||||
|
|
@ -96,6 +98,7 @@ namespace Luban.Job.Common.Utils
|
|||
{ "erlang", "erl" },
|
||||
{ "erl", "erl" },
|
||||
{ "xlsx", "xlsx" },
|
||||
{ "protobuf", "pb" },
|
||||
};
|
||||
|
||||
public static string GetOutputFileSuffix(string genType)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,9 @@
|
|||
<None Update="Templates\common\lua\base.tpl">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Templates\common\pb\enum.tpl">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Templates\common\python\enum.tpl">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
|
@ -163,6 +166,18 @@
|
|||
<None Update="Templates\config\lua_lua\all.tpl">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Templates\config\pb2\bean.tpl">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Templates\config\pb2\all.tpl">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Templates\config\pb2\table.tpl">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Templates\config\pb2\tables.tpl">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Templates\config\python_json\bean.tpl">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
{{~
|
||||
name = x.name
|
||||
namespace_with_top_module = x.namespace_with_top_module
|
||||
comment = x.comment
|
||||
items = x.items
|
||||
~}}
|
||||
|
||||
enum {{x.pb_full_name}} {
|
||||
{{~for item in items ~}}
|
||||
{{x.pb_full_name}}_{{item.name}} = {{item.int_value}};
|
||||
{{~end~}}
|
||||
{{~if items.empty?~}}
|
||||
{{x.pb_full_name}}_EMPTY_PLACEHOLDER = 0;
|
||||
{{~end~}}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
syntax = "proto2";
|
||||
// luban internal types begin
|
||||
message Vector2 {
|
||||
required float x = 1;
|
||||
required float y = 2;
|
||||
}
|
||||
|
||||
message Vector3 {
|
||||
required float x = 1;
|
||||
required float y = 2;
|
||||
required float z = 3;
|
||||
}
|
||||
|
||||
message Vector4 {
|
||||
required float x = 1;
|
||||
required float y = 2;
|
||||
required float z = 3;
|
||||
required float w = 4;
|
||||
}
|
||||
// luban internal types end
|
||||
|
||||
{{~for enum in x.enums ~}}
|
||||
{{enum}}
|
||||
{{~end~}}
|
||||
|
||||
{{~for bean in x.beans~}}
|
||||
{{bean}}
|
||||
{{~end~}}
|
||||
|
||||
{{~for table in x.tables~}}
|
||||
{{table}}
|
||||
{{~end~}}
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
{{~
|
||||
name = x.name
|
||||
parent_def_type = x.parent_def_type
|
||||
export_fields = x.export_fields
|
||||
hierarchy_export_fields = x.hierarchy_export_fields
|
||||
~}}
|
||||
|
||||
message {{x.pb_full_name}} {
|
||||
{{~if x.is_abstract_type ~}}
|
||||
oneof value {
|
||||
{{~for c in x.hierarchy_not_abstract_children~}}
|
||||
{{c.pb_full_name}} {{c.name}} = {{c.auto_id}};
|
||||
{{~end~}}
|
||||
}
|
||||
{{~else~}}
|
||||
{{~for f in hierarchy_export_fields ~}}
|
||||
{{protobuf_pre_decorator f.ctype}} {{protobuf_define_type f.ctype}} {{f.name}} = {{f.auto_id}} {{protobuf_suffix_options f.ctype}};
|
||||
{{~end~}}
|
||||
{{~end~}}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{{~
|
||||
name = x.name
|
||||
key_type = x.key_ttype
|
||||
value_type = x.value_ttype
|
||||
~}}
|
||||
|
||||
message {{x.pb_full_name}} {
|
||||
repeated {{protobuf_define_type value_type}} data_list = 1 [packed = false];
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{{~
|
||||
name = x.name
|
||||
namespace = x.namespace
|
||||
tables = x.tables
|
||||
~}}
|
||||
|
||||
message {{name}} {
|
||||
{{~index = 0~}}
|
||||
{{~for table in tables~}}
|
||||
{{~index = index + 1~}}
|
||||
{{table.pb_full_name}} {{name}} = {{index}};
|
||||
{{~end~}}
|
||||
}
|
||||
Loading…
Reference in New Issue