コード例 #1
0
ファイル: ILCodeGen.cs プロジェクト: uncaha/ProtoToCS
        /// <summary>
        /// Write an extension
        /// </summary>
        protected override void WriteExtension(GeneratorContext ctx, FieldDescriptorProto field)
        {
            var type = GetTypeName(ctx, field, out string dataFormat, out bool isMap);

            if (isMap)
            {
                ctx.WriteLine("#error map extensions not yet implemented");
            }
            else if (field.label == FieldDescriptorProto.Label.LabelRepeated)
            {
                ctx.WriteLine("#error repeated extensions not yet implemented");
            }
            else
            {
                var msg      = ctx.TryFind <DescriptorProto>(field.Extendee);
                var extendee = MakeRelativeName(field, msg, ctx.NameNormalizer);

                var    @this = field.Parent is FileDescriptorProto ? "this " : "";
                string name  = field.Name;
                var    tw    = ctx.WriteLine($"{GetAccess(GetAccess(field))} static {type} Get{name}({@this}{extendee} obj)")
                               .Write($"=> obj == null ? default({type}) : global::ProtoBuf.Extensible.GetValue<{type}>(obj, {field.Number}");
                if (!string.IsNullOrEmpty(dataFormat))
                {
                    tw.Write($", global::ProtoBuf.DataFormat.{dataFormat}");
                }
                tw.WriteLine(");");
                ctx.WriteLine();
                //  GetValue<TValue>(IExtensible instance, int tag, DataFormat format)
            }
        }
コード例 #2
0
ファイル: ILCodeGen.cs プロジェクト: uncaha/ProtoToCS
        /// <summary>
        /// Write a field
        /// </summary>
        protected override void WriteField(GeneratorContext ctx, FieldDescriptorProto obj, ref object state, OneOfStub[] oneOfs)
        {
            //var name = ctx.NameNormalizer.GetName(obj);
            var tw = ctx.Output;

            bool isOptional = obj.label == FieldDescriptorProto.Label.LabelOptional;
            bool isRepeated = obj.label == FieldDescriptorProto.Label.LabelRepeated;

            OneOfStub oneOf = obj.ShouldSerializeOneofIndex() ? oneOfs?[obj.OneofIndex] : null;

            if (oneOf != null && oneOf.CountTotal == 1)
            {
                oneOf = null; // not really a one-of, then!
            }
            bool explicitValues = isOptional && oneOf == null && ctx.Syntax == FileDescriptorProto.SyntaxProto2 &&
                                  obj.type != FieldDescriptorProto.Type.TypeMessage &&
                                  obj.type != FieldDescriptorProto.Type.TypeGroup;


            string defaultValue             = null;
            bool   suppressDefaultAttribute = !isOptional;
            var    typeName = GetTypeName(ctx, obj, out var dataFormat, out var isMap);

            defaultValue = GetDefaltValue(ctx, obj, typeName);
            if (isRepeated)
            {
                var mapMsgType = isMap ? ctx.TryFind <DescriptorProto>(obj.TypeName) : null;
                if (mapMsgType != null)
                {
                    var keyTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 1),
                                                  out var keyDataFormat, out var _);
                    var valueTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 2),
                                                    out var valueDataFormat, out var _);
                    ctx.WriteLine($"{GetAccess(GetAccess(obj))} System.Collections.Generic.Dictionary<{keyTypeName}, {valueTypeName}> {Escape(obj.Name)} = new System.Collections.Generic.Dictionary<{keyTypeName}, {valueTypeName}>();");
                }
                // else if (UseArray(obj))
                //  {
                // ctx.WriteLine($"{GetAccess(GetAccess(obj))} {typeName}[] {Escape(name)} ;");
                //  }
                else
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(obj))} System.Collections.Generic.List<{typeName}> {Escape(obj.Name)} = new System.Collections.Generic.List<{typeName}>();");
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(defaultValue))
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(obj))} {typeName} {obj.Name} = {defaultValue};");
                }
                else
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(obj))} {typeName} {obj.Name} ;");
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Emit code initializing field values inside a constructor, if one is required
        /// </summary>
        protected override void WriteInitField(GeneratorContext ctx, FieldDescriptorProto obj, ref object state, OneOfStub[] oneOfs)
        {
            var       name       = ctx.NameNormalizer.GetName(obj);
            bool      isOptional = obj.label == FieldDescriptorProto.Label.LabelOptional;
            bool      isRepeated = obj.label == FieldDescriptorProto.Label.LabelRepeated;
            string    dataFormat;
            bool      isMap;
            var       typeName       = GetTypeName(ctx, obj, out dataFormat, out isMap);
            OneOfStub oneOf          = obj.ShouldSerializeOneofIndex() ? oneOfs?[obj.OneofIndex] : null;
            bool      explicitValues = isOptional && oneOf == null && ctx.Syntax == FileDescriptorProto.SyntaxProto2 &&
                                       obj.type != FieldDescriptorProto.Type.TypeMessage &&
                                       obj.type != FieldDescriptorProto.Type.TypeGroup;

            string defaultValue = GetDefaultValue(ctx, obj, typeName);

            if (isRepeated)
            {
                var mapMsgType = isMap ? ctx.TryFind <DescriptorProto>(obj.TypeName) : null;
                if (mapMsgType != null)
                {
                    string keyDataFormat;
                    string valueDataFormat;
                    bool   _;
                    var    keyTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 1),
                                                     out keyDataFormat, out _);
                    var valueTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 2),
                                                    out valueDataFormat, out _);
                    ctx.WriteLine($"{Escape(name)} = new global::System.Collections.Generic.Dictionary<{keyTypeName}, {valueTypeName}>();");
                }
                else if (UseArray(obj))
                {
                }   // nothing needed
                else
                {
                    ctx.WriteLine($"{Escape(name)} = new global::System.Collections.Generic.List<{typeName}>();");
                }
            }
            else if (oneOf != null)
            {
            }   // nothing to do
            else if (explicitValues)
            {
            }   // nothing to do
            else
            {
                if (!string.IsNullOrWhiteSpace(defaultValue))
                {
                    ctx.WriteLine($"{Escape(name)} = {defaultValue};");
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Obtain a relative name from a type name
        /// </summary>
        protected string MakeRelativeName(GeneratorContext ctx, string typeName)
        {
            var target = ctx.TryFind <DescriptorProto>(typeName);

            if (target != null && target.Parent is IType type)
            {
                var name = FindNameFromCommonAncestor(type, target, ctx.NameNormalizer);
                if (!string.IsNullOrWhiteSpace(name))
                {
                    return(name);
                }
            }

            return(Escape(typeName));
        }
コード例 #5
0
        private string GetTypeName(GeneratorContext ctx, FieldDescriptorProto field, string typeName, ref string dataFormat, ref bool isMap,
                                   bool nonNullable = false)
        {
            switch (typeName)
            {
            case WellKnownTypeTimestamp:
                dataFormat = "WellKnown";
                return(nonNullable ? "global::System.DateTime" : "global::System.DateTime?");

            case WellKnownTypeDuration:
                dataFormat = "WellKnown";
                return(nonNullable ? "global::System.TimeSpan" : "global::System.TimeSpan?");

            case WellKnownTypeEmpty:
                return("global::ProtoBuf.Empty");

            case ".bcl.NetObjectProxy":
                return("object");

            case ".bcl.DateTime":
                return(nonNullable ? "global::System.DateTime" : "global::System.DateTime?");

            case ".bcl.TimeSpan":
                return(nonNullable ? "global::System.TimeSpan" : "global::System.TimeSpan?");

            case ".bcl.Decimal":
                return(nonNullable ? "decimal" : "decimal?");

            case ".bcl.Guid":
                return(nonNullable ? "global::System.Guid" : "global::System.Guid?");
            }
            var msgType = ctx.TryFind <DescriptorProto>(typeName);

            if (field != null && field.type == FieldDescriptorProto.Type.TypeGroup)
            {
                dataFormat = nameof(DataFormat.Group);
            }
            isMap = msgType?.Options?.MapEntry ?? false;
            return(field == null?MakeRelativeName(ctx, typeName) : MakeRelativeName(field, msgType, ctx.NameNormalizer));
        }
コード例 #6
0
        /// <summary>
        /// Write an extension
        /// </summary>
        protected override void WriteExtension(GeneratorContext ctx, FieldDescriptorProto field)
        {
            var type = GetTypeName(ctx, field, out string dataFormat, out bool isMap);

            if (isMap)
            {
                ctx.WriteLine("REM #error map extensions not yet implemented; please file an issue");
            }
            else if (field.label == FieldDescriptorProto.Label.LabelRepeated)
            {
                ctx.WriteLine("REM #error repeated extensions not yet implemented; please file an issue");
            }
            else
            {
                var msg      = ctx.TryFind <DescriptorProto>(field.Extendee);
                var extendee = MakeRelativeName(field, msg, ctx.NameNormalizer);

                string name   = ctx.NameNormalizer.GetName(field);
                string shared = "";
                if (field.Parent is FileDescriptorProto)
                {
                    ctx.WriteLine("<Global.System.Runtime.CompilerServices.Extension> _");
                }
                else
                {
                    shared = "Shared ";
                }
                ctx.WriteLine($"{GetAccess(GetAccess(field))} {shared}Function Get{name}(ByVal obj As {extendee}) As {type}");

                var tw = ctx.Indent().Write($"Return If(obj Is Nothing, CType(Nothing, {type}), Global.ProtoBuf.Extensible.GetValue(Of {type})(obj, {field.Number}");
                if (!string.IsNullOrEmpty(dataFormat))
                {
                    tw.Write($", Global.ProtoBuf.DataFormat.{dataFormat}");
                }
                tw.WriteLine("))");
                ctx.Outdent().WriteLine("End Function");
            }
        }
コード例 #7
0
        /// <summary>
        /// Write a field
        /// </summary>
        protected override void WriteField(GeneratorContext ctx, FieldDescriptorProto field, ref object state, OneOfStub[] oneOfs)
        {
            var name = ctx.NameNormalizer.GetName(field);
            var tw   = ctx.Write($"[global::ProtoBuf.ProtoMember({field.Number}");

            if (name != field.Name)
            {
                tw.Write($@", Name = @""{field.Name}""");
            }
            var options = field.Options?.GetOptions();

            if (options?.AsReference == true)
            {
                tw.Write(", AsReference = true");
            }
            if (options?.DynamicType == true)
            {
                tw.Write(", DynamicType = true");
            }

            bool isOptional = field.label == FieldDescriptorProto.Label.LabelOptional;
            bool isRepeated = field.label == FieldDescriptorProto.Label.LabelRepeated;

            OneOfStub oneOf = field.ShouldSerializeOneofIndex() ? oneOfs?[field.OneofIndex] : null;

            if (oneOf != null && !ctx.OneOfEnums && oneOf.CountTotal == 1)
            {
                oneOf = null; // not really a one-of, then!
            }
            bool explicitValues = isOptional && oneOf == null && ctx.Syntax == FileDescriptorProto.SyntaxProto2 &&
                                  field.type != FieldDescriptorProto.Type.TypeMessage &&
                                  field.type != FieldDescriptorProto.Type.TypeGroup;

            bool   suppressDefaultAttribute = !isOptional;
            var    typeName     = GetTypeName(ctx, field, out var dataFormat, out var isMap);
            string defaultValue = GetDefaultValue(ctx, field, typeName);

            if (!string.IsNullOrWhiteSpace(dataFormat))
            {
                tw.Write($", DataFormat = global::ProtoBuf.DataFormat.{dataFormat}");
            }
            if (field.IsPacked(ctx.Syntax))
            {
                tw.Write($", IsPacked = true");
            }
            if (field.label == FieldDescriptorProto.Label.LabelRequired)
            {
                tw.Write($", IsRequired = true");
            }
            tw.WriteLine(")]");
            if (!isRepeated && !string.IsNullOrWhiteSpace(defaultValue) && !suppressDefaultAttribute)
            {
                ctx.WriteLine($"[global::System.ComponentModel.DefaultValue({defaultValue})]");
            }
            WriteOptions(ctx, field.Options);
            if (isRepeated)
            {
                var  mapMsgType = isMap ? ctx.TryFind <DescriptorProto>(field.TypeName) : null;
                bool allowSet   = ctx.EmitListSetters;
                if (mapMsgType != null)
                {
                    var keyTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 1),
                                                  out var keyDataFormat, out var _);
                    var valueTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 2),
                                                    out var valueDataFormat, out var _);

                    bool first = true;
                    tw = ctx.Write($"[global::ProtoBuf.ProtoMap");
                    if (!string.IsNullOrWhiteSpace(keyDataFormat))
                    {
                        tw.Write($"{(first ? "(" : ", ")}KeyFormat = global::ProtoBuf.DataFormat.{keyDataFormat}");
                        first = false;
                    }
                    if (!string.IsNullOrWhiteSpace(valueDataFormat))
                    {
                        tw.Write($"{(first ? "(" : ", ")}ValueFormat = global::ProtoBuf.DataFormat.{valueDataFormat}");
                        first = false;
                    }
                    tw.WriteLine(first ? "]" : ")]");
                    if (ctx.Supports(CSharp6))
                    {
                        ctx.WriteLine($"{GetAccess(GetAccess(field))} global::System.Collections.Generic.Dictionary<{keyTypeName}, {valueTypeName}> {Escape(name)} {{ get; {(allowSet ? "set; " : "")}}} = new global::System.Collections.Generic.Dictionary<{keyTypeName}, {valueTypeName}>();");
                    }
                    else
                    {
                        ctx.WriteLine($"{GetAccess(GetAccess(field))} global::System.Collections.Generic.Dictionary<{keyTypeName}, {valueTypeName}> {Escape(name)} {{ get; {(allowSet ? "" : "private ")}set; }}");
                    }
                }
                else if (UseArray(field))
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(field))} {typeName}[] {Escape(name)} {{ get; set; }}");
                }
                else if (ctx.Supports(CSharp6))
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(field))} global::System.Collections.Generic.List<{typeName}> {Escape(name)} {{ get; {(allowSet ? "set; " : "")}}} = new global::System.Collections.Generic.List<{typeName}>();");
                }
                else
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(field))} global::System.Collections.Generic.List<{typeName}> {Escape(name)} {{ get; {(allowSet ? "" : "private ")}set; }}");
                }
            }
            else if (oneOf != null)
            {
                var defValue  = string.IsNullOrWhiteSpace(defaultValue) ? (ctx.Supports(CSharp7_1) ? "default" : $"default({typeName})") : defaultValue;
                var fieldName = GetOneOfFieldName(oneOf.OneOf);
                var storage   = oneOf.GetStorage(field.type, field.TypeName);
                ctx.WriteLine($"{GetAccess(GetAccess(field))} {typeName} {Escape(name)}").WriteLine("{").Indent();

                switch (field.type)
                {
                case FieldDescriptorProto.Type.TypeMessage:
                case FieldDescriptorProto.Type.TypeGroup:
                case FieldDescriptorProto.Type.TypeEnum:
                case FieldDescriptorProto.Type.TypeBytes:
                case FieldDescriptorProto.Type.TypeString:
                    ctx.WriteLine($"get {{ return {fieldName}.Is({field.Number}) ? (({typeName}){fieldName}.{storage}) : {defValue}; }}");
                    break;

                default:
                    ctx.WriteLine($"get {{ return {fieldName}.Is({field.Number}) ? {fieldName}.{storage} : {defValue}; }}");
                    break;
                }
                var unionType = oneOf.GetUnionType();
                var cast      = field.type == FieldDescriptorProto.Type.TypeEnum ? "(int)" : "";
                ctx.WriteLine($"set {{ {fieldName} = new global::ProtoBuf.{unionType}({field.Number}, {cast}value); }}")
                .Outdent().WriteLine("}");

                if (ctx.Supports(CSharp6))
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(field))} bool ShouldSerialize{name}() => {fieldName}.Is({field.Number});")
                    .WriteLine($"{GetAccess(GetAccess(field))} void Reset{name}() => global::ProtoBuf.{unionType}.Reset(ref {fieldName}, {field.Number});");
                }
                else
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(field))} bool ShouldSerialize{name}()").WriteLine("{").Indent()
                    .WriteLine($"return {fieldName}.Is({field.Number});").Outdent().WriteLine("}")
                    .WriteLine($"{GetAccess(GetAccess(field))} void Reset{name}()").WriteLine("{").Indent()
                    .WriteLine($"global::ProtoBuf.{unionType}.Reset(ref {fieldName}, {field.Number});").Outdent().WriteLine("}");
                }

                if (oneOf.IsFirst())
                {
                    ctx.WriteLine().WriteLine($"private global::ProtoBuf.{unionType} {fieldName};");
                }
            }
            else if (explicitValues)
            {
                string fieldName = FieldPrefix + name, fieldType;
                bool   isRef = false;
                switch (field.type)
                {
                case FieldDescriptorProto.Type.TypeString:
                case FieldDescriptorProto.Type.TypeBytes:
                    fieldType = typeName;
                    isRef     = true;
                    break;

                default:
                    fieldType = typeName + "?";
                    break;
                }
                ctx.WriteLine($"{GetAccess(GetAccess(field))} {typeName} {Escape(name)}").WriteLine("{").Indent();
                tw = ctx.Write($"get {{ return {fieldName}");
                if (!string.IsNullOrWhiteSpace(defaultValue))
                {
                    tw.Write(" ?? ");
                    tw.Write(defaultValue);
                }
                else if (!isRef)
                {
                    tw.Write(".GetValueOrDefault()");
                }
                tw.WriteLine("; }");
                ctx.WriteLine($"set {{ {fieldName} = value; }}")
                .Outdent().WriteLine("}");
                if (ctx.Supports(CSharp6))
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(field))} bool ShouldSerialize{name}() => {fieldName} != null;")
                    .WriteLine($"{GetAccess(GetAccess(field))} void Reset{name}() => {fieldName} = null;");
                }
                else
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(field))} bool ShouldSerialize{name}()").WriteLine("{").Indent()
                    .WriteLine($"return {fieldName} != null;").Outdent().WriteLine("}")
                    .WriteLine($"{GetAccess(GetAccess(field))} void Reset{name}()").WriteLine("{").Indent()
                    .WriteLine($"{fieldName} = null;").Outdent().WriteLine("}");
                }
                ctx.WriteLine($"private {fieldType} {fieldName};");
            }
            else
            {
                tw = ctx.Write($"{GetAccess(GetAccess(field))} {typeName} {Escape(name)} {{ get; set; }}");
                if (!string.IsNullOrWhiteSpace(defaultValue) && ctx.Supports(CSharp6))
                {
                    tw.Write($" = {defaultValue};");
                }
                tw.WriteLine();
            }
            ctx.WriteLine();
        }
コード例 #8
0
        private string GetDefaultValue(GeneratorContext ctx, FieldDescriptorProto obj, string typeName)
        {
            string defaultValue = null;
            bool   isOptional   = obj.label == FieldDescriptorProto.Label.LabelOptional;

            if (isOptional || ctx.EmitRequiredDefaults || obj.type == FieldDescriptorProto.Type.TypeEnum)
            {
                defaultValue = obj.DefaultValue;

                if (obj.type == FieldDescriptorProto.Type.TypeString)
                {
                    defaultValue = string.IsNullOrEmpty(defaultValue) ? "\"\""
                        : ("@\"" + (defaultValue ?? "").Replace("\"", "\"\"") + "\"");
                }
                else if (obj.type == FieldDescriptorProto.Type.TypeDouble)
                {
                    switch (defaultValue)
                    {
                    case "inf": defaultValue = "double.PositiveInfinity"; break;

                    case "-inf": defaultValue = "double.NegativeInfinity"; break;

                    case "nan": defaultValue = "double.NaN"; break;
                    }
                }
                else if (obj.type == FieldDescriptorProto.Type.TypeFloat)
                {
                    switch (defaultValue)
                    {
                    case "inf": defaultValue = "float.PositiveInfinity"; break;

                    case "-inf": defaultValue = "float.NegativeInfinity"; break;

                    case "nan": defaultValue = "float.NaN"; break;
                    }
                }
                else if (obj.type == FieldDescriptorProto.Type.TypeEnum)
                {
                    var enumType = ctx.TryFind <EnumDescriptorProto>(obj.TypeName);
                    if (enumType != null)
                    {
                        EnumValueDescriptorProto found = null;
                        if (!string.IsNullOrEmpty(defaultValue))
                        {
                            found = enumType.Values.Find(x => x.Name == defaultValue);
                        }
                        else if (ctx.Syntax == FileDescriptorProto.SyntaxProto2)
                        {
                            // find the first one; if that is a zero, we don't need it after all
                            found = enumType.Values.FirstOrDefault();
                            if (found != null && found.Number == 0)
                            {
                                if (!isOptional)
                                {
                                    found = null;              // we don't need it after all
                                }
                            }
                        }
                        // for proto3 the default is 0, so no need to do anything - GetValueOrDefault() will do it all

                        if (found != null)
                        {
                            defaultValue = ctx.NameNormalizer.GetName(found);
                        }
                        if (!string.IsNullOrWhiteSpace(defaultValue))
                        {
                            defaultValue = typeName + "." + defaultValue;
                        }
                    }
                }
            }

            return(defaultValue);
        }
コード例 #9
0
ファイル: ILCodeGen.cs プロジェクト: uncaha/ProtoToCS
        protected string GetDefaltValue(GeneratorContext ctx, FieldDescriptorProto obj, string _typename)
        {
            string defaultValue = obj.DefaultValue;

            if (obj.type == FieldDescriptorProto.Type.TypeString)
            {
                if (!string.IsNullOrEmpty(defaultValue))
                {
                    defaultValue = '"' + defaultValue + '"';
                }
            }
            else if (obj.type == FieldDescriptorProto.Type.TypeDouble)
            {
                switch (defaultValue)
                {
                case "inf": defaultValue = "double.PositiveInfinity"; break;

                case "-inf": defaultValue = "double.NegativeInfinity"; break;

                case "nan": defaultValue = "double.NaN"; break;

                default:
                    if (!string.IsNullOrEmpty(defaultValue) && !defaultValue.EndsWith("f"))
                    {
                        defaultValue += "f";
                    }
                    break;
                }
            }
            else if (obj.type == FieldDescriptorProto.Type.TypeFloat)
            {
                switch (defaultValue)
                {
                case "inf": defaultValue = "float.PositiveInfinity"; break;

                case "-inf": defaultValue = "float.NegativeInfinity"; break;

                case "nan": defaultValue = "float.NaN"; break;

                default:
                    if (!string.IsNullOrEmpty(defaultValue) && !defaultValue.EndsWith("f"))
                    {
                        defaultValue += "f";
                    }
                    break;
                }
            }
            else if (obj.type == FieldDescriptorProto.Type.TypeMessage)
            {
                defaultValue = $"new {_typename}()";
            }
            else if (obj.type == FieldDescriptorProto.Type.TypeEnum)
            {
                var enumType = ctx.TryFind <EnumDescriptorProto>(obj.TypeName);
                if (enumType != null)
                {
                    EnumValueDescriptorProto found = null;
                    if (!string.IsNullOrEmpty(defaultValue))
                    {
                        found = enumType.Values.FirstOrDefault(x => x.Name == defaultValue);
                    }
                    else if (ctx.Syntax == FileDescriptorProto.SyntaxProto2)
                    {
                        found = enumType.Values.FirstOrDefault();
                    }

                    if (found != null)
                    {
                        // defaultValue = ctx.NameNormalizer.GetName(found);
                        defaultValue = found.Name;
                    }
                    if (!string.IsNullOrEmpty(defaultValue))
                    {
                        var typeName = GetTypeName(ctx, obj, out var dataFormat, out var isMap);
                        defaultValue = typeName + "." + defaultValue;
                    }
                }
            }

            return(defaultValue);
        }
コード例 #10
0
ファイル: ILCodeGen.cs プロジェクト: uncaha/ProtoToCS
        protected void WriteFieldWrite(GeneratorContext ctx, FieldDescriptorProto obj, OneOfStub[] oneOfs)
        {
            bool isOptional = obj.label == FieldDescriptorProto.Label.LabelOptional;
            bool isRepeated = obj.label == FieldDescriptorProto.Label.LabelRepeated;

            Google.Protobuf.WireFormat.WireType ttwtype = ProtoTool.ILHelper.GetWireType(obj.type);
            uint   ttag   = Google.Protobuf.WireFormat.MakeTag(obj.Number, ttwtype);
            string tagstr = $"output.WriteTag({ttag});";

            var typeName = GetTypeName(ctx, obj, out var dataFormat, out var isMap);

            if (isOptional)
            {
                string tifvalue = "";
                if (obj.type == FieldDescriptorProto.Type.TypeString)
                {
                    tifvalue = $"if(!string.IsNullOrEmpty({obj.Name})){"{"}";
                }
                else
                {
                    tifvalue = $"if({obj.Name} != default({typeName})){"{"}";
                }
                ctx.WriteLine(tifvalue).Indent();
                //代码块
                ctx.WriteLine(tagstr);
                ctx.WriteLine(WriteString(obj.type, obj.Name));

                ctx.Outdent();
                ctx.WriteLine($"{"}"}");
            }
            else if (isRepeated)
            {
                var mapMsgType = isMap ? ctx.TryFind <DescriptorProto>(obj.TypeName) : null;
                if (mapMsgType != null)
                {
                    var keyTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 1),
                                                  out var keyDataFormat, out var _);
                    var valueTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 2),
                                                    out var valueDataFormat, out var _);
                    // System.Collections.Generic.Dictionary<int, int> ttt = new Dictionary<int, int>();
                    // System.Collections.Generic.KeyValuePair<int,int> ttt
                    ctx.WriteLine($"if({obj.Name}.Count > 0 ){"{"}").Indent();
                    ctx.WriteLine($"foreach (System.Collections.Generic.KeyValuePair<{keyTypeName}, {valueTypeName}> item in {obj.Name}){"{"}").Indent();

                    ctx.WriteLine(tagstr);
                    ctx.WriteLine(WriteString(mapMsgType.Fields[0].type, "item.Key"));
                    ctx.WriteLine(WriteString(mapMsgType.Fields[1].type, "item.Value"));

                    ctx.Outdent().WriteLine("}");
                    ctx.Outdent().WriteLine("}");
                }
                else
                {
                    ctx.WriteLine($"if({obj.Name}.Count > 0 ){"{"}").Indent();
                    ctx.WriteLine($"for (int i = 0; i < {obj.Name}.Count; i++){"{"}").Indent();

                    ctx.WriteLine(tagstr);
                    ctx.WriteLine(WriteString(obj.type, obj.Name + "[i]"));

                    ctx.Outdent().WriteLine("}");

                    ctx.Outdent().WriteLine("}");
                }
            }
            else
            {
                ctx.WriteLine(tagstr);
                ctx.WriteLine(WriteString(obj.type, obj.Name));
            }
        }
コード例 #11
0
        protected override void WriteFile(GeneratorContext ctx, FileDescriptorProto obj)
        {
            var file = ctx.File;

            var ast = new ProtoFile
            {
                Filename    = file.Name,
                PackageName = file.Package,
                CsNamespace = file.Options?.CsharpNamespace ?? file.Package,
                Messages    = file
                              .MessageTypes
                              .ToArray()
                              .Select(mt => new ProtoMessage
                {
                    Name   = mt.Name,
                    Fields = mt.Fields.Select(f => new ProtoField()
                    {
                        TypeName   = f.TypeName,
                        Name       = f.Name,
                        Number     = f.Number,
                        IsRepeated = f.label == FieldDescriptorProto.Label.LabelRepeated,
                        OneOfIndex = f.OneofIndex,
                        Type       = f.type,
                        Object     = ctx.TryFind <DescriptorProto>(f.TypeName),
                    }).ToArray()
                })
                              .ToArray(),
                Services = file
                           .Services
                           .ToArray()
                           .Select(
                    s => new ProtoService
                {
                    Name    = s.Name,
                    Methods = s.Methods.ToArray()
                              .Select(
                        (m, i) => new ProtoMethod
                    {
                        Index         = i,
                        Name          = m.Name,
                        InputNameRaw  = RemovePackageName(m.InputType),
                        OutputNameRaw = RemovePackageName(m.OutputType),
                        InputObject   = ctx.TryFind <DescriptorProto>(m.InputType),
                        OutputObject  = ctx.TryFind <DescriptorProto>(m.OutputType),
                    }
                        )
                              .ToArray()
                }
                    )
                           .ToArray()
            };

            Handlebars.RegisterHelper("StringEquality", (output, options, context, arguments) =>
            {
                if (arguments.Length != 2)
                {
                    throw new HandlebarsException("{{#StringEquality}} helper must have exactly two arguments");
                }

                var left  = arguments.At <string>(0);
                var right = arguments[1] as string;
                if (left == right)
                {
                    options.Template(output, context);
                }
                else
                {
                    options.Inverse(output, context);
                }
            });

            var f = Handlebars.Compile(_template);

            var result = f(ast);

            ctx.WriteLine(result);
コード例 #12
0
        private string GetTypeName(GeneratorContext ctx, FieldDescriptorProto field, out string dataFormat, out bool isMap,
                                   bool nonNullable = false)
        {
            dataFormat = "";
            isMap      = false;
            switch (field.type)
            {
            case FieldDescriptorProto.Type.TypeDouble:
                return("double");

            case FieldDescriptorProto.Type.TypeFloat:
                return("float");

            case FieldDescriptorProto.Type.TypeBool:
                return("bool");

            case FieldDescriptorProto.Type.TypeString:
                return("string");

            case FieldDescriptorProto.Type.TypeSint32:
                dataFormat = nameof(DataFormat.ZigZag);
                return("int");

            case FieldDescriptorProto.Type.TypeInt32:
                return("int");

            case FieldDescriptorProto.Type.TypeSfixed32:
                dataFormat = nameof(DataFormat.FixedSize);
                return("int");

            case FieldDescriptorProto.Type.TypeSint64:
                dataFormat = nameof(DataFormat.ZigZag);
                return("long");

            case FieldDescriptorProto.Type.TypeInt64:
                return("long");

            case FieldDescriptorProto.Type.TypeSfixed64:
                dataFormat = nameof(DataFormat.FixedSize);
                return("long");

            case FieldDescriptorProto.Type.TypeFixed32:
                dataFormat = nameof(DataFormat.FixedSize);
                return("uint");

            case FieldDescriptorProto.Type.TypeUint32:
                return("uint");

            case FieldDescriptorProto.Type.TypeFixed64:
                dataFormat = nameof(DataFormat.FixedSize);
                return("ulong");

            case FieldDescriptorProto.Type.TypeUint64:
                return("ulong");

            case FieldDescriptorProto.Type.TypeBytes:
                return("byte[]");

            case FieldDescriptorProto.Type.TypeEnum:
                switch (field.TypeName)
                {
                case ".bcl.DateTime.DateTimeKind":
                    return("global::System.DateTimeKind");
                }
                var enumType = ctx.TryFind <EnumDescriptorProto>(field.TypeName);
                return(MakeRelativeName(field, enumType, ctx.NameNormalizer));

            case FieldDescriptorProto.Type.TypeGroup:
            case FieldDescriptorProto.Type.TypeMessage:
                return(GetTypeName(ctx, field, field.TypeName, ref dataFormat, ref isMap, nonNullable));

            default:
                return(field.TypeName);
            }
        }
コード例 #13
0
        /// <summary>
        /// Write a field
        /// </summary>
        protected override void WriteField(GeneratorContext ctx, FieldDescriptorProto obj, ref object state, OneOfStub[] oneOfs)
        {
            var name = ctx.NameNormalizer.GetName(obj);
            var tw   = ctx.Write($@"[global::ProtoBuf.ProtoMember({obj.Number}");

            if (name != obj.Name)
            {
                tw.Write($@", Name = @""{obj.Name}""");
            }
            var options = obj.Options?.GetOptions();

            if (options?.AsReference == true)
            {
                tw.Write($@", AsReference = true");
            }
            if (options?.DynamicType == true)
            {
                tw.Write($@", DynamicType = true");
            }

            bool isOptional = obj.label == FieldDescriptorProto.Label.LabelOptional;
            bool isRepeated = obj.label == FieldDescriptorProto.Label.LabelRepeated;

            OneOfStub oneOf = obj.ShouldSerializeOneofIndex() ? oneOfs?[obj.OneofIndex] : null;

            if (oneOf != null && oneOf.CountTotal == 1)
            {
                oneOf = null; // not really a one-of, then!
            }
            bool explicitValues = isOptional && oneOf == null && ctx.Syntax == FileDescriptorProto.SyntaxProto2 &&
                                  obj.type != FieldDescriptorProto.Type.TypeMessage &&
                                  obj.type != FieldDescriptorProto.Type.TypeGroup;


            string defaultValue             = null;
            bool   suppressDefaultAttribute = !isOptional;

            if (isOptional || obj.type == FieldDescriptorProto.Type.TypeEnum)
            {
                defaultValue = obj.DefaultValue;

                if (obj.type == FieldDescriptorProto.Type.TypeString)
                {
                    defaultValue = string.IsNullOrEmpty(defaultValue) ? "\"\""
                        : ("@\"" + (defaultValue ?? "").Replace("\"", "\"\"") + "\"");
                }
                else if (obj.type == FieldDescriptorProto.Type.TypeDouble)
                {
                    switch (defaultValue)
                    {
                    case "inf": defaultValue = "double.PositiveInfinity"; break;

                    case "-inf": defaultValue = "double.NegativeInfinity"; break;

                    case "nan": defaultValue = "double.NaN"; break;
                    }
                }
                else if (obj.type == FieldDescriptorProto.Type.TypeFloat)
                {
                    switch (defaultValue)
                    {
                    case "inf": defaultValue = "float.PositiveInfinity"; break;

                    case "-inf": defaultValue = "float.NegativeInfinity"; break;

                    case "nan": defaultValue = "float.NaN"; break;
                    }
                }
                else if (obj.type == FieldDescriptorProto.Type.TypeEnum)
                {
                    var enumType = ctx.TryFind <EnumDescriptorProto>(obj.TypeName);
                    if (enumType != null)
                    {
                        EnumValueDescriptorProto found = null;
                        if (!string.IsNullOrEmpty(defaultValue))
                        {
                            found = enumType.Values.FirstOrDefault(x => x.Name == defaultValue);
                        }
                        else if (ctx.Syntax == FileDescriptorProto.SyntaxProto2)
                        {
                            // find the first one; if that is a zero, we don't need it after all
                            found = enumType.Values.FirstOrDefault();
                            if (found != null && found.Number == 0)
                            {
                                if (!isOptional)
                                {
                                    found = null;             // we don't need it after all
                                }
                            }
                        }
                        // for proto3 the default is 0, so no need to do anything - GetValueOrDefault() will do it all

                        if (found != null)
                        {
                            defaultValue = ctx.NameNormalizer.GetName(found);
                        }
                        if (!string.IsNullOrWhiteSpace(defaultValue))
                        {
                            defaultValue = ctx.NameNormalizer.GetName(enumType) + "." + defaultValue;
                        }
                    }
                }
            }
            var typeName = GetTypeName(ctx, obj, out var dataFormat, out var isMap);

            if (!string.IsNullOrWhiteSpace(dataFormat))
            {
                tw.Write($", DataFormat = global::ProtoBuf.DataFormat.{dataFormat}");
            }
            if (obj.IsPacked(ctx.Syntax))
            {
                tw.Write($", IsPacked = true");
            }
            if (obj.label == FieldDescriptorProto.Label.LabelRequired)
            {
                tw.Write($", IsRequired = true");
            }
            tw.WriteLine(")]");
            if (!isRepeated && !string.IsNullOrWhiteSpace(defaultValue) && !suppressDefaultAttribute)
            {
                ctx.WriteLine($"[global::System.ComponentModel.DefaultValue({defaultValue})]");
            }
            WriteOptions(ctx, obj.Options);
            if (isRepeated)
            {
                var mapMsgType = isMap ? ctx.TryFind <DescriptorProto>(obj.TypeName) : null;
                if (mapMsgType != null)
                {
                    var keyTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 1),
                                                  out var keyDataFormat, out var _);
                    var valueTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 2),
                                                    out var valueDataFormat, out var _);

                    bool first = true;
                    tw = ctx.Write($"[global::ProtoBuf.ProtoMap");
                    if (!string.IsNullOrWhiteSpace(keyDataFormat))
                    {
                        tw.Write($"{(first ? "(" : ", ")}KeyFormat = global::ProtoBuf.DataFormat.{keyDataFormat}");
                        first = false;
                    }
                    if (!string.IsNullOrWhiteSpace(valueDataFormat))
                    {
                        tw.Write($"{(first ? "(" : ", ")}ValueFormat = global::ProtoBuf.DataFormat.{valueDataFormat}");
                        first = false;
                    }
                    tw.WriteLine(first ? "]" : ")]");
                    ctx.WriteLine($"{GetAccess(GetAccess(obj))} global::System.Collections.Generic.Dictionary<{keyTypeName}, {valueTypeName}> {Escape(name)} {{ get; }} = new global::System.Collections.Generic.Dictionary<{keyTypeName}, {valueTypeName}>();");
                }
                else if (UseArray(obj))
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(obj))} {typeName}[] {Escape(name)} {{ get; set; }}");
                }
                else
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(obj))} global::System.Collections.Generic.List<{typeName}> {Escape(name)} {{ get; }} = new global::System.Collections.Generic.List<{typeName}>();");
                }
            }
            else if (oneOf != null)
            {
                var defValue  = string.IsNullOrWhiteSpace(defaultValue) ? $"default({typeName})" : defaultValue;
                var fieldName = FieldPrefix + oneOf.OneOf.Name;
                var storage   = oneOf.GetStorage(obj.type, obj.TypeName);
                ctx.WriteLine($"{GetAccess(GetAccess(obj))} {typeName} {Escape(name)}").WriteLine("{").Indent();

                switch (obj.type)
                {
                case FieldDescriptorProto.Type.TypeMessage:
                case FieldDescriptorProto.Type.TypeGroup:
                case FieldDescriptorProto.Type.TypeEnum:
                case FieldDescriptorProto.Type.TypeBytes:
                case FieldDescriptorProto.Type.TypeString:
                    ctx.WriteLine($"get {{ return {fieldName}.Is({obj.Number}) ? (({typeName}){fieldName}.{storage}) : {defValue}; }}");
                    break;

                default:
                    ctx.WriteLine($"get {{ return {fieldName}.Is({obj.Number}) ? {fieldName}.{storage} : {defValue}; }}");
                    break;
                }
                var unionType = oneOf.GetUnionType();
                ctx.WriteLine($"set {{ {fieldName} = new global::ProtoBuf.{unionType}({obj.Number}, value); }}")
                .Outdent().WriteLine("}")
                .WriteLine($"{GetAccess(GetAccess(obj))} bool ShouldSerialize{name}() => {fieldName}.Is({obj.Number});")
                .WriteLine($"{GetAccess(GetAccess(obj))} void Reset{name}() => global::ProtoBuf.{unionType}.Reset(ref {fieldName}, {obj.Number});");

                if (oneOf.IsFirst())
                {
                    ctx.WriteLine().WriteLine($"private global::ProtoBuf.{unionType} {fieldName};");
                }
            }
            else if (explicitValues)
            {
                string fieldName = FieldPrefix + name, fieldType;
                bool   isRef = false;
                switch (obj.type)
                {
                case FieldDescriptorProto.Type.TypeString:
                case FieldDescriptorProto.Type.TypeBytes:
                    fieldType = typeName;
                    isRef     = true;
                    break;

                default:
                    fieldType = typeName + "?";
                    break;
                }
                ctx.WriteLine($"{GetAccess(GetAccess(obj))} {typeName} {Escape(name)}").WriteLine("{").Indent();
                tw = ctx.Write($"get {{ return {fieldName}");
                if (!string.IsNullOrWhiteSpace(defaultValue))
                {
                    tw.Write(" ?? ");
                    tw.Write(defaultValue);
                }
                else if (!isRef)
                {
                    tw.Write(".GetValueOrDefault()");
                }
                tw.WriteLine("; }");
                ctx.WriteLine($"set {{ {fieldName} = value; }}")
                .Outdent().WriteLine("}")
                .WriteLine($"{GetAccess(GetAccess(obj))} bool ShouldSerialize{name}() => {fieldName} != null;")
                .WriteLine($"{GetAccess(GetAccess(obj))} void Reset{name}() => {fieldName} = null;")
                .WriteLine($"private {fieldType} {fieldName};");
            }
            else
            {
                tw = ctx.Write($"{GetAccess(GetAccess(obj))} {typeName} {Escape(name)} {{ get; set; }}");
                if (!string.IsNullOrWhiteSpace(defaultValue))
                {
                    tw.Write($" = {defaultValue};");
                }
                tw.WriteLine();
            }
            ctx.WriteLine();
        }
コード例 #14
0
        /// <summary>
        /// Write a field
        /// </summary>
        protected override void WriteField(GeneratorContext ctx, FieldDescriptorProto field, ref object state, OneOfStub[] oneOfs)
        {
            var name = ctx.NameNormalizer.GetName(field);

            var tw = ctx.Write($"<Global.ProtoBuf.ProtoMember({field.Number}");

            if (name != field.Name)
            {
                tw.Write($@", Name := ""{field.Name}""");
            }
            var options = field.Options?.GetOptions();

            if (options?.AsReference == true)
            {
                tw.Write(", AsReference := True");
            }
            if (options?.DynamicType == true)
            {
                tw.Write(", DynamicType := True");
            }

            bool isOptional = field.label == FieldDescriptorProto.Label.LabelOptional;
            bool isRepeated = field.label == FieldDescriptorProto.Label.LabelRepeated;

            OneOfStub oneOf = field.ShouldSerializeOneofIndex() ? oneOfs?[field.OneofIndex] : null;

            if (oneOf != null && !ctx.OneOfEnums && oneOf.CountTotal == 1)
            {
                oneOf = null; // not really a one-of, then!
            }
            bool explicitValues = isOptional && oneOf == null && ctx.Syntax == FileDescriptorProto.SyntaxProto2 &&
                                  field.type != FieldDescriptorProto.Type.TypeMessage &&
                                  field.type != FieldDescriptorProto.Type.TypeGroup;

            bool suppressDefaultAttribute = !isOptional;
            var  typeName = GetTypeName(ctx, field, out var dataFormat, out var isMap);

            string defaultValue = GetDefaultValue(ctx, field, typeName);

            if (!string.IsNullOrWhiteSpace(dataFormat))
            {
                tw.Write($", DataFormat := Global.ProtoBuf.DataFormat.{dataFormat}");
            }
            if (field.IsPacked(ctx.Syntax))
            {
                tw.Write($", IsPacked := True");
            }
            if (field.label == FieldDescriptorProto.Label.LabelRequired)
            {
                tw.Write($", IsRequired := True");
            }
            tw.WriteLine(")> _");
            if (!isRepeated && !string.IsNullOrWhiteSpace(defaultValue) && !suppressDefaultAttribute)
            {
                ctx.WriteLine($"<Global.System.ComponentModel.DefaultValue({defaultValue})> _");
            }
            WriteOptions(ctx, field.Options);
            if (isRepeated)
            {
                var mapMsgType = isMap ? ctx.TryFind <DescriptorProto>(field.TypeName) : null;
                if (mapMsgType != null)
                {
                    var keyTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 1),
                                                  out var keyDataFormat, out var _);
                    var valueTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 2),
                                                    out var valueDataFormat, out var _);

                    bool first = true;
                    tw = ctx.Write($"<Global.ProtoBuf.ProtoMap");
                    if (!string.IsNullOrWhiteSpace(keyDataFormat))
                    {
                        tw.Write($"{(first ? "(" : ", ")}KeyFormat := Global.ProtoBuf.DataFormat.{keyDataFormat}");
                        first = false;
                    }
                    if (!string.IsNullOrWhiteSpace(valueDataFormat))
                    {
                        tw.Write($"{(first ? "(" : ", ")}ValueFormat := Global.ProtoBuf.DataFormat.{valueDataFormat}");
                        first = false;
                    }
                    tw.WriteLine(first ? "> _" : ")> _");

                    if (ctx.Supports(VB14))
                    {
                        ctx.WriteLine($"{GetAccess(GetAccess(field))} Readonly Property {Escape(name)} As New Global.System.Collections.Generic.Dictionary(Of {keyTypeName}, {valueTypeName})");
                    }
                    else
                    {
                        var fieldName = FieldPrefix + name;
                        ctx.WriteLine($"{GetAccess(GetAccess(field))} Readonly Property {Escape(name)} As Global.System.Collections.Generic.Dictionary(Of {keyTypeName}, {valueTypeName})").Indent()
                        .WriteLine("Get").Indent()
                        .WriteLine($"Return {fieldName}")
                        .Outdent().WriteLine("End Get").Outdent().WriteLine("End Property").WriteLine()
                        .WriteLine($"Private ReadOnly {fieldName} As New Global.System.Collections.Generic.Dictionary(Of {keyTypeName}, {valueTypeName})").WriteLine();
                    }
                }
                else if (UseArray(field))
                {
                    if (ctx.Supports(VB11))
                    {
                        ctx.WriteLine($"{GetAccess(GetAccess(field))} Property {Escape(name)} As {typeName}()");
                    }
                    else
                    {
                        var fieldName = FieldPrefix + name;
                        ctx.WriteLine($"{GetAccess(GetAccess(field))} Property {Escape(name)} As {typeName}()")
                        .Indent().WriteLine("Get").Indent().WriteLine($"Return {fieldName}").Outdent().WriteLine("End Get").Outdent()
                        .Indent().WriteLine($"Set(ByVal value as {typeName}())").Indent().WriteLine($"{fieldName} = value").Outdent().WriteLine("End Set").Outdent()
                        .WriteLine("End Property").WriteLine()
                        .WriteLine($"Private {fieldName} As {typeName}()").WriteLine();
                    }
                }
                else
                {
                    if (ctx.Supports(VB14))
                    {
                        ctx.WriteLine($"{GetAccess(GetAccess(field))} Readonly Property {Escape(name)} As New Global.System.Collections.Generic.List(Of {typeName})");
                    }
                    else
                    {
                        var fieldName = FieldPrefix + name;
                        ctx.WriteLine($"{GetAccess(GetAccess(field))} Readonly Property {Escape(name)} As Global.System.Collections.Generic.List(Of {typeName})").Indent()
                        .WriteLine("Get").Indent()
                        .WriteLine($"Return {fieldName}")
                        .Outdent().WriteLine("End Get").Outdent().WriteLine("End Property").WriteLine()
                        .WriteLine($"Private ReadOnly {fieldName} As New Global.System.Collections.Generic.List(Of {typeName})").WriteLine();
                    }
                }
            }
            else if (oneOf != null)
            {
                var defValue  = string.IsNullOrWhiteSpace(defaultValue) ? $"CType(Nothing, {typeName})" : defaultValue;
                var fieldName = GetOneOfFieldName(oneOf.OneOf);
                var storage   = oneOf.GetStorage(field.type, field.TypeName);
                ctx.WriteLine($"{GetAccess(GetAccess(field))} Property {Escape(name)} As {typeName}").Indent().WriteLine("Get").Indent();
                switch (field.type)
                {
                case FieldDescriptorProto.Type.TypeMessage:
                case FieldDescriptorProto.Type.TypeGroup:
                case FieldDescriptorProto.Type.TypeEnum:
                case FieldDescriptorProto.Type.TypeBytes:
                case FieldDescriptorProto.Type.TypeString:
                    ctx.WriteLine($"Return If({fieldName}.Is({field.Number}), CType({fieldName}.{storage}, {typeName}), {defValue})");
                    break;

                default:
                    ctx.WriteLine($"Return If({fieldName}.Is({field.Number}), {fieldName}.{storage}, {defValue})");
                    break;
                }
                ctx.Outdent().WriteLine("End Get");

                var unionType = oneOf.GetUnionType();

                ctx.WriteLine($"Set(ByVal value As {typeName})").Indent()
                .WriteLine($"{fieldName} = New Global.ProtoBuf.{unionType}({field.Number}, value)").Outdent().WriteLine("End Set");

                ctx.Outdent().WriteLine("End Property").WriteLine();

                ctx.WriteLine($"{GetAccess(GetAccess(field))} Function ShouldSerialize{name}() As Boolean").Indent()
                .WriteLine($"Return {fieldName}.Is({field.Number})").Outdent()
                .WriteLine("End Function").WriteLine()
                .WriteLine($"{GetAccess(GetAccess(field))} Sub Reset{name}()").Indent()
                .WriteLine($"Global.ProtoBuf.{unionType}.Reset({fieldName}, {field.Number})")
                .Outdent().WriteLine("End Sub");

                if (oneOf.IsFirst())
                {
                    ctx.WriteLine().WriteLine($"Private {fieldName} As Global.ProtoBuf.{unionType}");
                }
            }
            else if (explicitValues)
            {
                string fieldName = FieldPrefix + name, fieldType;
                bool   isRef = false;
                switch (field.type)
                {
                case FieldDescriptorProto.Type.TypeString:
                case FieldDescriptorProto.Type.TypeBytes:
                    fieldType = typeName;
                    isRef     = true;
                    break;

                default:
                    fieldType = typeName + "?";
                    break;
                }

                ctx.WriteLine($"{GetAccess(GetAccess(field))} Property {Escape(name)} As {typeName}").Indent()
                .WriteLine("Get").Indent();

                if (!string.IsNullOrWhiteSpace(defaultValue))
                {
                    ctx.WriteLine($"Return If({fieldName}, {defaultValue})");
                }
                else if (!isRef)
                {
                    ctx.WriteLine($"Return {fieldName}.GetValueOrDefault()");
                }
                else
                {
                    ctx.WriteLine($"Return {fieldName}");
                }

                ctx.Outdent().WriteLine("End Get").WriteLine($"Set(ByVal value As {typeName})").Indent()
                .WriteLine($"{fieldName} = value").Outdent().WriteLine("End Set").
                Outdent().WriteLine("End Property");

                ctx.WriteLine($"{GetAccess(GetAccess(field))} Function ShouldSerialize{name}() As Boolean").Indent()
                .WriteLine($"Return Not ({fieldName} Is Nothing)").Outdent()
                .WriteLine("End Function")
                .WriteLine($"{GetAccess(GetAccess(field))} Sub Reset{name}()").Indent()
                .WriteLine($"{fieldName} = Nothing").Outdent().WriteLine("End Sub");

                ctx.WriteLine($"Private {fieldName} As {fieldType}");
            }
            else
            {
                if (ctx.Supports(VB11))
                {
                    tw = ctx.Write($"{GetAccess(GetAccess(field))} Property {Escape(name)} As {typeName}");
                    if (!string.IsNullOrWhiteSpace(defaultValue))
                    {
                        tw.Write($" = {defaultValue}");
                    }
                    tw.WriteLine();
                }
                else
                {
                    var fieldName = FieldPrefix + name;
                    tw = ctx.WriteLine($"{GetAccess(GetAccess(field))} Property {Escape(name)} As {typeName}")
                         .Indent().WriteLine("Get").Indent().WriteLine($"Return {fieldName}").Outdent().WriteLine("End Get").Outdent()
                         .Indent().WriteLine($"Set(ByVal value as {typeName})").Indent().WriteLine($"{fieldName} = value").Outdent().WriteLine("End Set").Outdent()
                         .WriteLine("End Property").WriteLine()
                         .Write($"Private {fieldName} As {typeName}");
                    if (!string.IsNullOrWhiteSpace(defaultValue))
                    {
                        tw.Write($" = {defaultValue}");
                    }
                    tw.WriteLine();
                }
            }
            ctx.WriteLine();
        }
コード例 #15
0
        /// <summary>
        /// Write an extension
        /// </summary>
        protected override void WriteExtension(GeneratorContext ctx, FieldDescriptorProto field)
        {
            var type            = GetTypeName(ctx, field, out string dataFormat, out bool isMap, false);
            var nonNullableType = GetTypeName(ctx, field, out _, out _, true);
            var msg             = ctx.TryFind <DescriptorProto>(field.Extendee);
            var extendee        = MakeRelativeName(field, msg, ctx.NameNormalizer);

            var        @this = field.Parent is FileDescriptorProto ? "this " : "";
            string     name  = ctx.NameNormalizer.GetName(field);
            TextWriter tw;

            if (isMap)
            {
                ctx.WriteLine("#error map extensions not yet implemented; please file an issue");
            }
            else
            {
                bool isRepeated = field.label == FieldDescriptorProto.Label.LabelRepeated;

                var getMethodName = isRepeated ? nameof(Extensible.GetValues) : nameof(Extensible.GetValue);
                if (isRepeated)
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(field))} static global::System.Collections.Generic.IEnumerable<{nonNullableType}> Get{name}({@this}{extendee} obj)");
                }
                else
                {
                    ctx.WriteLine($"{GetAccess(GetAccess(field))} static {type} Get{name}({@this}{extendee} obj)");
                }
                if (ctx.Supports(CSharp6))
                {
                    tw = ctx.Indent().Write($"=> ");
                }
                else
                {
                    ctx.WriteLine("{").Indent();
                    tw = ctx.Write("return ");
                }
                var defaultValue = isRepeated ? "null" : ctx.Supports(CSharp7_1) ? "default" : $"default({type})";
                tw.Write($"obj == null ? {defaultValue} : global::ProtoBuf.Extensible.{getMethodName}<{(isRepeated ? nonNullableType : type)}>(obj, {field.Number}");
                if (!string.IsNullOrEmpty(dataFormat))
                {
                    tw.Write($", global::ProtoBuf.DataFormat.{dataFormat}");
                }
                tw.WriteLine(");");
                if (ctx.Supports(CSharp6))
                {
                    ctx.Outdent().WriteLine();
                }
                else
                {
                    ctx.Outdent().WriteLine("}").WriteLine();
                }

                var setAccessorName = isRepeated ? "Add" : "Set";
                ctx.WriteLine($"{GetAccess(GetAccess(field))} static void {setAccessorName}{name}({@this}{extendee} obj, {nonNullableType} value)");
                if (ctx.Supports(CSharp6))
                {
                    tw = ctx.Indent().Write($"=> ");
                }
                else
                {
                    ctx.WriteLine("{").Indent();
                    tw = ctx.Write("");
                }
                tw.Write($"global::ProtoBuf.Extensible.AppendValue<{nonNullableType}>(obj, {field.Number}");
                if (!string.IsNullOrEmpty(dataFormat))
                {
                    tw.Write($", global::ProtoBuf.DataFormat.{dataFormat}");
                }
                tw.WriteLine(", value);");
                if (ctx.Supports(CSharp6))
                {
                    ctx.Outdent().WriteLine();
                }
                else
                {
                    ctx.Outdent().WriteLine("}").WriteLine();
                }
            }
        }
コード例 #16
0
        private string GetTypeName(GeneratorContext ctx, FieldDescriptorProto field, out string dataFormat, out bool isMap,
                                   bool nonNullable = false)
        {
            dataFormat = "";
            isMap      = false;
            switch (field.type)
            {
            case FieldDescriptorProto.Type.TypeDouble:
                return("double");

            case FieldDescriptorProto.Type.TypeFloat:
                return("float");

            case FieldDescriptorProto.Type.TypeBool:
                return("bool");

            case FieldDescriptorProto.Type.TypeString:
                return("string");

            case FieldDescriptorProto.Type.TypeSint32:
                dataFormat = nameof(DataFormat.ZigZag);
                return("int");

            case FieldDescriptorProto.Type.TypeInt32:
                return("int");

            case FieldDescriptorProto.Type.TypeSfixed32:
                dataFormat = nameof(DataFormat.FixedSize);
                return("int");

            case FieldDescriptorProto.Type.TypeSint64:
                dataFormat = nameof(DataFormat.ZigZag);
                return("long");

            case FieldDescriptorProto.Type.TypeInt64:
                return("long");

            case FieldDescriptorProto.Type.TypeSfixed64:
                dataFormat = nameof(DataFormat.FixedSize);
                return("long");

            case FieldDescriptorProto.Type.TypeFixed32:
                dataFormat = nameof(DataFormat.FixedSize);
                return("uint");

            case FieldDescriptorProto.Type.TypeUint32:
                return("uint");

            case FieldDescriptorProto.Type.TypeFixed64:
                dataFormat = nameof(DataFormat.FixedSize);
                return("ulong");

            case FieldDescriptorProto.Type.TypeUint64:
                return("ulong");

            case FieldDescriptorProto.Type.TypeBytes:
                return("byte[]");

            case FieldDescriptorProto.Type.TypeEnum:
                switch (field.TypeName)
                {
                case ".bcl.DateTime.DateTimeKind":
                    return("global::System.DateTimeKind");
                }
                var enumType = ctx.TryFind <EnumDescriptorProto>(field.TypeName);
                return(MakeRelativeName(field, enumType, ctx.NameNormalizer));

            case FieldDescriptorProto.Type.TypeGroup:
            case FieldDescriptorProto.Type.TypeMessage:
                switch (field.TypeName)
                {
                case WellKnownTypeTimestamp:
                    dataFormat = "WellKnown";
                    return(nonNullable ? "global::System.DateTime" : "global::System.DateTime?");

                case WellKnownTypeDuration:
                    dataFormat = "WellKnown";
                    return(nonNullable ? "global::System.TimeSpan" : "global::System.TimeSpan?");

                case ".bcl.NetObjectProxy":
                    return("object");

                case ".bcl.DateTime":
                    return(nonNullable ? "global::System.DateTime" : "global::System.DateTime?");

                case ".bcl.TimeSpan":
                    return(nonNullable ? "global::System.TimeSpan" : "global::System.TimeSpan?");

                case ".bcl.Decimal":
                    return(nonNullable ? "decimal" : "decimal?");

                case ".bcl.Guid":
                    return(nonNullable ? "global::System.Guid" : "global::System.Guid?");
                }
                var msgType = ctx.TryFind <DescriptorProto>(field.TypeName);
                if (field.type == FieldDescriptorProto.Type.TypeGroup)
                {
                    dataFormat = nameof(DataFormat.Group);
                }
                isMap = msgType?.Options?.MapEntry ?? false;
                return(MakeRelativeName(field, msgType, ctx.NameNormalizer));

            default:
                return(field.TypeName);
            }
        }
コード例 #17
0
ファイル: ILCodeGen.cs プロジェクト: uncaha/ProtoToCS
        protected void ReaderString(GeneratorContext ctx, FieldDescriptorProto obj)
        {
            bool isRepeated = obj.label == FieldDescriptorProto.Label.LabelRepeated;
            var  typeName   = GetTypeName(ctx, obj, out var dataFormat, out var isMap);

            string tfirstvalue = obj.Name;

            if (isRepeated)
            {
                tfirstvalue = $"{typeName} tvalue";
                ctx.WriteLine("{").Indent();
            }

            ReadBaseDataStr(ctx, obj.type, tfirstvalue, typeName);

            if (isRepeated)
            {
                var mapMsgType = isMap ? ctx.TryFind <DescriptorProto>(obj.TypeName) : null;
                if (mapMsgType != null)
                {
                    var keyTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 1),
                                                  out var keyDataFormat, out var _);
                    var valueTypeName = GetTypeName(ctx, mapMsgType.Fields.Single(x => x.Number == 2),
                                                    out var valueDataFormat, out var _);

                    string tkey = "tkey";
                    if (FieldDescriptorProto.Type.TypeMessage == mapMsgType.Fields[0].type)
                    {
                        ReadCreatObjectStr(ctx, keyTypeName, tkey);
                    }
                    else
                    {
                        ReadBaseDataStr(ctx, mapMsgType.Fields[0].type, $"{keyTypeName} {tkey}", keyTypeName);
                    }

                    string tvalue = "tvalue";
                    if (FieldDescriptorProto.Type.TypeMessage == mapMsgType.Fields[1].type)
                    {
                        ReadCreatObjectStr(ctx, valueTypeName, tvalue);
                    }
                    else
                    {
                        ReadBaseDataStr(ctx, mapMsgType.Fields[1].type, $"{valueTypeName} {tvalue}", valueTypeName);
                    }

                    ctx.WriteLine($"{obj.Name}.Add({tkey}, {tvalue});");
                }
                else
                {
                    if (FieldDescriptorProto.Type.TypeMessage == obj.type)
                    {
                        ReadCreatObjectStr(ctx, typeName, "tobj");
                        ctx.WriteLine($"{obj.Name}.Add(tobj);");
                    }
                    else
                    {
                        ctx.WriteLine($"{obj.Name}.Add(tvalue);");
                    }
                }
                ctx.Outdent().WriteLine("}");
            }
            else
            {
                switch (obj.type)
                {
                case FieldDescriptorProto.Type.TypeMessage:
                    ctx.WriteLine("{").Indent();
                    ctx.WriteLine($"byte[] tchildbuffer = input.ReadBytes().ToByteArray();");
                    ctx.WriteLine($"{tfirstvalue}.MergeFrom(tchildbuffer);");
                    ctx.Outdent().WriteLine("}");
                    break;
                }
            }
        }