
com.jsoniter.Codegen Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jsoniter Show documentation
Show all versions of jsoniter Show documentation
jsoniter (json-iterator) is fast and flexible JSON parser available in Java and Go
package com.jsoniter;
import com.jsoniter.spi.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.*;
class Codegen {
// only read/write when generating code with synchronized protection
private final static Set generatedClassNames = new HashSet();
static CodegenAccess.StaticCodegenTarget isDoingStaticCodegen = null;
static Decoder getDecoder(String cacheKey, Type type) {
Decoder decoder = JsoniterSpi.getDecoder(cacheKey);
if (decoder != null) {
return decoder;
}
return gen(cacheKey, type);
}
private synchronized static Decoder gen(String cacheKey, Type type) {
Decoder decoder = JsoniterSpi.getDecoder(cacheKey);
if (decoder != null) {
return decoder;
}
List extensions = JsoniterSpi.getExtensions();
for (Extension extension : extensions) {
type = extension.chooseImplementation(type);
}
type = chooseImpl(type);
for (Extension extension : extensions) {
decoder = extension.createDecoder(cacheKey, type);
if (decoder != null) {
JsoniterSpi.addNewDecoder(cacheKey, decoder);
return decoder;
}
}
ClassInfo classInfo = new ClassInfo(type);
decoder = CodegenImplNative.NATIVE_DECODERS.get(classInfo.clazz);
if (decoder != null) {
return decoder;
}
addPlaceholderDecoderToSupportRecursiveStructure(cacheKey);
try {
Config currentConfig = JsoniterSpi.getCurrentConfig();
DecodingMode mode = currentConfig.decodingMode();
if (mode == DecodingMode.REFLECTION_MODE) {
decoder = ReflectionDecoderFactory.create(classInfo);
return decoder;
}
if (isDoingStaticCodegen == null) {
try {
decoder = (Decoder) Class.forName(cacheKey).newInstance();
return decoder;
} catch (Exception e) {
if (mode == DecodingMode.STATIC_MODE) {
throw new JsonException("static gen should provide the decoder we need, but failed to create the decoder", e);
}
}
}
String source = genSource(mode, classInfo);
source = "public static java.lang.Object decode_(com.jsoniter.JsonIterator iter) throws java.io.IOException { "
+ source + "}";
if ("true".equals(System.getenv("JSONITER_DEBUG"))) {
System.out.println(">>> " + cacheKey);
System.out.println(source);
}
try {
generatedClassNames.add(cacheKey);
if (isDoingStaticCodegen == null) {
decoder = DynamicCodegen.gen(cacheKey, source);
} else {
staticGen(cacheKey, source);
}
return decoder;
} catch (Exception e) {
String msg = "failed to generate decoder for: " + classInfo + " with " + Arrays.toString(classInfo.typeArgs) + ", exception: " + e;
msg = msg + "\n" + source;
throw new JsonException(msg, e);
}
} finally {
JsoniterSpi.addNewDecoder(cacheKey, decoder);
}
}
private static void addPlaceholderDecoderToSupportRecursiveStructure(final String cacheKey) {
JsoniterSpi.addNewDecoder(cacheKey, new Decoder() {
@Override
public Object decode(JsonIterator iter) throws IOException {
Decoder decoder = JsoniterSpi.getDecoder(cacheKey);
if (this == decoder) {
for(int i = 0; i < 30; i++) {
decoder = JsoniterSpi.getDecoder(cacheKey);
if (this == decoder) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new JsonException(e);
}
} else {
break;
}
}
if (this == decoder) {
throw new JsonException("internal error: placeholder is not replaced with real decoder");
}
}
return decoder.decode(iter);
}
});
}
public static boolean canStaticAccess(String cacheKey) {
return generatedClassNames.contains(cacheKey);
}
private static Type chooseImpl(Type type) {
Type[] typeArgs = new Type[0];
Class clazz;
if (type instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) type;
clazz = (Class) pType.getRawType();
typeArgs = pType.getActualTypeArguments();
} else if (type instanceof WildcardType) {
return Object.class;
} else {
clazz = (Class) type;
}
Class implClazz = JsoniterSpi.getTypeImplementation(clazz);
if (Collection.class.isAssignableFrom(clazz)) {
Type compType = Object.class;
if (typeArgs.length == 0) {
// default to List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy