Search in sources :

Example 1 with IfFalse

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

the class DoWrite method apply.

@Override
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
    Map<String, FieldDescription> fieldsByName = CodeGenUtil.fieldsByName(implementationContext);
    List<StackManipulation> stackManipulations = new ArrayList<>();
    final StackManipulation getDefaultInstance;
    try {
        getDefaultInstance = invoke(messageClass.getDeclaredMethod("getDefaultInstance"));
    } catch (NoSuchMethodException e) {
        throw new IllegalStateException("Could not find getDefaultInstance on a Message class.");
    }
    LocalVariables<LocalVariable> locals = LocalVariables.builderForMethod(instrumentedMethod, LocalVariable.values()).add(Iterator.class, LocalVariable.iterator).add(Map.Entry.class, LocalVariable.entry).build();
    stackManipulations.add(locals.initialize());
    // based on the includeDefaults parameter.
    for (FieldDescriptor f : descriptor.getFields()) {
        ProtoFieldInfo field = new ProtoFieldInfo(f, prototype);
        StackManipulation getValue = new StackManipulation.Compound(locals.load(LocalVariable.message), invoke(field.getValueMethod()));
        Label afterSerializeField = new Label();
        // }
        if (!includeDefaults || // one-of).
        field.isInOneof() || // a message has itself as a sub-field.
        (field.descriptor().isOptional() && field.valueJavaType() == JavaType.MESSAGE)) {
            stackManipulations.add(checkDefaultValue(field, locals, getValue, getDefaultInstance, afterSerializeField));
        }
        stackManipulations.addAll(Arrays.asList(locals.load(LocalVariable.gen), FieldAccess.forField(fieldsByName.get(CodeGenUtil.fieldNameForSerializedFieldName(field))).read(), JsonGenerator_writeFieldName_SerializableString));
        // gen.writeEndObject();
        if (field.isMapField()) {
            final StackManipulation keyToString;
            switch(field.mapKeyField().descriptor().getType()) {
                case INT32:
                case SINT32:
                case SFIXED32:
                    keyToString = Integer_toString;
                    break;
                case INT64:
                case SINT64:
                case SFIXED64:
                    keyToString = Long_toString;
                    break;
                case BOOL:
                    keyToString = Boolean_toString;
                    break;
                case UINT32:
                case FIXED32:
                    keyToString = new StackManipulation.Compound(SerializeSupport_normalizeUnsignedInt32, Long_toString);
                    break;
                case UINT64:
                case FIXED64:
                    keyToString = SerializeSupport_normalizeUnsignedInt64;
                    break;
                case STRING:
                    keyToString = Trivial.INSTANCE;
                    break;
                default:
                    throw new IllegalStateException("Unexpected map key type: " + field.mapKeyField().descriptor().getType());
            }
            final Label loopStart = new Label();
            final Label loopEnd = new Label();
            final StackManipulation printValue = printValue(fieldsByName, field);
            final StackManipulation printMapFieldValue = new StackManipulation.Compound(locals.load(LocalVariable.gen), JsonGenerator_writeStartObject, getValue, Map_entrySet, Set_iterator, locals.store(LocalVariable.iterator), new SetJumpTargetLabel(loopStart), locals.load(LocalVariable.iterator), Iterator_hasNext, new IfFalse(loopEnd), locals.load(LocalVariable.iterator), Iterator_next, TypeCasting.to(new ForLoadedType(Entry.class)), locals.store(LocalVariable.entry), locals.load(LocalVariable.gen), locals.load(LocalVariable.entry), Map_Entry_getKey, unbox(field.mapKeyField()), keyToString, JsonGenerator_writeFieldName_String, locals.load(LocalVariable.entry), Map_Entry_getValue, unbox(field.valueField()), locals.load(LocalVariable.gen), printValue, new Goto(loopStart), new SetJumpTargetLabel(loopEnd), locals.load(LocalVariable.gen), JsonGenerator_writeEndObject);
            stackManipulations.add(printMapFieldValue);
        } else {
            // Simply calls the SerializeSupport method that prints out this field. Any iteration will
            // be handled there.
            // 
            // e.g.,
            // SerializeSupport.printUnsignedInt32(message.getFoo());
            // SerializeSupport.printRepeatedString(message.getBar());
            final StackManipulation printValue = printValue(fieldsByName, field);
            stackManipulations.addAll(Arrays.asList(getValue, locals.load(LocalVariable.gen), printValue));
        }
        stackManipulations.add(new SetJumpTargetLabel(afterSerializeField));
    }
    stackManipulations.add(MethodReturn.VOID);
    StackManipulation.Size operandStackSize = new StackManipulation.Compound(stackManipulations).apply(methodVisitor, implementationContext);
    return new Size(operandStackSize.getMaximalSize(), locals.stackSize());
}
Also used : Goto(org.curioswitch.common.protobuf.json.bytebuddy.Goto) StackManipulation(net.bytebuddy.implementation.bytecode.StackManipulation) ForLoadedType(net.bytebuddy.description.type.TypeDescription.ForLoadedType) ArrayList(java.util.ArrayList) SetJumpTargetLabel(org.curioswitch.common.protobuf.json.bytebuddy.SetJumpTargetLabel) Label(net.bytebuddy.jar.asm.Label) SerializableString(com.fasterxml.jackson.core.SerializableString) ByteString(com.google.protobuf.ByteString) FieldDescription(net.bytebuddy.description.field.FieldDescription) FieldDescriptor(com.google.protobuf.Descriptors.FieldDescriptor) Entry(java.util.Map.Entry) SetJumpTargetLabel(org.curioswitch.common.protobuf.json.bytebuddy.SetJumpTargetLabel) IfFalse(org.curioswitch.common.protobuf.json.bytebuddy.IfFalse)

Aggregations

SerializableString (com.fasterxml.jackson.core.SerializableString)1 ByteString (com.google.protobuf.ByteString)1 FieldDescriptor (com.google.protobuf.Descriptors.FieldDescriptor)1 ArrayList (java.util.ArrayList)1 Entry (java.util.Map.Entry)1 FieldDescription (net.bytebuddy.description.field.FieldDescription)1 ForLoadedType (net.bytebuddy.description.type.TypeDescription.ForLoadedType)1 StackManipulation (net.bytebuddy.implementation.bytecode.StackManipulation)1 Label (net.bytebuddy.jar.asm.Label)1 Goto (org.curioswitch.common.protobuf.json.bytebuddy.Goto)1 IfFalse (org.curioswitch.common.protobuf.json.bytebuddy.IfFalse)1 SetJumpTargetLabel (org.curioswitch.common.protobuf.json.bytebuddy.SetJumpTargetLabel)1