package org.sahagin.share.srctree.code;

import java.util.HashMap;
import java.util.Map;

import org.sahagin.share.yaml.YamlUtils;
import org.sahagin.share.yaml.YamlConvertException;
import org.sahagin.share.yaml.YamlConvertible;

public abstract class Code implements YamlConvertible {
    public static final String MSG_INVALID_TYPE = "invalid type: %s";

    private String original;

    public String getOriginal() {
        return original;
    }

    public void setOriginal(String original) {
        this.original = original;
    }

    protected abstract String getType();

    @Override
    public Map<String, Object> toYamlObject() {
        Map<String, Object> result = new HashMap<String, Object>(8);
        result.put("type", getType());
        result.put("original", original);
        return result;
    }

    @Override
    public void fromYamlObject(Map<String, Object> yamlObject) throws YamlConvertException {
        YamlUtils.strValueEqualsCheck(yamlObject, "type", getType());
        original = YamlUtils.getStrValue(yamlObject, "original");
    }

    public static Code newInstanceFromYamlObject(Map<String, Object> yamlObject)
            throws YamlConvertException {
        if (yamlObject == null) {
            return null;
        }
        String type = YamlUtils.getStrValue(yamlObject, "type");
        Code result;
        if (StringCode.TYPE.equals(type)) {
            result = new StringCode();
        } else if (MethodArgument.TYPE.equals(type)) {
            result = new MethodArgument();
        } else if (SubMethodInvoke.TYPE.equals(type)) {
            result = new SubMethodInvoke();
        } else if (Field.TYPE.equals(type)) {
            result = new Field();
        } else if (LocalVar.TYPE.equals(type)) {
            result = new LocalVar();
        } else if (VarAssign.TYPE.equals(type)) {
            result = new VarAssign();
        } else if (TestStep.TYPE.equals(type)) {
            result = new TestStep();
        } else if (TestStepLabel.TYPE.equals(type)) {
            result = new TestStepLabel();
        } else if (UnknownCode.TYPE.equals(type)) {
            result = new UnknownCode();
        } else {
            throw new YamlConvertException(String.format(MSG_INVALID_TYPE, type));
        }
        result.fromYamlObject(yamlObject);
        return result;
    }

}

@@ -384,66 +384,659 @@
 al;%0A
-%0A    public String getOriginal() %7B%0A        return original
+    // Memo data are not write to nor read from YAML data.%0A    // They are only temporal data mainly used for SrcTree generation%0A    private Object rawASTObjectMemo;%0A    private Object rawASTTypeMemo;%0A%0A    public String getOriginal() %7B%0A        return original;%0A    %7D%0A%0A    public Object getRawASTObjectMemo() %7B%0A        return rawASTObjectMemo;%0A    %7D%0A%0A    public void setRawASTObjectMemo(Object rawASTObjectMemo) %7B%0A        this.rawASTObjectMemo = rawASTObjectMemo;%0A    %7D%0A%0A    public Object getRawASTTypeMemo() %7B%0A        return rawASTTypeMemo;%0A    %7D%0A%0A    public void setRawASTTypeMemo(Object rawASTTypeMemo) %7B%0A        this.rawASTTypeMemo = rawASTTypeMemo
 ;%0A  

Define raw AST memo