Inheritance: MessageEnumBase
示例#1
0
文件: Message.cs 项目: enyim/ProtoBuf
        public Message(Message parent)
        {
            this.Parent = parent;

            this.OptionNamespace = null;
            this.OptionTriggers = false;
        }
示例#2
0
        public override string GenerateClass(Message m)
        {
            string code = "";

            code += GenerateInterface (m);
            code += "\n";

            //Default class
            code += "public partial class " + m.CSType + " : I" + m.CSType + "\n";
            code += "{\n";
            string enums = GenerateEnums (m);
            if (enums.Length > 0) {
                code += Code.Indent (enums);
                code += "\n";
            }
            code += Code.Indent (GenerateProperties (m));
            code += "\n";

            foreach (Message sub in m.Messages) {
                code += "\n";
                code += Code.Indent (GenerateClass (sub));
            }
            code += "}\n";
            return code;
        }
示例#3
0
 /// <summary>
 /// Generates code for writing a class/message
 /// </summary>
 static string GenerateGenericWriter(Message m)
 {
     string code = "";
     code += m.OptionAccess + " static void Write(Stream stream, " + m.FullCSType + " instance)\n";
     code += "{\n";
     code += "	" + m.FullCSType + ".Serialize(stream, instance);\n";
     code += "}\n";
     return code;
 }
示例#4
0
 /// <summary>
 /// Adds BinaryWriter only if it will be used
 /// </summary>
 static bool GenerateBinaryWriter(Message m)
 {
     foreach (Field f in m.Fields.Values) {
         if (f.WireType == Wire.Fixed32 || f.WireType == Wire.Fixed64) {
             return true;
         }
     }
     return false;
 }
示例#5
0
        /// <summary>
        /// Gets the C# CamelCase version of a given name.
        /// Name collisions with enums are avoided.
        /// </summary>
        static string GetCSPropertyName(Message m, string name)
        {
            string csname = GetCamelCase (name);

            foreach (MessageEnum me in m.Enums)
                if (me.CSType == csname)
                    return name;

            return csname;
        }
示例#6
0
 public MessageName(Message parent, string fullNamespaceClass)
     : base(parent)
 {
     path = fullNamespaceClass;
     int pos = fullNamespaceClass.LastIndexOf (".");
     if (pos < 0) {
         this.CSType = fullNamespaceClass;
     } else {
         this.OptionNamespace = fullNamespaceClass.Substring (0, pos);
         this.CSType = fullNamespaceClass.Substring (pos + 1);
     }
 }
示例#7
0
 public static string GenerateGenericClassSerializer(Message m)
 {
     string code = "";
     code += "\n";
     code += GenerateGenericReader (m);
     code += "\n";
     code += GenerateGenericWriter (m);
     code += "\n";
     foreach (Message sub in m.Messages) {
         code += "\n";
         code += GenerateGenericClassSerializer (sub);
     }
     return code;
 }
示例#8
0
 public static string GenerateClassSerializer(Message m)
 {
     string code = "";
     code += m.OptionAccess + " partial class " + m.CSType + "\n";
     code += "{\n";
     code += Code.Indent (GenerateReader (m));
     code += "\n";
     code += Code.Indent (GenerateWriter (m));
     foreach (Message sub in m.Messages) {
         code += "\n";
         code += Code.Indent (GenerateClassSerializer (sub));
     }
     code += "}\n";
     code += "\n";
     return code;
 }
示例#9
0
 static string GenerateGenericReader(Message m)
 {
     string code = "";
     code += m.OptionAccess + " static " + m.FullCSType + " Read (Stream stream, " + m.FullCSType + " instance)\n";
     code += "{\n";
     code += "	return " + m.FullCSType + ".Deserialize(stream, instance);\n";
     code += "}\n";
     code += "\n";
     code += m.OptionAccess + " static " + m.FullCSType + " Read(byte[] buffer, " + m.FullCSType + " instance)\n";
     code += "{\n";
     code += "	using (MemoryStream ms = new MemoryStream(buffer))\n";
     code += "		" + m.FullCSType + ".Deserialize (ms, instance);\n";
     code += "	return instance;\n";
     code += "}\n";
     return code;
 }
示例#10
0
        private string GenerateInterface(Message m)
        {
            string properties = "";
            foreach (Field f in m.Fields.Values) {
                if (f.OptionDeprecated)
                    properties += "[Obsolete]\n";
                properties += f.PropertyType + " " + f.Name + " { get; set; }\n";
            }

            string code = "";
            code += "public interface I" + m.CSType + "\n";
            code += "{\n";
            code += Code.Indent (properties);
            code += "}\n";
            return code;
        }
示例#11
0
 /// <summary>
 /// Generates the properties.
 /// </summary>
 /// <param name='template'>
 /// if true it will generate only properties that are not included by default, because of the [generate=false] option.
 /// </param>
 protected string GenerateProperties(Message m)
 {
     string code = "";
     foreach (Field f in m.Fields.Values) {
         if (f.OptionGenerate) {
             if (f.Comments != null) {
                 code += "/// <summary>\n";
                 code += Code.Prefix ("/// ", f.Comments) + "\n";
                 code += "/// </summary>\n";
             }
             code += GenerateProperty (f) + "\n";
         } else {
             code += "//" + GenerateProperty (f) + "	//Implemented by user elsewhere\n";
         }
     }
     return code;
 }
示例#12
0
 protected string GenerateEnums(Message m)
 {
     string code = "";
     foreach (MessageEnum me in m.Enums) {
         code += "public enum " + me.CSType + "\n";
         code += "{\n";
         foreach (var epair in me.Enums) {
             if (me.EnumsComments.ContainsKey (epair.Key)) {
                 code += "	/// <summary>\n";
                 code += Code.Prefix ("	/// ", me.EnumsComments [epair.Key]) + "\n";
                 code += "	/// </summary>\n";
             }
             code += "	" + epair.Key + " = " + epair.Value + ",\n";
         }
         code += "}\n";
     }
     return code;
 }
示例#13
0
        public override string GenerateClass(Message m)
        {
            string code = "";

            //Base class
            code += m.OptionAccess + " abstract class " + m.CSType + "Base\n";
            code += "{\n";
            code += Code.Indent (GenerateProperties (m));
            code += "\n";
            if (m.OptionTriggers) {
                code += "	protected virtual void BeforeSerialize()\n";
                code += "	{\n";
                code += "	}\n";
                code += "\n";
                code += "	protected virtual void AfterDeserialize()\n";
                code += "	{\n";
                code += "	}\n";
            }
            code += "}\n\n";

            //Default class
            code += m.OptionAccess + " partial class " + m.CSType + " : " + m.CSType + "Base\n";
            code += "{\n";
            string enums = GenerateEnums (m);
            if (enums.Length > 0) {
                code += Code.Indent (enums);
                code += "\n";
            }
            #if !GENERATE_BASE
            code += Code.Indent (GenerateProperties (m));
            code += "\n";
            #endif

            foreach (Message sub in m.Messages) {
                code += "\n";
                code += Code.Indent (GenerateClass (sub));
            }
            code += "}\n";

            return code;
        }
示例#14
0
        static MessageEnum ParseEnum(TokenReader tr, Message parent)
        {
            MessageEnum me = new MessageEnum (parent);
            me.Comments = lastComment;
            lastComment = null;
            me.ProtoName = tr.ReadNext ();

            if (tr.ReadNext () != "{")
                throw new ProtoFormatException ("Expected: {");

            while (true) {
                string name = tr.ReadNext ();

                if (ParseComment (name))
                    continue;

                if (name == "}")
                    return me;

                //Ignore options
                if (name == "option") {
                    ParseOption (tr, null);
                    lastComment = null;
                    continue;
                }

                if (tr.ReadNext () != "=")
                    throw new ProtoFormatException ("Expected: =");

                int id = int.Parse (tr.ReadNext ());

                me.Enums.Add (name, id);
                if (lastComment != null)
                    me.EnumsComments.Add (name, lastComment);
                lastComment = null;

                if (tr.ReadNext () != ";")
                    throw new ProtoFormatException ("Expected: ;");
            }
        }
示例#15
0
        public virtual string GenerateClass(Message m)
        {
            string code = "";

            //Default class
            if (m.Comments != null) {
                code += "/// <summary>\n";
                code += Code.Prefix ("/// ", m.Comments) + "\n";
                code += "/// </summary>\n";
            }
            code += m.OptionAccess + " partial class " + m.CSType + "\n";
            code += "{\n";

            string enums = GenerateEnums (m);
            if (enums.Length > 0) {
                code += Code.Indent (enums);
                code += "\n";
            }

            code += Code.Indent (GenerateProperties (m));
            code += "\n";

            if (m.OptionTriggers) {
                code += Code.Indent (Code.Comment (
                    "protected virtual void BeforeSerialize() {}\n" +
                    "protected virtual void AfterDeserialize() {}\n"));
                code += "\n";
            }

            foreach (Message sub in m.Messages) {
                code += Code.Indent (GenerateClass (sub));
                code += "\n";
            }
            code = code.TrimEnd ('\n');
            code += "\n}\n";
            return code;
        }
示例#16
0
 //Search for name.
 static MessageEnumBase GetProtoType(Message m, string path)
 {
     string[] parts = path.Split ('.');
     return SearchMessageUp (m, parts);
 }
示例#17
0
        static Message ParseMessage(TokenReader tr, Message parent)
        {
            Message msg = new Message (parent);
            msg.Comments = lastComment;
            lastComment = null;
            msg.ProtoName = tr.ReadNext ();

            tr.ReadNextOrThrow ("{");

            while (ParseField (tr, msg))
                continue;

            return msg;
        }
示例#18
0
        static bool ParseField(TokenReader tr, Message m)
        {
            string rule = tr.ReadNext ();
            while (true) {
                if (ParseComment (rule) == false)
                    break;
                rule = tr.ReadNext ();
            }

            if (rule == "}")
                return false;

            if (rule == "enum") {
                MessageEnum me = ParseEnum (tr, m);
                m.Enums.Add (me);
                return true;
            }

            Field f = new Field ();
            f.Comments = lastComment;
            lastComment = null;

            //Rule
            switch (rule) {
            case "required":
                f.Rule = FieldRule.Required;
                break;
            case "optional":
                f.Rule = FieldRule.Optional;
                break;
            case "repeated":
                f.Rule = FieldRule.Repeated;
                break;
            case "option":
                //Save options
                ParseOption (tr, m);
                return true;
            case "message":
                m.Messages.Add (ParseMessage (tr, m));
                return true;
            default:
                throw new ProtoFormatException ("unknown rule: " + rule);
            }

            //Type
            f.ProtoTypeName = tr.ReadNext ();

            //Name
            f.Name = tr.ReadNext ();

            //ID
            tr.ReadNextOrThrow ("=");
            f.ID = int.Parse (tr.ReadNext ());
            if (19000 <= f.ID && f.ID <= 19999)
                throw new ProtoFormatException ("Can't use reserved field ID 19000-19999");
            if (f.ID > (1 << 29) - 1)
                throw new ProtoFormatException ("Maximum field id is 2^29 - 1");

            //Add Field to message
            m.Fields.Add (f.ID, f);

            //Determine if extra options
            string extra = tr.ReadNext ();
            if (extra == ";")
                return true;

            //Field options
            if (extra != "[")
                throw new ProtoFormatException ("Expected: [ got " + extra);

            while (true) {
                string key = tr.ReadNext ();
                tr.ReadNextOrThrow ("=");
                string val = tr.ReadNext ();

                ParseFieldOption (key, val, f);
                string optionSep = tr.ReadNext ();
                if (optionSep == "]")
                    break;
                if (optionSep == ",")
                    continue;
                throw new ProtoFormatException (@"Expected "","" or ""]"" got " + tr.Next);
            }
            tr.ReadNextOrThrow (";");

            return true;
        }
示例#19
0
        /// <summary>
        /// Generates code for writing a class/message
        /// </summary>
        static string GenerateWriter(Message m)
        {
            string code = m.OptionAccess + " static void Serialize(Stream stream, " + m.CSType + " instance)\n";
            code += "{\n";
            if (m.OptionTriggers) {
                code += "	instance.BeforeSerialize();\n";
                code += "\n";
            }
            if (GenerateBinaryWriter (m))
                code += "	BinaryWriter bw = new BinaryWriter(stream);\n";

            foreach (Field f in m.Fields.Values) {
                code += Code.Indent (FieldCode.GenerateFieldWriter (m, f));
            }
            code += "}\n\n";

            code += m.OptionAccess + " static byte[] SerializeToBytes(" + m.CSType + " instance)\n";
            code += "{\n";
            code += "	using(MemoryStream ms = new MemoryStream())\n";
            code += "	{\n";
            code += "		Serialize(ms, instance);\n";
            code += "		return ms.ToArray();\n";
            code += "	}\n";
            code += "}\n";

            return code;
        }
示例#20
0
        /// <summary>
        /// File or Message options
        /// </summary>
        static void ParseOption(TokenReader tr, Message m)
        {
            //Read name
            string key = tr.ReadNext ();
            if (tr.ReadNext () != "=")
                throw new ProtoFormatException ("Expected: = got " + tr.Next);
            //Read value
            string value = tr.ReadNext ();
            if (tr.ReadNext () != ";")
                throw new ProtoFormatException ("Expected: ; got " + tr.Next);

            //null = ignore option
            if (m == null)
                return;

            switch (key) {
            case "namespace":
                m.OptionNamespace = value;
                break;
            case "triggers":
                m.OptionTriggers = Boolean.Parse (value);
                break;
            case "access":
                m.OptionAccess = value;
                break;
            default:
                Console.WriteLine ("Warning: Unknown option: " + key);
                break;
            }
        }
示例#21
0
 public MessageEnum(Message parent)
 {
     this.Parent = parent;
 }
示例#22
0
        static string GenerateReader(Message m)
        {
            string code = "";
            code += m.OptionAccess + " static " + m.CSType + " Deserialize(Stream stream)\n";
            code += "{\n";
            code += "	" + m.CSType + " instance = new " + m.CSType + "();\n";
            code += "	Deserialize(stream, instance);\n";
            code += "	return instance;\n";
            code += "}\n";
            code += "\n";
            code += m.OptionAccess + " static " + m.CSType + " Deserialize(byte[] buffer)\n";
            code += "{\n";
            code += "	using(MemoryStream ms = new MemoryStream(buffer))\n";
            code += "		return Deserialize(ms);\n";
            code += "}\n";
            code += "\n";
            code += m.OptionAccess + " static T Deserialize<T> (Stream stream) where T : " + m.FullCSType + ", new()\n";
            code += "{\n";
            code += "	T instance = new T ();\n";
            code += "	Deserialize (stream, instance);\n";
            code += "	return instance;\n";
            code += "}\n";
            code += "\n";
            code += m.OptionAccess + " static T Deserialize<T> (byte[] buffer) where T : " + m.FullCSType + ", new()\n";
            code += "{\n";
            code += "	T instance = new T ();\n";
            code += "	Deserialize(buffer, instance);\n";
            code += "	return instance;\n";
            code += "}\n";
            code += "\n";
            code += m.OptionAccess + " static " + m.FullCSType + " Deserialize (byte[] buffer, " + m.FullCSType + " instance)\n";
            code += "{\n";
            code += "	using (MemoryStream ms = new MemoryStream(buffer))\n";
            code += "		Deserialize (ms, instance);\n";
            code += "   return instance;\n";
            code += "}\n";
            code += "\n";

            code += m.OptionAccess + " static " + m.FullCSType + " Deserialize(Stream stream, " + m.FullCSType + " instance)\n";
            code += "{\n";
            foreach (Field f in m.Fields.Values) {
                if (f.WireType == Wire.Fixed32 || f.WireType == Wire.Fixed64) {
                    code += "	BinaryReader br = new BinaryReader (stream);\n";
                    break;
                }
            }

            foreach (Field f in m.Fields.Values) {
                if (f.Rule == FieldRule.Repeated) {
                    code += "	if(instance." + f.Name + " == null)\n";
                    code += "		instance." + f.Name + " = new List<" + f.PropertyItemType + ">();\n";
                } else if (f.OptionDefault != null) {
                    if (f.ProtoType == ProtoTypes.Enum)
                        code += "	instance." + f.Name + " = " + f.FullPath + "." + f.OptionDefault + ";\n";
                    else
                        code += "	instance." + f.Name + " = " + f.OptionDefault + ";\n";
                } else if (f.Rule == FieldRule.Optional) {
                    if (f.ProtoType == ProtoTypes.Enum) {
                        //the default value is the first value listed in the enum's type definition
                        foreach (var kvp in f.ProtoTypeEnum.Enums) {
                            code += "	instance." + f.Name + " = " + kvp.Key + ";\n";
                            break;
                        }
                    }
                }
            }

            code += "	while (true)\n";
            code += "	{\n";
            code += "		ProtocolBuffers.Key key = null;\n";
            code += "		int keyByte = stream.ReadByte ();\n";
            code += "		if (keyByte == -1)\n";
            code += "			break;\n";
            code += "		//Optimized reading of known fields with field ID < 16\n";
            code += "		switch (keyByte) {\n";
            foreach (Field f in m.Fields.Values) {
                if (f.ID >= 16)
                    continue;
                code += "		case " + ((f.ID << 3) | (int)f.WireType) + ": //Field " + f.ID + " " + f.WireType + "\n";
                code += Code.Indent (3, FieldCode.GenerateFieldReader (f)) + "\n";
                code += "			break;\n";
            }
            code += "		default:\n";
            code += "			key = ProtocolParser.ReadKey ((byte)keyByte, stream);\n";
            code += "			break;\n";
            code += "		}\n";
            code += "\n";
            code += "		if (key == null)\n";
            code += "			continue;\n";
            code += "\n";
            code += "		//Reading field ID > 16 and unknown field ID/wire type combinations\n";
            code += "		switch (key.Field) {\n";
            code += "		case 0:\n";
            code += "			throw new InvalidDataException(\"Invalid field id: 0, something went wrong in the stream\");\n";
            foreach (Field f in m.Fields.Values) {
                if (f.ID < 16)
                    continue;
                code += "		case " + f.ID + ":\n";
                code += Code.Indent (3, FieldCode.GenerateFieldReader (f)) + "\n";
                code += "			break;\n";
            }
            code += "		default:\n";
            code += "			ProtocolParser.SkipKey(stream, key);\n";
            code += "			break;\n";
            code += "		}\n";
            code += "	}\n";
            code += "	\n";
            if (m.OptionTriggers)
                code += "	instance.AfterDeserialize();\n";
            code += "	return instance;\n";
            code += "}\n";
            code += "\n";
            code += m.OptionAccess + " static " + m.FullCSType + " Read(byte[] buffer, " + m.FullCSType + " instance)\n";
            code += "{\n";
            code += "	using (MemoryStream ms = new MemoryStream(buffer))\n";
            code += "		Deserialize (ms, instance);\n";
            code += "	return instance;\n";
            code += "}\n";

            return code;
        }
示例#23
0
        /// <summary>
        /// Generates code for writing one field
        /// </summary>
        public static string GenerateFieldWriter(Message m, Field f)
        {
            string code = "";
            if (f.Rule == FieldRule.Repeated) {
                if (f.OptionPacked == true) {

                    string binaryWriter = "";
                    switch (f.ProtoType) {
                    case ProtoTypes.Double:
                    case ProtoTypes.Float:
                    case ProtoTypes.Fixed32:
                    case ProtoTypes.Fixed64:
                    case ProtoTypes.Sfixed32:
                    case ProtoTypes.Sfixed64:
                        binaryWriter = "\nBinaryWriter bw" + f.ID + " = new BinaryWriter(ms" + f.ID + ");";
                        break;
                    }

                    code += "if(instance." + f.Name + " != null)\n";
                    code += "{\n";
                    code += "	ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                    code += "	using(MemoryStream ms" + f.ID + " = new MemoryStream())\n";
                    code += "	{	" + binaryWriter + "\n";
                    code += "		foreach(" + f.PropertyItemType + " i" + f.ID + " in instance." + f.Name + ")\n";
                    code += "		{\n";
                    code += Code.Indent (3, GenerateFieldTypeWriter (f, "ms" + f.ID, "bw" + f.ID, "i" + f.ID)) + "\n";
                    code += "		}\n";
                    code += "		ProtocolParser.WriteBytes(stream, ms" + f.ID + ".ToArray());\n";
                    code += "	}\n";
                    code += "}\n";
                    return code;
                } else {
                    code += "if(instance." + f.Name + " != null)\n";
                    code += "{\n";
                    code += "	foreach(" + f.PropertyItemType + " i" + f.ID + " in instance." + f.Name + ")\n";
                    code += "	{\n";
                    code += "		ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                    code += Code.Indent (2, GenerateFieldTypeWriter (f, "stream", "bw", "i" + f.ID)) + "\n";
                    code += "	}\n";
                    code += "}\n";
                    return code;
                }
            } else if (f.Rule == FieldRule.Optional) {
                switch (f.ProtoType) {
                case ProtoTypes.String:
                case ProtoTypes.Message:
                case ProtoTypes.Bytes:
                    code += "if(instance." + f.Name + " != null)\n";
                    code += "{\n";
                    code += "	ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                    code += Code.Indent (GenerateFieldTypeWriter (f, "stream", "bw", "instance." + f.Name));
                    code += "}\n";
                    return code;
                case ProtoTypes.Enum:
                    code += "if(instance." + f.Name + " != " + f.PropertyItemType + "." + f.OptionDefault + ")\n";
                    code += "{\n";
                    code += "	ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                    code += Code.Indent (GenerateFieldTypeWriter (f, "stream", "bw", "instance." + f.Name));
                    code += "}\n";
                    return code;
                default:
                    code += "ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                    code += GenerateFieldTypeWriter (f, "stream", "bw", "instance." + f.Name);
                    return code;
                }
            } else if (f.Rule == FieldRule.Required) {
                switch (f.ProtoType) {
                case ProtoTypes.String:
                case ProtoTypes.Message:
                case ProtoTypes.Bytes:
                    code += "if(instance." + f.Name + " == null)\n";
                    code += "	throw new ArgumentNullException(\"" + f.Name + "\", \"Required by proto specification.\");\n";
                    break;
                }
                code += "ProtocolParser.WriteKey(stream, new ProtocolBuffers.Key(" + f.ID + ", Wire." + f.WireType + "));\n";
                code += GenerateFieldTypeWriter (f, "stream", "bw", "instance." + f.Name);
                return code;
            }
            throw new NotImplementedException ("Unknown rule: " + f.Rule);
        }
示例#24
0
        static void PrepareMessage(Message m)
        {
            //Name of message and enums
            m.CSType = ProtoPrepare.GetCamelCase (m.ProtoName);
            foreach (MessageEnum e in m.Enums) {
                e.CSType = GetCamelCase (e.ProtoName);
            }

            foreach (Message sub in m.Messages)
                PrepareMessage (sub);

            //Prepare fields
            foreach (Field f in m.Fields.Values) {
                PrepareProtoType (m, f);
                if (f.OptionDefault != null)
                    f.OptionDefault = GetCSDefaultValue (f);
            }
        }
示例#25
0
        /// <summary>
        /// Searchs the message for matchink classes
        /// </summary>
        /// <param name='name'>
        /// name from .proto
        /// </param>
        static MessageEnumBase SearchMessageUp(Message p, string[] name)
        {
            if (p is Proto)
                return SearchMessageDown (p, name);

            Message m = p as Message;
            if (m.ProtoName == name [0]) {
                if (name.Length == 1)
                    return m;

                string[] subName = new string[name.Length - 1];
                Array.Copy (name, 1, subName, 0, subName.Length);

                return SearchMessageDown (m, subName);
            }

            MessageEnumBase down = SearchMessageDown (p, name);
            if (down != null)
                return down;

            return SearchMessageUp (m.Parent, name);
        }
示例#26
0
        /// <summary>
        /// Search down for matching name
        /// </summary>
        /// <param name='name'>
        /// Split .proto type name
        /// </param>
        static MessageEnumBase SearchMessageDown(Message p, string[] name)
        {
            if (name.Length == 1) {
                foreach (MessageEnum me in p.Enums) {
                    if (me.ProtoName == name [0])
                        return me;
                }
            }

            foreach (Message sub in p.Messages) {
                if (sub.ProtoName == name [0]) {
                    if (name.Length == 1)
                        return sub;
                    string[] subName = new string[name.Length - 1];
                    Array.Copy (name, 1, subName, 0, subName.Length);

                    return SearchMessageDown (sub, subName);
                }
            }

            return null;
        }
示例#27
0
        /// <summary>
        /// Prepare: ProtoType, WireType and CSType
        /// </summary>
        static void PrepareProtoType(Message m, Field f)
        {
            //Change property name to C# style, CamelCase.
            f.Name = GetCSPropertyName (m, f.Name);

            f.ProtoType = GetScalarProtoType (f.ProtoTypeName);

            //Wire, and set type
            switch (f.ProtoType) {
            case ProtoTypes.Double:
            case ProtoTypes.Fixed64:
            case ProtoTypes.Sfixed64:
                f.WireType = Wire.Fixed64;
                break;
            case ProtoTypes.Float:
            case ProtoTypes.Fixed32:
            case ProtoTypes.Sfixed32:
                f.WireType = Wire.Fixed32;
                break;
            case ProtoTypes.Int32:
            case ProtoTypes.Int64:
            case ProtoTypes.Uint32:
            case ProtoTypes.Uint64:
            case ProtoTypes.Sint32:
            case ProtoTypes.Sint64:
            case ProtoTypes.Bool:
                f.WireType = Wire.Varint;
                break;
            case ProtoTypes.String:
            case ProtoTypes.Bytes:
                f.WireType = Wire.LengthDelimited;
                break;
            default:
                MessageEnumBase pt = GetProtoType (m, f.ProtoTypeName);

                if (pt == null) {
                    //Assumed to be a message defined elsewhere
                    f.ProtoType = ProtoTypes.Message;
                    f.WireType = Wire.LengthDelimited;
                    f.ProtoTypeMessage = new MessageName (m, f.ProtoTypeName);
                }
                if (pt is MessageEnum) {
                    f.ProtoType = ProtoTypes.Enum;
                    f.WireType = Wire.Varint;
                    f.ProtoTypeEnum = (MessageEnum)pt;
                }
                if (pt is Message) {
                    f.ProtoType = ProtoTypes.Message;
                    f.WireType = Wire.LengthDelimited;
                    f.ProtoTypeMessage = (Message)pt;
                }

                string[] parts = f.ProtoTypeName.Split ('.');
                string cc = GetCamelCase (parts [parts.Length - 1]);
                if (pt is Message) {
                    f.CSClass = cc;
            #if GENERATE_INTERFACE
                    f.CSType += "I" + cc;
            #else
                    f.CSType += cc;
            #endif
                    break;
                } else
                    f.CSType = cc;

                break;
            }

            if (f.OptionPacked) {
                if (f.WireType == Wire.LengthDelimited)
                    throw new InvalidDataException ("Packed field not allowed for length delimited types");
                f.WireType = Wire.LengthDelimited;
            }

            if (f.OptionCodeType != null) {
                f.CSClass = f.OptionCodeType;
                f.CSType = f.OptionCodeType;
            }

            if (f.CSType == null) {
                f.CSType = GetCSType (f.ProtoType);
                f.CSClass = f.CSType;
            }
        }