예제 #1
0
        /// <summary>
        /// 정의를 하나 읽습니다.
        /// 정의는 스키마 또는 ENUM 테이블 정의입니다.
        /// </summary>
        /// <param name="reader">reader</param>
        /// <param name="defFile">정의 파일</param>
        private static void ReadDefinition(ref Utf8JsonReader reader, ref DefinitionFile defFile)
        {
            if (reader.TokenType != JsonTokenType.StartObject)
            {
                throw new Exception("An internal error has occured. Definition token must starts a StartObject token");
            }

            if (!reader.Read() &&
                reader.TokenType != JsonTokenType.PropertyName)
            {
                throw new ArgumentException("An invalid definition has detected");
            }

            string firstPropName = reader.GetString();

            if (firstPropName.StartsWith("enum "))
            {
                reader.Read();

                Match match = EnumDefRegex.Match(firstPropName);
                if (!match.Success)
                {
                    throw new ArgumentException($"{firstPropName} is an invalid enum definition");
                }

                GroupCollection groups = match.Groups;

                string enumName = groups["name"].Value.Trim();
                if (!NameRegex.IsMatch(enumName))
                {
                    throw MakeDisallowedNameException(enumName, "enum name");
                }

                FieldType enumValueType = FieldType.Nil;
                if (groups["type"].Success)
                {
                    Field valueField = new Field();

                    BuildFieldType(ref valueField, groups["type"].Value);

                    enumValueType = valueField.Type;
                }

                string enumDesc = string.Empty;
                if (firstPropName.IndexOf("//", match.Length) != -1)
                {
                    enumDesc = firstPropName.Substring(firstPropName.IndexOf("//") + 2).Trim();
                }

                Table enumTable = ReadEnumTable(ref reader, enumName, enumValueType);
                if (!string.IsNullOrWhiteSpace(enumDesc))
                {
                    enumTable.Schema.Description = enumDesc;
                }

                if (!defFile.AddEnumTable(enumTable))
                {
                    throw new ArgumentException($"{enumName} is an already defined definition");
                }
            }
            else
            {
                Schema schema = new Schema();

                bool hasPartial = false;

                while (reader.TokenType != JsonTokenType.EndObject)
                {
                    string propName = reader.GetString();
                    reader.Read();

                    switch (propName)
                    {
                    case "name":
                    {
                        schema.Name = reader.GetString().Trim();
                        if (!NameRegex.IsMatch(schema.Name))
                        {
                            throw MakeDisallowedNameException(schema.Name, "schema name");
                        }
                        reader.Read();
                        break;
                    }

                    case "fields":
                    {
                        if (reader.TokenType == JsonTokenType.StartObject)
                        {
                            reader.Read();
                            while (reader.TokenType != JsonTokenType.EndObject)
                            {
                                string name = reader.GetString().Trim();
                                if (!NameRegex.IsMatch(name))
                                {
                                    throw MakeDisallowedNameException(schema.Name, "field name");
                                }

                                reader.Read();

                                Field field = ReadField(ref reader, name);
                                if (!schema.AddField(field))
                                {
                                    throw new ArgumentException($"{name} is an already defined field name");
                                }
                            }
                            reader.Read();
                        }
                        break;
                    }

                    case "partials":
                    case "parts":
                    {
                        hasPartial = true;

                        foreach (string name in reader.ReadStringList())
                        {
                            if (!PartialNameRegex.IsMatch(name))
                            {
                                throw MakeDisallowedNameException(schema.Name, "partial name");
                            }

                            if (!schema.AddPartial(name))
                            {
                                throw new ArgumentException($"{name} is an already defiend partial name");
                            }
                        }
                        break;
                    }

                    case "embed":
                    {
                        schema.Embed = reader.GetBoolean();
                        reader.Read();
                        break;
                    }

                    case "desc":
                    case "description":
                    {
                        schema.Description = reader.GetString();
                        reader.Read();
                        break;
                    }

                    default:
                    {
                        reader.Skip();
                        // Skip을 하면 StartToken에서 EndToken으로 가게 되므로,
                        // 한번 더 Read해서 Token을 완전히 끝냄
                        reader.Read();
                        break;
                    }
                    }
                }

                if (!hasPartial)
                {
                    schema.AddPartial(schema.Name);
                }

                if (!defFile.AddSchema(schema))
                {
                    throw new Exception($"{schema.Name} is an already defiend schema name");
                }
            }

            reader.Read();
        }