Exemple #1
0
        static ITypeDecleration ReadProtoType(MsgCodeReader reader, string ns, string[] parentTypes, TypeDict typeDict, bool requireMsgKeyWord, List <string> usings = null)
        {
            string     typeName        = null;
            ShellType  ret             = null;
            TypeCustom type            = null;
            bool       typeExtend      = false;
            string     baseType        = null;
            bool       done            = false;
            bool       isProperty      = false;
            bool       isArrayProperty = false;
            string     propertyName    = null;
            string     propertyType    = null;
            bool       protoMemberEq   = false;
            int        protoMember     = -1;
            int        hasDefaultVal   = 0;
            string     defaultValue    = null;

            string[] newParentTypes = null;
            string   comments       = null;

            while (reader.CanPeek())
            {
                char chr = (char)reader.Peek();
                if (chr == '\n')
                {
                    reader.Next();
                    continue;
                }
                if (WHITE_CHARS.IndexOf(chr) >= 0)
                {
                    reader.Next();
                    continue;
                }
                //Debug.LogFormat("'{0}' at Line {1} Column {2}", chr, reader.LineCount, reader.Column - 1);
                if (string.IsNullOrEmpty(typeName))
                {
                    typeName = ReadContentWord(reader);
                    if (requireMsgKeyWord && typeName == "message")
                    {
                        typeName          = null;
                        requireMsgKeyWord = false;
                    }
                    continue;
                }
                else
                {
                    bool typeDone = false;
                    if (type == null)
                    {
                        if (chr != '{')
                        {
                            string w = ReadContentWord(reader, ".");
                            if (typeExtend)
                            {
                                if (string.IsNullOrEmpty(baseType))
                                {
                                    baseType = w;
                                    continue;
                                }
                            }
                            else
                            {
                                if (w == "extend")
                                {
                                    typeExtend = true;
                                    continue;
                                }
                            }
                            Debug.LogWarning(w);
                            throw new Exception("'{' is required after message name !");
                        }
                        if (newParentTypes == null)
                        {
                            if (parentTypes == null)
                            {
                                parentTypes = new string[0];
                            }
                            newParentTypes = new string[parentTypes.Length + 1];
                            Array.Copy(parentTypes, 0, newParentTypes, 0, parentTypes.Length);
                            newParentTypes[parentTypes.Length] = typeName;
                        }
                        ret = typeDict.GetType(ns, parentTypes, typeName, false, usings);
                        if (ret != null && ret.type is TypeCustom)
                        {
                            type = ret.type as TypeCustom;
                        }
                        else
                        {
                            if (ret == null)
                            {
                                ret = new ShellType(typeName);
                            }
                            type     = new TypeCustom(typeName);
                            ret.type = type;
                        }
                        typeDict.AddType(ns, parentTypes, typeName, ret);
                        type.SetTypeExtend(baseType);
                        reader.Next();
                    }
                    else if (chr == '}')
                    {
                        //TODO is illegal
                        reader.Next();
                        done = true;
                        break;
                    }
                    else if (!isProperty)
                    {
                        comments = reader.LastComment;
                        string kw = ReadContentWord(reader);
                        if (kw == "optional" || kw == "required")
                        {
                            isProperty      = true;
                            isArrayProperty = false;
                        }
                        else if (kw == "repeated")
                        {
                            isProperty      = true;
                            isArrayProperty = true;
                        }
                        else if (kw == "message")
                        {
                            isProperty      = false;
                            isArrayProperty = false;
                            ITypeDecleration subType = ReadProtoType(reader, ns, newParentTypes, typeDict, false);
                            if (!string.IsNullOrEmpty(comments))
                            {
                                subType.AddTypeComments(comments);
                            }
                            comments = null;
                            type.AddSubType(subType);
                        }
                        else if (kw == "enum")
                        {
                            ITypeDecleration subType = ReadEnumType(reader, ns, newParentTypes, typeDict, false);
                            if (!string.IsNullOrEmpty(comments))
                            {
                                subType.AddTypeComments(comments);
                            }
                            comments = null;
                            type.AddSubType(subType);
                        }
                        else
                        {
                            throw new Exception(string.Format("Unknown key word '{0}' !", kw));
                        }
                    }
                    else if (string.IsNullOrEmpty(propertyType))
                    {
                        propertyType = ReadContentWord(reader);
                        if (string.IsNullOrEmpty(propertyType))
                        {
                            throw new Exception("Property Type is required !");
                        }
                    }
                    else if (string.IsNullOrEmpty(propertyName))
                    {
                        propertyName = ReadContentWord(reader);
                        if (string.IsNullOrEmpty(propertyName))
                        {
                            throw new Exception("Property Name is required !");
                        }
                    }
                    else if (!protoMemberEq)
                    {
                        if (chr != '=')
                        {
                            throw new Exception("'=' is required after property name !");
                        }
                        protoMemberEq = true;
                        reader.Next();
                    }
                    else if (protoMember <= 0)
                    {
                        string pm = ReadContentWord(reader);
                        //Debug.LogWarning("pm : " + pm + "    char " + reader.Peek());
                        if (!TryParseInt(pm, out protoMember))
                        {
                            throw new Exception(string.Format("Cannot parse proto member '{0}' into int !", pm));
                        }
                        if (protoMember <= 0)
                        {
                            throw new Exception("Proto member should be greater than or equal to 1");
                        }
                    }
                    else if (hasDefaultVal == 0)
                    {
                        if (chr == ';')
                        {
                            typeDone = true;
                        }
                        else
                        {
                            if (chr != '[')
                            {
                                throw new Exception("';' or '[default=xxx]' is required in property definition !");
                            }
                            hasDefaultVal = 1;
                        }
                        reader.Next();
                    }
                    else if (hasDefaultVal == 1)
                    {
                        string def = ReadContentWord(reader);
                        if (def != "default")
                        {
                            Debug.LogError(def);
                            throw new Exception("'[default=xxx]' is required in property definition !");
                        }
                        hasDefaultVal = 2;
                    }
                    else if (hasDefaultVal == 2)
                    {
                        if (chr != '=')
                        {
                            throw new Exception("'[default=xxx]' is required in property definition !");
                        }
                        hasDefaultVal = 3;
                        reader.Next();
                    }
                    else if (hasDefaultVal == 3)
                    {
                        defaultValue = ReadContentString(reader, "]\n");
                        if (string.IsNullOrEmpty(defaultValue))
                        {
                            throw new Exception("Illegal default value in property definition !");
                        }
                        Debug.LogWarning("default value : " + defaultValue);
                        hasDefaultVal = 4;
                    }
                    else if (hasDefaultVal == 4)
                    {
                        if (chr != ']')
                        {
                            throw new Exception("'[default=xxx]' is required in property definition !");
                        }
                        hasDefaultVal = 5;
                        reader.Next();
                    }
                    else
                    {
                        if (chr != ';')
                        {
                            throw new Exception("';' is required after property definition !");
                        }
                        typeDone = true;
                        reader.Next();
                    }
                    if (typeDone)
                    {
                        TypeBase t = TypeHelper.GetXmlValueType(propertyType);
                        if (t == null)
                        {
                            t = typeDict.GetType(ns, newParentTypes, propertyType, true, usings);
                        }
                        //Debug.LogWarningFormat("\t{0}{1} {2} = {3}", propertyType, isArrayProperty ? "[]" : "", propertyName, protoMember);
                        type.AddField(propertyName, t, isArrayProperty, defaultValue, comments, protoMember);
                        propertyType    = null;
                        propertyName    = null;
                        protoMemberEq   = false;
                        isArrayProperty = false;
                        protoMember     = -1;
                        isProperty      = false;
                        comments        = null;
                        hasDefaultVal   = 0;
                        defaultValue    = null;
                    }
                }
            }
            if (!done)
            {
                throw new Exception(string.Format("message '{0}' is not completed !", typeName));
            }
            //Debug.Log(ret);
            return(ret);
        }
Exemple #2
0
        public static Dictionary <string, List <ITypeDecleration> > ReadProto(MsgCodeReader reader, out List <string> usings)
        {
            usings = new List <string>();

            Dictionary <string, List <ITypeDecleration> > ret = new Dictionary <string, List <ITypeDecleration> >();

            int requiredChar = -1;
            Dictionary <string, TypeDict> typeDicts = new Dictionary <string, TypeDict>();

            TypeDict typeDict             = null;
            List <ITypeDecleration> types = null;

            int    curState     = 0;      //1 for package, 2 for import, 4 for message, 5 for enum
            string curNameSpace = "global";
            bool   headsOver    = false;

            while (reader.CanPeek())
            {
                char chr = (char)reader.Peek();
                if (WHITE_CHARS.IndexOf(chr) >= 0)
                {
                    reader.Next();
                    continue;
                }
                if (requiredChar >= 0)
                {
                    if ((char)requiredChar != chr)
                    {
                        throw new Exception(string.Format("'{0}' is required !", (char)requiredChar));
                    }
                    requiredChar = -1;
                    reader.Next();
                    continue;
                }
                if (chr == '\n')
                {
                    reader.Next();
                    continue;
                }

                if (curState == 0)
                {
                    string kw = ReadContentWord(reader);
                    if (kw == "package")
                    {
                        curState = 1;
                    }
                    else if (kw == "import")
                    {
                        if (headsOver)
                        {
                            throw new Exception("'import' should be in front of all types !");
                        }
                        curState = 2;
                    }
                    else if (kw == "message")
                    {
                        curState = 4;
                    }
                    else if (kw == "enum")
                    {
                        curState = 5;
                    }
                    else
                    {
                        Debug.LogError(chr + "   " + (int)chr + "    at line " + reader.LineCount + "  column " + reader.Column);
                        throw new Exception(string.Format("Unknows keyword '{0}' !", kw));
                    }
                }
                else if (curState == 1)                //package
                {
                    curNameSpace = ReadContentWord(reader, ".");
                    requiredChar = ';';
                    types        = null;
                    typeDict     = null;
                    curState     = 0;
                }
                else if (curState == 2)                 //import
                {
                    bool hasQuot = chr == '"';
                    if (hasQuot)
                    {
                        reader.Next();
                    }
                    string importNs = ReadContentWord(reader, ".");
                    if (string.IsNullOrEmpty(importNs))
                    {
                        throw new Exception("Namespace after 'import' is required !");
                    }
                    if (hasQuot)
                    {
                        if (reader.Peek() != '"')
                        {
                            throw new Exception("'\"' should be appeared in pairs !");
                        }
                        reader.Next();
                    }
                    usings.Add(importNs);
                    requiredChar = ';';
                    curState     = 0;
                }
                else if (curState == 4 || curState == 5)
                {
                    string comments = reader.LastComment;
                    headsOver = true;
                    if (types == null && !ret.TryGetValue(curNameSpace, out types))
                    {
                        types = new List <ITypeDecleration>();
                        ret.Add(curNameSpace, types);
                    }
                    if (typeDict == null && !typeDicts.TryGetValue(curNameSpace, out typeDict))
                    {
                        typeDict = new TypeDict();
                        typeDicts.Add(curNameSpace, typeDict);
                    }
                    if (curState == 4)                    //message
                    {
                        ITypeDecleration type = ReadProtoType(reader, curNameSpace, null, typeDict, false, usings);
                        if (!string.IsNullOrEmpty(comments))
                        {
                            type.AddTypeComments(comments);
                        }
                        types.Add(type);
                        curState = 0;
                    }
                    else if (curState == 5)                     //enum
                    {
                        ITypeDecleration type = ReadEnumType(reader, curNameSpace, null, typeDict, false);
                        if (!string.IsNullOrEmpty(comments))
                        {
                            type.AddTypeComments(comments);
                        }
                        types.Add(type);
                        curState = 0;
                    }
                }
            }
            return(ret);
        }