--- /dev/null
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.codec.gson;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypedSchemaNode;
+
+/**
+ * A thread-safe lazily-populated codec factory. Instances are cached in an internal weak/soft cache.
+ *
+ * @author Robert Varga
+ */
+@ThreadSafe
+final class SharedJSONCodecFactory extends JSONCodecFactory {
+ // Weak keys to retire the entry when SchemaContext goes away and to force identity-based lookup
+ private static final LoadingCache<SchemaContext, SharedJSONCodecFactory> CACHE = CacheBuilder.newBuilder()
+ .weakKeys().build(new CacheLoader<SchemaContext, SharedJSONCodecFactory>() {
+ @Override
+ public SharedJSONCodecFactory load(final SchemaContext key) {
+ return new SharedJSONCodecFactory(key);
+ }
+ });
+
+ // Soft values to keep unreferenced codecs around for a bit, but eventually we want them to go away
+ private final LoadingCache<TypedSchemaNode, JSONCodec<?>> codecs = CacheBuilder.newBuilder().softValues()
+ .build(new CacheLoader<TypedSchemaNode, JSONCodec<?>>() {
+ @Override
+ public JSONCodec<?> load(@Nonnull final TypedSchemaNode key) {
+ return createCodec(key, key.getType());
+ }
+ });
+
+ SharedJSONCodecFactory(final SchemaContext context) {
+ super(context);
+ }
+
+ static SharedJSONCodecFactory getIfPresent(final SchemaContext context) {
+ return CACHE.getIfPresent(context);
+ }
+
+ static SharedJSONCodecFactory get(final SchemaContext context) {
+ return CACHE.getUnchecked(context);
+ }
+
+ @Override
+ JSONCodec<?> codecFor(final TypedSchemaNode schema) {
+ return codecs.getUnchecked(schema);
+ }
+}