Source:
<code><T> JsonAdapter<T> adapter(Type type, Set<? extends Annotation> annotations, @Nullable String fieldName) { if (type == null) { throw new NullPointerException("type == null"); } if (annotations == null) { throw new NullPointerException("annotations == null"); } type = canonicalize(type); Object cacheKey = cacheKey(type, annotations); synchronized (adapterCache) { JsonAdapter<?> result = adapterCache.get(cacheKey); if (result != null) return (JsonAdapter<T>) result; } List<DeferredAdapter<?>> deferredAdapters = reentrantCalls.get(); List<String> fieldNames; if (deferredAdapters != null) { for (int i = 0, size = deferredAdapters.size(); i < size; i++) { DeferredAdapter<?> deferredAdapter = deferredAdapters.get(i); if (deferredAdapter.cacheKey.equals(cacheKey)) { return (JsonAdapter<T>) deferredAdapter; } } fieldNames = this.fieldNames.get(); } else { deferredAdapters = new ArrayList<>(); reentrantCalls.set(deferredAdapters); fieldNames = new ArrayList<>(); this.fieldNames.set(fieldNames); } DeferredAdapter<T> deferredAdapter = new DeferredAdapter<>(cacheKey); deferredAdapters.add(deferredAdapter); int lastIndex = deferredAdapters.size() - 1; if (fieldName != null) { fieldNames.add(fieldName); } try { for (int i = 0, size = factories.size(); i < size; i++) { JsonAdapter<T> result = (JsonAdapter<T>) factories.get(i).create(type, annotations, this); if (result != null) { deferredAdapter.ready(result); synchronized (adapterCache) { adapterCache.put(cacheKey, result); } if (fieldName != null) { fieldNames.remove(fieldNames.size() - 1); } return result; } } } catch (RuntimeException e) { if (lastIndex == 0) { e = errorWithFields(type, fieldNames, e); } throw e; } finally { deferredAdapters.remove(lastIndex); if (deferredAdapters.isEmpty()) { reentrantCalls.remove(); this.fieldNames.remove(); } } <START> throw new IllegalArgumentException( <END> "No JsonAdapter for " + typeAnnotatedWithAnnotations(type, annotations)); }</code><technical_language>combine list deferred adapters. give a deferred adapter a name</technical_language>

Target:
public <T> JsonAdapter<T> adapter(Type type, Set<? extends Annotation> annotations, @Nullable String fieldName) { if (type == null) { throw new NullPointerException("type == null"); } if (annotations == null) { throw new NullPointerException("annotations == null"); } type = canonicalize(type); Object cacheKey = cacheKey(type, annotations); synchronized (adapterCache) { JsonAdapter<?> result = adapterCache.get(cacheKey); if (result != null) return (JsonAdapter<T>) result; } List<DeferredAdapter<?>> deferredAdapters = reentrantCalls.get(); if (deferredAdapters != null) { for (int i = 0, size = deferredAdapters.size(); i < size; i++) { DeferredAdapter<?> deferredAdapter = deferredAdapters.get(i); if (deferredAdapter.cacheKey.equals(cacheKey)) { return (JsonAdapter<T>) deferredAdapter; } } } else { deferredAdapters = new ArrayList<>(); reentrantCalls.set(deferredAdapters); } DeferredAdapter<T> deferredAdapter = new DeferredAdapter<>(type, fieldName, cacheKey); deferredAdapters.add(deferredAdapter); int lastIndex = deferredAdapters.size() - 1; try { for (int i = 0, size = factories.size(); i < size; i++) { JsonAdapter<T> result = (JsonAdapter<T>) factories.get(i).create(type, annotations, this); if (result != null) { deferredAdapter.ready(result); synchronized (adapterCache) { adapterCache.put(cacheKey, result); } deferredAdapters.remove(lastIndex); return result; } } } catch (IllegalArgumentException e) { if (lastIndex == 0) { e = errorWithFields(deferredAdapters, e); } throw e; } finally { if (lastIndex == 0) { reentrantCalls.remove(); } } throw new IllegalArgumentException( "No JsonAdapter for " + typeAnnotatedWithAnnotations(type, annotations)); }