private IEnumerable <Command> ValidateOfCreate(ProcedureParser context, string target, string subTarget)
        {
            List <Command>     ret        = new List <Command>();
            CustomPath         path       = new CustomPath(subTarget);
            IProcedureParsable tempTarget = CustomPath.FindAssetWithPath(path);

            if (tempTarget != null)
            {
                Debug.Log($"{path} already exists.");
                return(ret);
            }
            else
            {
                List <string> tempTargets = CustomPath.FindAssetOnlyName(path);
                if (tempTargets.Count > 2)
                {
                    Debug.Log($"{path} : have more than one.");
                    ret.Add(new Command(DefaultCommandType.Log, $"{path} : have more than one.", $"Create {target} in {subTarget}"));
                    return(ret);
                }
                else if (tempTargets.Count == 0)
                {
                    return(null);
                }
                else
                {
                    ret.Add(new Command(DefaultCommandType.Move, tempTargets[0], subTarget));
                    context.ChangeAllCommandPath(path.FilePath, tempTargets[0]);
                    return(ret);
                }
            }
        }
        private static IEnumerable <Command> ValidateOfSet(ProcedureParser context, string target, string subTarget)
        {
            List <Command> ret = new List <Command>();

            ret.Add(new Command(DefaultCommandType.Set, target, subTarget));
            CustomPath         path       = new CustomPath(target);
            IProcedureParsable tempTarget = CustomPath.FindAssetWithPath(path);

            if (tempTarget == null)
            {
                if (context.WillBeCreated(new CustomPath(path.FilePath)))
                {
                    Command buff = ret[0];
                    buff.PastValue = Command.NaN;
                    ret[0]         = buff;
                    return(ret);
                }
                ret.Clear();
                ret.Add(new Command(DefaultCommandType.Log, "CannotFoundTarget", $"Set {target} into {subTarget}"));
                return(ret);
            }
            if (path.FromLast(1).StartsWith(CustomPath.RefPrefix))
            {
                string tempValue = tempTarget.Get($"{path.FromLast(1)}/{path.FromLast(0)}");
                if (tempValue == subTarget)
                {
                    ret.Clear();
                }
                else
                {
                    Command buff = ret[0];
                    buff.PastValue = tempValue;
                    ret[0]         = buff;
                }
            }
            else
            {
                string tempValue = tempTarget.Get(path.FromLast(0));
                if (tempValue == subTarget)
                {
                    ret.Clear();
                }
                else
                {
                    Command buff = ret[0];
                    buff.PastValue = tempValue;
                    ret[0]         = buff;
                }
            }
            return(ret);
        }
        private IEnumerable <Command> ReactionOfCreate(ProcedureParser context, string target, string subTarget)
        {
            List <Command>     ret         = new List <Command>();
            IProcedureParsable targetAsset = CreateNewObject(target);
            CustomPath         targetPath  = new CustomPath(subTarget);
            CustomPath         assetPath   = null;

            {
                int altIndex = 0;
                for (; altIndex < targetPath.Length; altIndex++)
                {
                    if (targetPath.FromLast(altIndex).Contains(CustomPath.ExtensionDiff))
                    {
                        break;
                    }
                }
                assetPath = targetPath.GenerateHigherPath(altIndex);
            }
            Debug.LogWarning(assetPath?.FullPath);

            CustomPath tempPath = new CustomPath(Empty);

            for (int i = 0; i < assetPath.Length - 1; i++)
            {
                tempPath = tempPath.GenerateLowerPath(assetPath[i]);
                if (!AssetDatabase.IsValidFolder(tempPath.FullPath))
                {
                    Debug.Log($"{tempPath} creating directory");
                    AssetDatabase.CreateFolder(tempPath.GenerateHigherPath(1).FullPath, tempPath.FromLast(0));
                }
            }
            if (targetAsset is ScriptableObject)
            {
                AssetDatabase.CreateAsset(targetAsset as ScriptableObject, assetPath.FullPath);
                targetAsset.InitializeAsset();
            }
            else if (targetAsset is Component)
            {
                targetAsset.InitializeAsset();
                PrefabUtility.SaveAsPrefabAsset((targetAsset as Component).gameObject, assetPath.FullPath);
                Object.DestroyImmediate((targetAsset as Component).gameObject);
            }
            else
            {
                ret.Add(new Command(DefaultCommandType.Log, "Invalid Type"));
                return(ret);
            }

            return(null);
        }
        public static IProcedureParsable FindAssetWithPath(CustomPath path)
        {
            int tempIndex = path.FileNameIndex + 1;

            if (path.FileName.EndsWith(PrefabExtension))
            {
                GameObject targetGameObject = AssetDatabase.LoadAssetAtPath <GameObject>(path.FilePath);
                if (targetGameObject == null)
                {
                    return(null);
                }
                Transform targetObject = targetGameObject.transform;
                while (path[tempIndex].Contains(ObjPrefix))
                {
                    targetObject = targetObject.Find(path[tempIndex].Substring(2));
                    tempIndex++;
                }

                string             componentName   = path[tempIndex++].Substring(2);
                IProcedureParsable targetComponent = targetObject.GetComponent(componentName) as IProcedureParsable;
                if (targetComponent == null)
                {
                    return(null);
                }

                return(targetComponent);
            }
            else if (path.FilePath.EndsWith(AssetExtension))
            {
                IProcedureParsable targetScriptableObject =
                    AssetDatabase.LoadAssetAtPath <ScriptableObject>(path.FilePath) as IProcedureParsable;
                if (targetScriptableObject == null)
                {
                    return(null);
                }
                return(targetScriptableObject);
            }
            return(null);
        }
        private static IEnumerable <Command> ReactionOfSet(ProcedureParser context, string target, string subTarget)
        {
            List <Command>     ret        = new List <Command>();
            CustomPath         path       = new CustomPath(target);
            IProcedureParsable tempTarget = CustomPath.FindAssetWithPath(path);

            if (tempTarget == null)
            {
                ret.Add(new Command(DefaultCommandType.Log, "CannotFoundTarget", $"Set {target} into {subTarget}"));
                return(ret);
            }

            if (path.FromLast(1).StartsWith(CustomPath.RefPrefix))
            {
                tempTarget.Set($"{path.FromLast(1)}/{path.FromLast(0)}", subTarget);
            }
            else
            {
                tempTarget.Set(path.FromLast(0), subTarget);
            }
            return(null);
        }
        public virtual IProcedureParsable CreateNewObject(string type)
        {
            IProcedureParsable ret = null;

            switch (type)
            {
                // case nameof(TestComponent):
                //     ret = new GameObject().AddComponent<TestComponent>();
                //     break;
                // case nameof(TestSubComponent):
                //     ret = new GameObject().AddComponent<TestSubComponent>();
                //     break;
                // case nameof(TestScriptableObject):
                //     ret = ScriptableObject.CreateInstance<TestScriptableObject>();
                //     break;
                // case nameof(TestSubScriptableObject):
                //     ret = ScriptableObject.CreateInstance<TestSubScriptableObject>();
                //     break;
                //TODO
            }
            return(ret);
        }