+
+ @Override
+ protected ExtensionStatement createDeclared(final StmtContext<QName, ExtensionStatement, ?> ctx,
+ final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+ return new RegularExtensionStatement(ctx.getArgument(), substatements);
+ }
+
+ @Override
+ protected ExtensionStatement createEmptyDeclared(final StmtContext<QName, ExtensionStatement, ?> ctx) {
+ return new EmptyExtensionStatement(ctx.getArgument());
+ }
+
+ @Override
+ public ExtensionEffectiveStatement createEffective(final Current<QName, ExtensionStatement> stmt,
+ final Stream<? extends StmtContext<?, ?, ?>> declaredSubstatements,
+ final Stream<? extends StmtContext<?, ?, ?>> effectiveSubstatements) {
+ Map<StmtContext<?, ?, ?>, ExtensionEffectiveStatementImpl> tl = TL_BUILDERS.get();
+ if (tl == null) {
+ tl = new IdentityHashMap<>();
+ TL_BUILDERS.set(tl);
+ }
+
+ final StmtContext<?, ?, ?> ctx = stmt.caerbannog();
+ final ExtensionEffectiveStatementImpl existing = tl.get(ctx);
+ if (existing != null) {
+ // Implies non-empty map, no cleanup necessary
+ return existing;
+ }
+
+ try {
+ final ExtensionEffectiveStatementImpl created = new ExtensionEffectiveStatementImpl(stmt.declared(),
+ stmt.getSchemaPath());
+ verify(tl.put(ctx, created) == null);
+ try {
+ return super.createEffective(stmt, declaredSubstatements, effectiveSubstatements);
+ } finally {
+ verify(tl.remove(ctx) == created);
+ }
+ } finally {
+ if (tl.isEmpty()) {
+ TL_BUILDERS.remove();
+ }
+ }
+ }
+
+ @Override
+ protected ExtensionEffectiveStatement createEffective(final Current<QName, ExtensionStatement> stmt,
+ final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+ final ExtensionEffectiveStatementImpl ret = verifyNotNull(verifyNotNull(TL_BUILDERS.get(),
+ "Statement build state not initialized").get(stmt.caerbannog()), "No build state found for %s", stmt);
+ ret.setSubstatements(substatements);
+ return ret;
+ }