public void GenerateEnum(ProtoEnum m) { if (m.OptionExternal) { cw.Comment("Written elsewhere"); cw.Comment(m.Comments); cw.Comment(m.OptionAccess + " enum " + m.CsType); cw.Comment("{"); foreach (var epair in m.Enums) { cw.Summary(epair.Comment); cw.Comment(cw.IndentPrefix + epair.Name + " = " + epair.Value + ","); } cw.Comment("}"); return; } cw.Summary(m.Comments); if (m.OptionFlags) cw.Attribute("global::System.FlagsAttribute"); cw.Bracket(m.OptionAccess + " enum " + m.CsType); foreach (var epair in m.Enums) { cw.Summary(epair.Comment); cw.WriteLine(epair.Name + " = " + epair.Value + ","); } cw.EndBracket(); cw.WriteLine(); }
static void ParseEnumValue(TokenReader tr, ProtoEnum parent, string name) { if (tr.ReadNext() != "=") { throw new ProtoFormatException("Expected: =", tr); } int id = ParseInt(tr); var value = new ProtoEnumValue(name, id, lastComment); parent.Enums.Add(value); string extra = tr.ReadNext(); if (extra == ";") { return; } if (extra != "[") { throw new ProtoFormatException("Expected: ; or [", tr); } ParseEnumValueOptions(tr); }
static void ParseEnum(TokenReader tr, ProtoMessage parent, string package) { ProtoEnum me = new ProtoEnum(parent, package); LocalParser.ParseComments(me, lastComment, tr); me.ProtoName = tr.ReadNext(); parent.Enums.Add(me.ProtoName, me); //must be after .ProtoName is read if (tr.ReadNext() != "{") throw new ProtoFormatException("Expected: {", tr); while (true) { string name = tr.ReadNext(); if (ParseComment(name)) continue; if (name == "}") return; //Ignore options if (name == "option") { ParseOption(tr, null); lastComment.Clear(); continue; } ParseEnumValue(tr, me, name); } }
public void GenerateEnum(ProtoEnum m) { if (m.OptionExternal) { cw.Comment("Written elsewhere"); cw.Comment(m.Comments); cw.Comment(m.OptionAccess + " enum " + m.CsType); cw.Comment("{"); foreach (var epair in m.Enums) { cw.Summary(epair.Comment); cw.Comment(cw.IndentPrefix + epair.Name + " = " + epair.Value + ","); } cw.Comment("}"); return; } cw.Summary(m.Comments); if (m.OptionFlags) { cw.Attribute("global::System.FlagsAttribute"); } cw.Bracket(m.OptionAccess + " enum " + m.CsType); foreach (var epair in m.Enums) { cw.Summary(epair.Comment); cw.WriteLine(epair.Name + " = " + epair.Value + ","); } cw.EndBracket(); cw.WriteLine(); }
public static void GenerateEnum(ProtoEnum me, CodeWriter cw) { cw.Bracket("public class " + me.CsNamespace + "_" + me.CsType + "Enum"); foreach (var epair in me.Enums) { cw.Summary(epair.Comment); cw.WriteLine("public const int " + epair.Name + " = " + epair.Value + ";"); } cw.EndBracket(); cw.WriteLine(); }
public void GenerateEnum(ProtoEnum me) { cw.Bracket("public enum " + me.CsType); foreach (var epair in me.Enums) { cw.Summary(epair.Comment); cw.WriteLine(epair.Name + " = " + epair.Value + ","); } cw.EndBracket(); cw.WriteLine(); }
public static void GenerateEnum(ProtoEnum me, CodeWriter cw) { cw.Bracket("public enum " + me.CsType); foreach (var epair in me.Enums) { if (me.EnumsComments.ContainsKey(epair.Key)) cw.Summary(me.EnumsComments [epair.Key]); cw.WriteLine(epair.Key + " = " + epair.Value + ","); } cw.EndBracket(); cw.WriteLine(); }
static void ParseEnumFlags(ProtoEnum message, string flag) { switch (flag) { case "external": message.OptionExternal = true; break; case "flags": message.OptionFlags = true; break; default: throw new NotImplementedException("Unknown option: " + flag); } }
static void ParseEnumOption(ProtoEnum message, string key, string value) { //Parse value switch (key) { /* This could be supported if the code generation handles the scope when generating the code for the enum. case "namespace": message.OptionNamespace = value; break;*/ case "access": message.OptionAccess = value; break; default: throw new NotImplementedException("Unknown option: " + key); } }
static void ParseEnumOption(ProtoEnum message, string key, string value) { //Parse value switch (key) { /* This could be supported if the code generation handles the scope when generating the code for the enum. * case "namespace": * message.OptionNamespace = value; * break;*/ case "access": message.OptionAccess = value; break; default: throw new NotImplementedException("Unknown option: " + key); } }
static void GenerateDefaults(ProtoMessage m, CodeWriter cw, Options options) { foreach (Field f in m.Fields.Values) { if (f.Rule == FieldRule.Repeated) { //Initialize lists of the custom DateTime or TimeSpan type. string csType = f.ProtoType.FullCsType; if (f.OptionCodeType != null) { csType = f.OptionCodeType; } cw.WriteLine("if (instance." + f.CsName + " == null)"); cw.WriteIndent("instance." + f.CsName + " = Pool.GetList<" + csType + ">();"); } else if (f.OptionDefault != null) { if (options.Properties) { if (f.ProtoType is ProtoEnum) { cw.WriteLine("instance." + f.CsName + " = " + f.ProtoType.FullCsType + "." + f.OptionDefault + ";"); } else { cw.WriteLine("instance." + f.CsName + " = " + f.FormatForTypeAssignment() + ";"); } } } else if (f.Rule == FieldRule.Optional) { if (f.ProtoType is ProtoEnum) { ProtoEnum pe = f.ProtoType as ProtoEnum; //the default value is the first value listed in the enum's type definition foreach (var kvp in pe.Enums) { cw.WriteLine("instance." + f.CsName + " = " + pe.FullCsType + "." + kvp.Name + ";"); break; } } } } }
public void GenerateEnum(ProtoEnum m) { if (options.NoGenerateImported && m.IsImported) { Console.Error.WriteLine("Skipping imported enum " + m.FullProtoName); return; } cw.Summary(m.Comments); if (m.OptionFlags) { cw.Attribute("System.FlagsAttribute"); } cw.Bracket("public enum " + m.CsType); foreach (var epair in m.Enums) { cw.Summary(epair.Comment); cw.WriteLine(epair.Name + " = " + epair.Value + ","); } cw.EndBracket(); cw.WriteLine(); }
private void GenerateDefaults(ProtoMessage m) { //Prepare List<> and default values foreach (Field f in m.Fields.Values) { if (f.Rule == FieldRule.Repeated) { if (f.OptionReadOnly == false) { //Initialize lists of the custom DateTime or TimeSpan type. string csType = f.ProtoType.FullCsType; if (f.OptionCodeType != null) { csType = f.OptionCodeType; } cw.WriteLine("if (instance." + f.CsName + " == null)"); cw.WriteIndent("instance." + f.CsName + " = new List<" + csType + ">();"); } } else if (f.OptionDefault != null) { cw.WriteLine("instance." + f.CsName + " = " + f.FormatForTypeAssignment() + ";"); } else if ((f.Rule == FieldRule.Optional) && !options.Nullable) { if (f.ProtoType is ProtoEnum) { ProtoEnum pe = f.ProtoType as ProtoEnum; //the default value is the first value listed in the enum's type definition foreach (var kvp in pe.Enums) { cw.WriteLine("instance." + f.CsName + " = " + pe.FullCsType + "." + kvp.Name + ";"); break; } } } } }
static void ParseEnumValue(TokenReader tr, ProtoEnum parent, string name) { if (tr.ReadNext() != "=") throw new ProtoFormatException("Expected: =", tr); int id = int.Parse(tr.ReadNext()); var value = new ProtoEnumValue(name, id, lastComment); parent.Enums.Add(value); string extra = tr.ReadNext(); if (extra == ";") return; if (extra != "[") throw new ProtoFormatException("Expected: ; or [", tr); ParseEnumValueOptions(tr, value); }
static void GenerateReader(ProtoMessage m, CodeWriter cw) { #region Helper Deserialize Methods string refstr = (m.OptionType == "struct") ? "ref " : ""; if (m.OptionType != "interface") { cw.Summary("Helper: create a new instance to deserializing into"); cw.Bracket(m.OptionAccess + " static " + m.CsType + " Deserialize(Stream stream)"); cw.WriteLine(m.CsType + " instance = new " + m.CsType + "();"); cw.WriteLine("Deserialize(stream, " + refstr + "instance);"); cw.WriteLine("return instance;"); cw.EndBracketSpace(); cw.Summary("Helper: create a new instance to deserializing into"); cw.Bracket(m.OptionAccess + " static " + m.CsType + " DeserializeLengthDelimited(Stream stream)"); cw.WriteLine(m.CsType + " instance = new " + m.CsType + "();"); cw.WriteLine("DeserializeLengthDelimited(stream, " + refstr + "instance);"); cw.WriteLine("return instance;"); cw.EndBracketSpace(); cw.Summary("Helper: create a new instance to deserializing into"); cw.Bracket(m.OptionAccess + " static " + m.CsType + " DeserializeLength(Stream stream, int length)"); cw.WriteLine(m.CsType + " instance = new " + m.CsType + "();"); cw.WriteLine("DeserializeLength(stream, length, " + refstr + "instance);"); cw.WriteLine("return instance;"); cw.EndBracketSpace(); cw.Summary("Helper: put the buffer into a MemoryStream and create a new instance to deserializing into"); cw.Bracket(m.OptionAccess + " static " + m.CsType + " Deserialize(byte[] buffer)"); cw.WriteLine(m.CsType + " instance = new " + m.CsType + "();"); cw.WriteLine("using (var ms = new MemoryStream(buffer))"); cw.WriteIndent("Deserialize(ms, " + refstr + "instance);"); cw.WriteLine("return instance;"); cw.EndBracketSpace(); } cw.Summary("Helper: put the buffer into a MemoryStream before deserializing"); cw.Bracket(m.OptionAccess + " static " + m.FullCsType + " Deserialize(byte[] buffer, " + refstr + m.FullCsType + " instance)"); cw.WriteLine("using (var ms = new MemoryStream(buffer))"); cw.WriteIndent("Deserialize(ms, " + refstr + "instance);"); cw.WriteLine("return instance;"); cw.EndBracketSpace(); #endregion string[] methods = new string[] { "Deserialize", //Default old one "DeserializeLengthDelimited", //Start by reading length prefix and stay within that limit "DeserializeLength", //Read at most length bytes given by argument }; //Main Deserialize foreach (string method in methods) { if (method == "Deserialize") { cw.Summary("Takes the remaining content of the stream and deserialze it into the instance."); cw.Bracket(m.OptionAccess + " static " + m.FullCsType + " " + method + "(Stream stream, " + refstr + m.FullCsType + " instance)"); } else if (method == "DeserializeLengthDelimited") { cw.Summary("Read the VarInt length prefix and the given number of bytes from the stream and deserialze it into the instance."); cw.Bracket(m.OptionAccess + " static " + m.FullCsType + " " + method + "(Stream stream, " + refstr + m.FullCsType + " instance)"); } else if (method == "DeserializeLength") { cw.Summary("Read the given number of bytes from the stream and deserialze it into the instance."); cw.Bracket(m.OptionAccess + " static " + m.FullCsType + " " + method + "(Stream stream, int length, " + refstr + m.FullCsType + " instance)"); } else { throw new NotImplementedException(); } if (m.IsUsingBinaryWriter) { cw.WriteLine("BinaryReader br = new BinaryReader(stream);"); } //Prepare List<> and default values foreach (Field f in m.Fields.Values) { if (f.Rule == FieldRule.Repeated) { if (f.OptionReadOnly == false) { //Initialize lists of the custom DateTime or TimeSpan type. string csType = f.ProtoType.FullCsType; if (f.OptionCodeType != null) { csType = f.OptionCodeType; } cw.WriteLine("if (instance." + f.CsName + " == null)"); cw.WriteIndent("instance." + f.CsName + " = new List<" + csType + ">();"); } } else if (f.OptionDefault != null) { cw.WriteLine("instance." + f.CsName + " = " + f.FormatForTypeAssignment() + ";"); } else if (f.Rule == FieldRule.Optional) { if (f.ProtoType is ProtoEnum) { ProtoEnum pe = f.ProtoType as ProtoEnum; //the default value is the first value listed in the enum's type definition foreach (var kvp in pe.Enums) { cw.WriteLine("instance." + f.CsName + " = " + pe.FullCsType + "." + kvp.Name + ";"); break; } } } } if (method == "DeserializeLengthDelimited") { //Important to read stream position after we have read the length field cw.WriteLine("long limit = global::SilentOrbit.ProtocolBuffers.ProtocolParser.ReadUInt32(stream);"); cw.WriteLine("limit += stream.Position;"); } if (method == "DeserializeLength") { //Important to read stream position after we have read the length field cw.WriteLine("long limit = stream.Position + length;"); } cw.WhileBracket("true"); if (method == "DeserializeLengthDelimited" || method == "DeserializeLength") { cw.IfBracket("stream.Position >= limit"); cw.WriteLine("if (stream.Position == limit)"); cw.WriteIndent("break;"); cw.WriteLine("else"); cw.WriteIndent("throw new global::SilentOrbit.ProtocolBuffers.ProtocolBufferException(\"Read past max limit\");"); cw.EndBracket(); } cw.WriteLine("int keyByte = stream.ReadByte();"); cw.WriteLine("if (keyByte == -1)"); if (method == "Deserialize") { cw.WriteIndent("break;"); } else { cw.WriteIndent("throw new System.IO.EndOfStreamException();"); } //Determine if we need the lowID optimization bool hasLowID = false; foreach (Field f in m.Fields.Values) { if (f.ID < 16) { hasLowID = true; break; } } if (hasLowID) { cw.Comment("Optimized reading of known fields with field ID < 16"); cw.Switch("keyByte"); foreach (Field f in m.Fields.Values) { if (f.ID >= 16) { continue; } cw.Dedent(); cw.Comment("Field " + f.ID + " " + f.WireType); cw.Indent(); cw.Case(((f.ID << 3) | (int)f.WireType)); if (FieldSerializer.FieldReader(f, cw)) { cw.WriteLine("continue;"); } } cw.SwitchEnd(); cw.WriteLine(); } cw.WriteLine("var key = global::SilentOrbit.ProtocolBuffers.ProtocolParser.ReadKey((byte)keyByte, stream);"); cw.WriteLine(); cw.Comment("Reading field ID > 16 and unknown field ID/wire type combinations"); cw.Switch("key.Field"); cw.Case(0); cw.WriteLine("throw new global::SilentOrbit.ProtocolBuffers.ProtocolBufferException(\"Invalid field id: 0, something went wrong in the stream\");"); foreach (Field f in m.Fields.Values) { if (f.ID < 16) { continue; } cw.Case(f.ID); //Makes sure we got the right wire type cw.WriteLine("if(key.WireType != global::SilentOrbit.ProtocolBuffers.Wire." + f.WireType + ")"); cw.WriteIndent("break;"); //This can be changed to throw an exception for unknown formats. if (FieldSerializer.FieldReader(f, cw)) { cw.WriteLine("continue;"); } } cw.CaseDefault(); if (m.OptionPreserveUnknown) { cw.WriteLine("if (instance.PreservedFields == null)"); cw.WriteIndent("instance.PreservedFields = new List<global::SilentOrbit.ProtocolBuffers.KeyValue>();"); cw.WriteLine("instance.PreservedFields.Add(new global::SilentOrbit.ProtocolBuffers.KeyValue(key, global::SilentOrbit.ProtocolBuffers.ProtocolParser.ReadValueBytes(stream, key)));"); } else { cw.WriteLine("global::SilentOrbit.ProtocolBuffers.ProtocolParser.SkipKey(stream, key);"); } cw.WriteLine("break;"); cw.SwitchEnd(); cw.EndBracket(); cw.WriteLine(); if (m.OptionTriggers) { cw.WriteLine("instance.AfterDeserialize();"); } cw.WriteLine("return instance;"); cw.EndBracket(); cw.WriteLine(); } return; }