Search in sources :

Example 1 with IfEqual

use of org.curioswitch.common.protobuf.json.bytebuddy.IfEqual in project curiostack by curioswitch.

the class DoParse method setRepeatedFieldValue.

/**
 * Returns the {@link StackManipulation} for setting the value of a normal repeated field.
 *
 * <p>Roughly equivalent to:
 *
 * <pre>{@code
 * ParseSupport.parseArrayStart(parser);
 * while (!ParseSupport.checkArrayEnd(parser)) {
 *   builder.addFoo(readValue());
 * }
 * }</pre>
 */
private StackManipulation setRepeatedFieldValue(ProtoFieldInfo info, Label beforeReadField, LocalVariables<LocalVariable> locals, Map<String, FieldDescription> fieldsByName, StackManipulation setSingleValue) {
    Label arrayStart = new Label();
    StackManipulation.Compound beforeRead = new StackManipulation.Compound(locals.load(LocalVariable.parser), ParseSupport_parseArrayStart, new SetJumpTargetLabel(arrayStart), locals.load(LocalVariable.parser), ParseSupport_throwIfRepeatedNull, locals.load(LocalVariable.parser), ParseSupport_checkArrayEnd, new IfTrue(beforeReadField));
    Label afterSet = new Label();
    StackManipulation.Compound setValueAndPrepareForNext = new StackManipulation.Compound(setSingleValue, Removal.SINGLE, new SetJumpTargetLabel(afterSet), locals.load(LocalVariable.parser), Parser_nextValue, Removal.SINGLE, new Goto(arrayStart));
    if (info.valueType() == Type.ENUM) {
        // We special-case enum since we may need to skip unknown values.
        return new StackManipulation.Compound(beforeRead, locals.load(LocalVariable.parser), readValue(info, fieldsByName, locals), locals.store(LocalVariable.intvalue), locals.load(LocalVariable.intvalue), IntegerConstant.forValue(-1), new IfEqual(int.class, afterSet), locals.load(LocalVariable.builder), locals.load(LocalVariable.intvalue), setValueAndPrepareForNext);
    } else {
        return new StackManipulation.Compound(beforeRead, locals.load(LocalVariable.builder), locals.load(LocalVariable.parser), readValue(info, fieldsByName, locals), setValueAndPrepareForNext);
    }
}
Also used : IfEqual(org.curioswitch.common.protobuf.json.bytebuddy.IfEqual) Goto(org.curioswitch.common.protobuf.json.bytebuddy.Goto) StackManipulation(net.bytebuddy.implementation.bytecode.StackManipulation) SetJumpTargetLabel(org.curioswitch.common.protobuf.json.bytebuddy.SetJumpTargetLabel) Label(net.bytebuddy.jar.asm.Label) SetJumpTargetLabel(org.curioswitch.common.protobuf.json.bytebuddy.SetJumpTargetLabel) IfTrue(org.curioswitch.common.protobuf.json.bytebuddy.IfTrue)

Example 2 with IfEqual

use of org.curioswitch.common.protobuf.json.bytebuddy.IfEqual in project curiostack by curioswitch.

the class DoParse method setMapFieldValue.

/**
 * Returns the {@link StackManipulation} for setting the value of a map field.
 *
 * <p>Roughly equivalent to:
 *
 * <pre>{@code
 * ParseSupport.parseObjectStart(parser);
 * while (!ParseSupport.checkObjectEnd(parser.currentToken())) {
 *   builder.putFoo(readKey(), readValue());
 * }
 * }</pre>
 */
private StackManipulation setMapFieldValue(ProtoFieldInfo info, Label beforeReadField, LocalVariables<LocalVariable> locals, Map<String, FieldDescription> fieldsByName) {
    final StackManipulation setConcreteValue = invoke(info.setValueMethod());
    final StackManipulation setMapEntry;
    if (info.valueJavaType() == JavaType.MESSAGE) {
        setMapEntry = new StackManipulation.Compound(TypeCasting.to(new ForLoadedType(info.javaClass())), setConcreteValue);
    } else {
        setMapEntry = setConcreteValue;
    }
    Label mapStart = new Label();
    Label afterSet = new Label();
    StackManipulation.Compound beforeReadKey = new StackManipulation.Compound(locals.load(LocalVariable.parser), ParseSupport_parseObjectStart, new SetJumpTargetLabel(mapStart), locals.load(LocalVariable.parser), Parser_currentToken, ParseSupport_checkObjectEnd, new IfTrue(beforeReadField));
    StackManipulation.Compound setValueAndPrepareForNext = new StackManipulation.Compound(setMapEntry, Removal.SINGLE, new SetJumpTargetLabel(afterSet), locals.load(LocalVariable.parser), Parser_nextToken, Removal.SINGLE, new Goto(mapStart));
    if (info.valueType() == Type.ENUM) {
        // We special-case enum since we may need to skip unknown values.
        final LocalVariable keyVar;
        switch(info.mapKeyField().valueJavaType()) {
            case INT:
                keyVar = LocalVariable.intMapKey;
                break;
            case LONG:
                keyVar = LocalVariable.longMapKey;
                break;
            case BOOLEAN:
                keyVar = LocalVariable.boolMapKey;
                break;
            case STRING:
                keyVar = LocalVariable.stringMapKey;
                break;
            default:
                throw new IllegalArgumentException("Invalid map key type");
        }
        return new StackManipulation.Compound(beforeReadKey, locals.load(LocalVariable.parser), readValue(info.mapKeyField(), fieldsByName, locals), locals.store(keyVar), locals.load(LocalVariable.parser), Parser_nextToken, Removal.SINGLE, locals.load(LocalVariable.parser), readValue(info, fieldsByName, locals), locals.store(LocalVariable.intvalue), locals.load(LocalVariable.intvalue), IntegerConstant.forValue(-1), new IfEqual(int.class, afterSet), locals.load(LocalVariable.builder), locals.load(keyVar), locals.load(LocalVariable.intvalue), setValueAndPrepareForNext);
    } else {
        return new StackManipulation.Compound(beforeReadKey, locals.load(LocalVariable.builder), locals.load(LocalVariable.parser), readValue(info.mapKeyField(), fieldsByName, locals), locals.load(LocalVariable.parser), Parser_nextToken, Removal.SINGLE, locals.load(LocalVariable.parser), readValue(info, fieldsByName, locals), setValueAndPrepareForNext);
    }
}
Also used : IfEqual(org.curioswitch.common.protobuf.json.bytebuddy.IfEqual) Goto(org.curioswitch.common.protobuf.json.bytebuddy.Goto) StackManipulation(net.bytebuddy.implementation.bytecode.StackManipulation) ForLoadedType(net.bytebuddy.description.type.TypeDescription.ForLoadedType) SetJumpTargetLabel(org.curioswitch.common.protobuf.json.bytebuddy.SetJumpTargetLabel) Label(net.bytebuddy.jar.asm.Label) SetJumpTargetLabel(org.curioswitch.common.protobuf.json.bytebuddy.SetJumpTargetLabel) IfTrue(org.curioswitch.common.protobuf.json.bytebuddy.IfTrue)

Aggregations

StackManipulation (net.bytebuddy.implementation.bytecode.StackManipulation)2 Label (net.bytebuddy.jar.asm.Label)2 Goto (org.curioswitch.common.protobuf.json.bytebuddy.Goto)2 IfEqual (org.curioswitch.common.protobuf.json.bytebuddy.IfEqual)2 IfTrue (org.curioswitch.common.protobuf.json.bytebuddy.IfTrue)2 SetJumpTargetLabel (org.curioswitch.common.protobuf.json.bytebuddy.SetJumpTargetLabel)2 ForLoadedType (net.bytebuddy.description.type.TypeDescription.ForLoadedType)1