/// <summary> /// Start a file /// </summary> protected override void WriteFileHeader(GeneratorContext ctx, FileDescriptorProto file, ref object state) { var prefix = ctx.Supports(CSharp6) ? "CS" : ""; var tw = ctx.WriteLine("// <auto-generated>") .WriteLine("// This file was generated by a tool; you should avoid making direct changes.") .WriteLine("// Consider using 'partial classes' to extend these types") .WriteLine($"// Input: {Path.GetFileName(ctx.File.Name)}") .WriteLine("// </auto-generated>") .WriteLine() .WriteLine("#region Designer generated code") .Write($"#pragma warning disable {prefix}0612, {prefix}1591, {prefix}3021"); if (ctx.Supports(CSharp6)) { tw.Write(AdditionalSuppressionCodes); } tw.WriteLine(); var @namespace = ctx.NameNormalizer.GetName(file); if (!string.IsNullOrWhiteSpace(@namespace)) { state = @namespace; ctx.WriteLine($"namespace {@namespace}"); ctx.WriteLine("{").Indent().WriteLine(); } }
/// <summary> /// End a file /// </summary> protected override void WriteFileFooter(GeneratorContext ctx, FileDescriptorProto file, ref object state) { var prefix = ctx.Supports(CSharp6) ? "CS" : ""; var tw = ctx.Write($"#pragma warning restore {prefix}0612, {prefix}0618, {prefix}1591, {prefix}3021"); if (ctx.Supports(CSharp6)) { tw.Write(AdditionalSuppressionCodes); } tw.WriteLine(); tw.WriteLine("#endregion"); }
/// <summary> /// Write an extension /// </summary> protected override void WriteExtension(GeneratorContext ctx, FieldDescriptorProto field) { string dataFormat; bool isMap; var type = GetTypeName(ctx, field, out dataFormat, out 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 = ctx.NameNormalizer.GetName(field); ctx.WriteLine($"{GetAccess(GetAccess(field))} static {type} Get{name}({@this}{extendee} obj)"); TextWriter tw; if (ctx.Supports(CSharp6)) { tw = ctx.Indent().Write($"=> "); } else { ctx.WriteLine("{").Indent(); tw = ctx.Write("return "); } tw.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(");"); if (ctx.Supports(CSharp6)) { ctx.Outdent().WriteLine(); } else { ctx.Outdent().WriteLine("}").WriteLine(); } // GetValue<TValue>(IExtensible instance, int tag, DataFormat format) } }
/// <summary> /// Emit code terminating a constructor, if one is required /// </summary> protected override void WriteConstructorFooter(GeneratorContext ctx, DescriptorProto message, ref object state) { if (ctx.Supports(CSharp3)) { ctx.WriteLine("OnConstructor();"); } ctx.Outdent().WriteLine("}").WriteLine(); if (ctx.Supports(CSharp3)) { ctx.WriteLine("partial void OnConstructor();") .WriteLine(); } }
/// <summary> /// End a file /// </summary> protected override void WriteFileFooter(GeneratorContext ctx, FileDescriptorProto file, ref object state) { if (ctx.Supports(VB14)) { ctx.WriteLine($"#Enable Warning BC40008, BC40055, IDE1006").WriteLine(); } }
/// <summary> /// Start a message /// </summary> protected override void WriteMessageHeader(GeneratorContext ctx, DescriptorProto message, ref object state) { var name = ctx.NameNormalizer.GetName(message); var tw = ctx.Write("[global::ProtoBuf.ProtoContract("); if (name != message.Name) { tw.Write($@"Name = @""{message.Name}"""); } tw.WriteLine(")]"); WriteOptions(ctx, message.Options); tw = ctx.Write($"{GetAccess(GetAccess(message))} partial class {Escape(name)}"); tw.Write(" : global::ProtoBuf.IExtensible"); tw.WriteLine(); ctx.WriteLine("{").Indent(); if (message.Options?.MessageSetWireFormat == true) { ctx.WriteLine("#error message_set_wire_format is not currently implemented").WriteLine(); } ctx.WriteLine($"private global::ProtoBuf.IExtension {FieldPrefix}extensionData;") .WriteLine($"global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)"); if (ctx.Supports(CSharp6)) { ctx.Indent().WriteLine($"=> global::ProtoBuf.Extensible.GetExtensionObject(ref {FieldPrefix}extensionData, createIfMissing);").Outdent().WriteLine(); } else { ctx.WriteLine("{").Indent().WriteLine($"return global::ProtoBuf.Extensible.GetExtensionObject(ref {FieldPrefix}extensionData, createIfMissing);").Outdent().WriteLine("}"); } }
/// <summary> /// End a file /// </summary> protected override void WriteFileFooter(GeneratorContext ctx, FileDescriptorProto file, ref object state) { var @namespace = (string)state; var prefix = ctx.Supports(CSharp6) ? "CS" : ""; if (!string.IsNullOrWhiteSpace(@namespace)) { ctx.Outdent().WriteLine("}").WriteLine(); } var tw = ctx.Write($"#pragma warning restore {prefix}0612, {prefix}1591, {prefix}3021"); if (ctx.Supports(CSharp6)) { tw.Write(AdditionalSuppressionCodes); } tw.WriteLine(); }
/// <summary> /// Emit code beginning a constructor, if one is required /// </summary> /// <returns>true if a constructor is required</returns> protected override bool WriteContructorHeader(GeneratorContext ctx, DescriptorProto message, ref object state) { if (ctx.Supports(CSharp6)) { return(false); } var name = ctx.NameNormalizer.GetName(message); ctx.WriteLine($"public {Escape(name)}()") // note: the .ctor is still public even if the type is internal; it is protected by the scope .WriteLine("{").Indent(); return(true); }
/// <summary> /// End a file /// </summary> protected override void WriteFileFooter(GeneratorContext ctx, FileDescriptorProto file, ref object state) { var @namespace = (string)state; if (!string.IsNullOrWhiteSpace(@namespace)) { ctx.Outdent().WriteLine("End Namespace").WriteLine(); } if (ctx.Supports(VB14)) { ctx.WriteLine($"#Enable Warning BC40008, BC40055, IDE1006").WriteLine(); } }
/// <summary> /// End a file /// </summary> protected override void WriteFileFooter(GeneratorContext ctx, FileDescriptorProto file, ref object state) { var @namespace = (string)state; var prefix = ctx.Supports(CSharp6) ? "CS" : ""; if (!string.IsNullOrWhiteSpace(@namespace)) { ctx.Outdent().WriteLine("}").WriteLine(); } var @filename = file.Name.Substring(0, file.Name.IndexOf(".")); ctx.WriteLine($"public class ILRuntime_{@filename}"); ctx.WriteLine("{").Indent(); ctx.WriteLine($"static ILRuntime_{@filename}()"); ctx.WriteLine("{"); ctx.WriteLine().Indent(); ctx.WriteLine($"//Initlize();"); ctx.WriteLine().Outdent(); ctx.WriteLine("}"); ctx.WriteLine($"public static void Initlize()"); ctx.WriteLine("{"); ctx.WriteLine().Indent(); foreach (var T in TypeNames2) { ctx.WriteLine($@"ProtoBuf.PType.RegisterType(""{T}"", typeof({T}));"); } ctx.WriteLine().Outdent(); ctx.WriteLine("}").Outdent(); ctx.WriteLine("}").WriteLine(); var tw = ctx.Write($"#pragma warning restore {prefix}1591, {prefix}0612, {prefix}3021"); if (ctx.Supports(CSharp6)) { tw.Write(", IDE1006"); } tw.WriteLine(); }
/// <summary> /// Start a file /// </summary> protected override void WriteFileHeader(GeneratorContext ctx, FileDescriptorProto file, ref object state) { //var prefix = ctx.Supports(CSharp6) ? "CS" : ""; ctx.WriteLine("' <auto-generated>") .WriteLine("' This file was generated by a tool; you should avoid making direct changes.") .WriteLine("' Consider using 'partial classes' to extend these types") .WriteLine($"' Input: {Path.GetFileName(ctx.File.Name)}") .WriteLine("' </auto-generated>") .WriteLine(); if (ctx.Supports(VB14)) { ctx.WriteLine($"#Disable Warning BC40008, BC40055, IDE1006").WriteLine(); } }
/// <summary> /// Emit the discriminator accessor for 'oneof' groups /// </summary> protected override void WriteOneOfDiscriminator(GeneratorContext ctx, OneofDescriptorProto oneof, ref object state) { var name = ctx.NameNormalizer.GetName(oneof); var fieldName = GetOneOfFieldName(oneof); if (ctx.Supports(CSharp6)) { ctx.WriteLine($"public {name}{OneOfEnumSuffixEnum} {name}{OneOfEnumSuffixDiscriminator} => ({name}{OneOfEnumSuffixEnum}){fieldName}.Discriminator;"); } else { ctx.WriteLine($"public {name}{OneOfEnumSuffixEnum} {name}{OneOfEnumSuffixDiscriminator}").WriteLine("{").Indent() .WriteLine($"get {{ return ({name}{OneOfEnumSuffixEnum}){fieldName}.Discriminator; }}") .Outdent().WriteLine("}"); } }
/// <summary> /// Start a file /// </summary> protected override void WriteFileHeader(GeneratorContext ctx, FileDescriptorProto file, ref object state) { //var prefix = ctx.Supports(CSharp6) ? "CS" : ""; ctx.WriteLine("' This file was generated by a tool; you should avoid making direct changes.") .WriteLine("' Consider using 'partial classes' to extend these types") .WriteLine($"' Input: {Path.GetFileName(ctx.File.Name)}").WriteLine(); if (ctx.Supports(VB14)) { ctx.WriteLine($"#Disable Warning BC40008, BC40055, IDE1006").WriteLine(); } var @namespace = ctx.NameNormalizer.GetName(file); if (!string.IsNullOrWhiteSpace(@namespace)) { state = @namespace; ctx.WriteLine($"Namespace {@namespace}").Indent(); } }
/// <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(); } } }
/// <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(); }
/// <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(); }
/// <summary> /// Emit code representing a service method /// </summary> protected override void WriteServiceMethod(GeneratorContext ctx, MethodDescriptorProto method, ref object state) { var name = ctx.NameNormalizer.GetName(method); if (name != method.Name) { ctx.WriteLine($@"[global::System.ServiceModel.OperationContract(Name = @""{method.Name}"")]"); } WriteOptions(ctx, method.Options); string returnType, inputType; if (method.ServerStreaming) { returnType = "global::System.Collection.Generics.IAsyncEnumerable<" + GetTypeName(ctx, method.OutputType) + ">"; } else { if (method.OutputType == WellKnownTypeEmpty) { returnType = "global::System.Threading.Tasks.ValueTask"; } else { returnType = "global::System.Threading.Tasks.ValueTask<" + GetTypeName(ctx, method.OutputType) + ">"; } } if (method.ClientStreaming) { inputType = "global::System.Collection.Generics.IAsyncEnumerable<" + GetTypeName(ctx, method.InputType) + ">"; } else { if (method.InputType == WellKnownTypeEmpty) { inputType = null; } else { inputType = GetTypeName(ctx, method.InputType); } } var tw = ctx.Write($"{returnType} {Escape(name)}Async("); if (inputType != null) { tw.Write(inputType); tw.Write(method.ClientStreaming ? " values, " : " value, "); } tw.Write("global::ProtoBuf.Grpc.CallContext context"); if (ctx.Supports(CSharp4)) { tw.Write(" = default"); if (!ctx.Supports(CSharp7_1)) { tw.Write("(global::ProtoBuf.Grpc.CallContext)"); } } tw.WriteLine(");"); }