private Expression deserializeClassSimple( final int version, SerializerBuilder.StaticMethods staticMethods, CompatibilityLevel compatibilityLevel) { Expression local = let(constructor(this.getRawType())); List<Expression> list = new ArrayList<>(); list.add(local); for (String fieldName : fields.keySet()) { FieldGen fieldGen = fields.get(fieldName); if (!fieldGen.hasVersion(version)) continue; Variable field = field(local, fieldName); fieldGen.serializer.prepareDeserializeStaticMethods( version, staticMethods, compatibilityLevel); list.add( set( field, fieldGen.serializer.deserialize( fieldGen.getRawType(), version, staticMethods, compatibilityLevel))); } list.add(local); return sequence(list); }
public void addMatchingSetters() { check(implInterface || !dataTypeIn.isInterface()); Set<String> usedFields = new HashSet<>(); if (constructorParams != null) { usedFields.addAll(constructorParams); } if (factoryParams != null) { usedFields.addAll(factoryParams); } for (List<String> list : setters.values()) { usedFields.addAll(list); } for (String fieldName : fields.keySet()) { FieldGen fieldGen = fields.get(fieldName); Method getter = fieldGen.method; if (getter == null) continue; if (usedFields.contains(fieldName)) continue; String setterName = "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); try { Method setter; if (implInterface) setter = dataTypeOut.getMethod(setterName, getter.getReturnType()); else setter = dataTypeIn.getMethod(setterName, getter.getReturnType()); if (!isPrivate(setter.getModifiers())) { addSetter(setter, asList(fieldName)); } } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } }
private Expression callFactory(Map<String, Expression> map, int version) { Expression[] param = new Expression[factoryParams.size()]; int i = 0; for (String fieldName : factoryParams) { final FieldGen fieldGen = fields.get(fieldName); checkNotNull(fieldGen, "Field '%s' is not found in '%s'", fieldName, factory); if (fieldGen.hasVersion(version)) { param[i++] = map.get(fieldName); } else { param[i++] = pushDefaultValue(fieldGen.getAsmType()); } } return callStatic(factory.getDeclaringClass(), factory.getName(), param); }
@Override public void prepareSerializeStaticMethods( int version, SerializerBuilder.StaticMethods staticMethods, CompatibilityLevel compatibilityLevel) { if (staticMethods.startSerializeStaticMethod(this, version)) { return; } List<Expression> list = new ArrayList<>(); for (String fieldName : fields.keySet()) { FieldGen fieldGen = fields.get(fieldName); if (!fieldGen.hasVersion(version)) continue; Class<?> type = fieldGen.serializer.getRawType(); if (!fieldGen.getRawType().equals(Object.class)) type = fieldGen.getRawType(); if (fieldGen.field != null) { fieldGen.serializer.prepareSerializeStaticMethods( version, staticMethods, compatibilityLevel); list.add( set( arg(1), fieldGen.serializer.serialize( arg(0), arg(1), cast(field(arg(2), fieldName), type), version, staticMethods, compatibilityLevel))); } else if (fieldGen.method != null) { fieldGen.serializer.prepareSerializeStaticMethods( version, staticMethods, compatibilityLevel); list.add( set( arg(1), fieldGen.serializer.serialize( arg(0), arg(1), cast(call(arg(2), fieldGen.method.getName()), type), version, staticMethods, compatibilityLevel))); } else throw new AssertionError(); } list.add(arg(1)); staticMethods.registerStaticSerializeMethod(this, version, sequence(list)); }
public void addGetter(Method method, SerializerGen serializer, int added, int removed) { check(method.getGenericParameterTypes().length == 0); check(isPublic(method.getModifiers())); String fieldName = stripGet(method.getName(), method.getReturnType()); check(!fields.containsKey(fieldName), "Duplicate field '%s'", method); FieldGen fieldGen = new FieldGen(); fieldGen.method = method; fieldGen.serializer = serializer; fieldGen.versionAdded = added; fieldGen.versionDeleted = removed; fieldGen.offset = lastOffset; lastOffset += getType(method.getReturnType()).getSize(); fields.put(fieldName, fieldGen); }
public void addField(Field field, SerializerGen serializer, int added, int removed) { check(implInterface || !dataTypeIn.isInterface()); check(isPublic(field.getModifiers())); String fieldName = field.getName(); check(!fields.containsKey(fieldName), "Duplicate field '%s'", field); FieldGen fieldGen = new FieldGen(); fieldGen.field = field; fieldGen.serializer = serializer; fieldGen.versionAdded = added; fieldGen.versionDeleted = removed; fieldGen.offset = lastOffset; lastOffset += getType(field.getType()).getSize(); fields.put(fieldName, fieldGen); }
@Override public void getVersions(VersionsCollector versions) { for (FieldGen fieldGen : fields.values()) { if (fieldGen.versionAdded != -1) versions.add(fieldGen.versionAdded); if (fieldGen.versionDeleted != -1) versions.add(fieldGen.versionDeleted); versions.addRecursive(fieldGen.serializer); } }
private Expression callConstructor( Class<?> targetType, final Map<String, Expression> map, int version) { Expression[] param; if (constructorParams == null) { param = new Expression[0]; return constructor(targetType, param); } param = new Expression[constructorParams.size()]; int i = 0; for (String fieldName : constructorParams) { FieldGen fieldGen = fields.get(fieldName); checkNotNull(fieldGen, "Field '%s' is not found in '%s'", fieldName, constructor); if (fieldGen.hasVersion(version)) { param[i++] = map.get(fieldName); } else { param[i++] = pushDefaultValue(fieldGen.getAsmType()); } } return constructor(targetType, param); }
private Expression deserializeInterface( Class<?> targetType, final int version, SerializerBuilder.StaticMethods staticMethods, CompatibilityLevel compatibilityLevel) { ClassBuilder<?> asmFactory = ClassBuilder.create(staticMethods.getDefiningClassLoader(), targetType); for (String fieldName : fields.keySet()) { FieldGen fieldGen = fields.get(fieldName); Method method = checkNotNull(fieldGen.method); asmFactory = asmFactory .withField(fieldName, method.getReturnType()) .withMethod(method.getName(), field(self(), fieldName)); } Class<?> newClass = asmFactory.build(); Expression local = let(constructor(newClass)); List<Expression> list = new ArrayList<>(); list.add(local); for (String fieldName : fields.keySet()) { FieldGen fieldGen = fields.get(fieldName); if (!fieldGen.hasVersion(version)) continue; Variable field = field(local, fieldName); fieldGen.serializer.prepareDeserializeStaticMethods( version, staticMethods, compatibilityLevel); Expression expression = fieldGen.serializer.deserialize( fieldGen.getRawType(), version, staticMethods, compatibilityLevel); list.add(set(field, expression)); } list.add(local); return sequence(list); }
@Override public void prepareDeserializeStaticMethods( int version, SerializerBuilder.StaticMethods staticMethods, CompatibilityLevel compatibilityLevel) { if (staticMethods.startDeserializeStaticMethod(this, version)) { return; } if (!implInterface && dataTypeIn.isInterface()) { Expression expression = deserializeInterface(this.getRawType(), version, staticMethods, compatibilityLevel); staticMethods.registerStaticDeserializeMethod(this, version, expression); return; } if (!implInterface && constructor == null && factory == null && setters.isEmpty()) { Expression expression = deserializeClassSimple(version, staticMethods, compatibilityLevel); staticMethods.registerStaticDeserializeMethod(this, version, expression); return; } List<Expression> list = new ArrayList<>(); final Map<String, Expression> map = new HashMap<>(); for (String fieldName : fields.keySet()) { FieldGen fieldGen = fields.get(fieldName); if (!fieldGen.hasVersion(version)) continue; fieldGen.serializer.prepareDeserializeStaticMethods( version, staticMethods, compatibilityLevel); Expression expression = let( fieldGen.serializer.deserialize( fieldGen.getRawType(), version, staticMethods, compatibilityLevel)); list.add(expression); map.put(fieldName, cast(expression, fieldGen.getRawType())); } Expression constructor; if (factory == null) { constructor = callConstructor(this.getRawType(), map, version); } else { constructor = callFactory(map, version); } Expression local = let(constructor); list.add(local); for (Method method : setters.keySet()) { boolean found = false; for (String fieldName : setters.get(method)) { FieldGen fieldGen = fields.get(fieldName); Preconditions.checkNotNull(fieldGen, "Field '%s' is not found in '%s'", fieldName, method); if (fieldGen.hasVersion(version)) { found = true; break; } } if (found) { Expression[] temp = new Expression[method.getParameterTypes().length]; int i = 0; for (String fieldName : setters.get(method)) { FieldGen fieldGen = fields.get(fieldName); assert fieldGen != null; if (fieldGen.hasVersion(version)) { temp[i++] = map.get(fieldName); } else { temp[i++] = pushDefaultValue(fieldGen.getAsmType()); } } list.add(call(local, method.getName(), temp)); } } for (String fieldName : fields.keySet()) { FieldGen fieldGen = fields.get(fieldName); if (!fieldGen.hasVersion(version)) continue; if (fieldGen.field == null || isFinal(fieldGen.field.getModifiers())) continue; Variable field = field(local, fieldName); list.add(set(field, map.get(fieldName))); } list.add(local); staticMethods.registerStaticDeserializeMethod(this, version, sequence(list)); }