Repository: amzn/ion-java (java)

Issue:
Disable LST append writing by default and add option to enable it
Follow-up to #178.

Pull request:
Disables LST append writing by default and adds option to enable it
Resolves #277 

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.


Patch:
diff --git a/src/com/amazon/ion/IonWriter.java b/src/com/amazon/ion/IonWriter.java
index dae9c08e..99270c6e 100644
--- a/src/com/amazon/ion/IonWriter.java
+++ b/src/com/amazon/ion/IonWriter.java
@@ -113,7 +113,9 @@ public interface IonWriter
      * In particular, when writing binary Ion data, Ion's length-prefixed
      * encoding requires a complete top-level value to be written at once.
      * <p>
-     * This feature can be used to flush buffered data before writing more
+     * If localSymbolTableAppend is enabled (see
+     * {@link com.amazon.ion.system.IonBinaryWriterBuilder#withLocalSymbolTableAppendEnabled}),
+     * this feature can be used to flush buffered data before writing more
      * values without subsequently having to redeclare the current local
      * symbol table. Applications that produce long streams of binary Ion may
      * wish to flush occasionally to relieve memory pressure, then continue
@@ -153,7 +155,9 @@ public interface IonWriter
      * number of unique symbols to avoid unbounded growth of the symbol table,
      * which may degrade performance and bloat the encoding. Applications that
      * produce long streams with a limited number of unique symbols should
-     * use {@link #flush()} instead to avoid re-declaring the local symbol
+     * enable localSymbolTableAppend (see
+     * {@link com.amazon.ion.system.IonBinaryWriterBuilder#withLocalSymbolTableAppendEnabled})
+     * and {@link #flush()} instead to avoid re-declaring the local symbol
      * table unnecessarily.
      *
      * @throws IOException if thrown by the underlying output target.
diff --git a/src/com/amazon/ion/impl/_Private_IonBinaryWriterBuilder.java b/src/com/amazon/ion/impl/_Private_IonBinaryWriterBuilder.java
index c92da72b..3465bd47 100644
--- a/src/com/amazon/ion/impl/_Private_IonBinaryWriterBuilder.java
+++ b/src/com/amazon/ion/impl/_Private_IonBinaryWriterBuilder.java
@@ -193,6 +193,36 @@ public class _Private_IonBinaryWriterBuilder
         return b;
     }
 
+    @Override
+    public void setLocalSymbolTableAppendEnabled(boolean enabled)
+    {
+        mutationCheck();
+        if (enabled)
+        {
+            myBinaryWriterBuilder.withLocalSymbolTableAppendEnabled();
+        }
+        else
+        {
+            myBinaryWriterBuilder.withLocalSymbolTableAppendDisabled();
+        }
+    }
+
+    @Override
+    public _Private_IonBinaryWriterBuilder withLocalSymbolTableAppendEnabled()
+    {
+        _Private_IonBinaryWriterBuilder b = mutable();
+        b.setLocalSymbolTableAppendEnabled(true);
+        return b;
+    }
+
+    @Override
+    public _Private_IonBinaryWriterBuilder withLocalSymbolTableAppendDisabled()
+    {
+        _Private_IonBinaryWriterBuilder b = mutable();
+        b.setLocalSymbolTableAppendEnabled(false);
+        return b;
+    }
+
     @Override
     public void setIsFloatBinary32Enabled(boolean enabled) {
         mutationCheck();
diff --git a/src/com/amazon/ion/impl/bin/IonManagedBinaryWriter.java b/src/com/amazon/ion/impl/bin/IonManagedBinaryWriter.java
index 2299baf2..003dc70a 100644
--- a/src/com/amazon/ion/impl/bin/IonManagedBinaryWriter.java
+++ b/src/com/amazon/ion/impl/bin/IonManagedBinaryWriter.java
@@ -659,6 +659,7 @@ import java.util.Map;
     private final List<SymbolTable>             userImports;
     private final List<String>                  userSymbols;
     private final ImportDescriptor              userCurrentImport;
+    private final boolean                       lstAppendEnabled;
     private boolean                             isUserLSTAppend;
 
     private boolean                             closed;
@@ -704,6 +705,7 @@ import java.util.Map;
         this.userImports = new ArrayList<SymbolTable>();
         this.userSymbols = new ArrayList<String>();
         this.userCurrentImport = new ImportDescriptor();
+        this.lstAppendEnabled = builder.isLocalSymbolTableAppendEnabled;
         this.isUserLSTAppend = false;
 
         // TODO decide if initial LST should survive finish() and seed the next LST
@@ -765,7 +767,7 @@ import java.util.Map;
 
     private void startLocalSymbolTableIfNeeded(final boolean writeIVM) throws IOException
     {
-        boolean isAppend = symbolState == SymbolState.LOCAL_SYMBOLS_FLUSHED;
+        boolean isAppend = symbolState == SymbolState.LOCAL_SYMBOLS_FLUSHED && lstAppendEnabled;
         if (symbolState == SymbolState.SYSTEM_SYMBOLS || isAppend)
         {
             if (writeIVM && !isAppend)
@@ -1103,7 +1105,7 @@ import java.util.Map;
 
     public void flush() throws IOException
     {
-        if (getDepth() == 0 && !user.hasAnnotations())
+        if (getDepth() == 0 && !user.hasAnnotations() && (localsLocked || lstAppendEnabled))
         {
             unsafeFlush();
         }
diff --git a/src/com/amazon/ion/impl/bin/_Private_IonManagedBinaryWriterBuilder.java b/src/com/amazon/ion/impl/bin/_Private_IonManagedBinaryWriterBuilder.java
index 8c1dd6aa..b439d160 100644
--- a/src/com/amazon/ion/impl/bin/_Private_IonManagedBinaryWriterBuilder.java
+++ b/src/com/amazon/ion/impl/bin/_Private_IonManagedBinaryWriterBuilder.java
@@ -77,6 +77,7 @@ public final class _Private_IonManagedBinaryWriterBuilder
     /*package*/ volatile IonCatalog             catalog;
     /*package*/ volatile WriteValueOptimization optimization;
     /*package*/ volatile SymbolTable            initialSymbolTable;
+    /*package*/ volatile boolean                isLocalSymbolTableAppendEnabled;
     /*package*/ volatile boolean                isFloatBinary32Enabled;
 
     private _Private_IonManagedBinaryWriterBuilder(final BlockAllocatorProvider provider)
@@ -88,6 +89,7 @@ public final class _Private_IonManagedBinaryWriterBuilder
         this.preallocationMode = PreallocationMode.PREALLOCATE_2;
         this.catalog = new SimpleCatalog();
         this.optimization = WriteValueOptimization.NONE;
+        this.isLocalSymbolTableAppendEnabled = false;
         this.isFloatBinary32Enabled = false;
     }
 
@@ -101,6 +103,7 @@ public final class _Private_IonManagedBinaryWriterBuilder
         this.catalog            = other.catalog;
         this.optimization       = other.optimization;
         this.initialSymbolTable = other.initialSymbolTable;
+        this.isLocalSymbolTableAppendEnabled = other.isLocalSymbolTableAppendEnabled;
         this.isFloatBinary32Enabled = other.isFloatBinary32Enabled;
     }
 
@@ -193,6 +196,18 @@ public final class _Private_IonManagedBinaryWriterBuilder
         return this;
     }
 
+    public _Private_IonManagedBinaryWriterBuilder withLocalSymbolTableAppendEnabled()
+    {
+        isLocalSymbolTableAppendEnabled = true;
+        return this;
+    }
+
+    public _Private_IonManagedBinaryWriterBuilder withLocalSymbolTableAppendDisabled()
+    {
+        isLocalSymbolTableAppendEnabled = false;
+        return this;
+    }
+
     public _Private_IonManagedBinaryWriterBuilder withFloatBinary32Enabled() {
         isFloatBinary32Enabled = true;
         return this;
diff --git a/src/com/amazon/ion/system/IonBinaryWriterBuilder.java b/src/com/amazon/ion/system/IonBinaryWriterBuilder.java
index c6d6a0e5..b6b40257 100644
--- a/src/com/amazon/ion/system/IonBinaryWriterBuilder.java
+++ b/src/com/amazon/ion/system/IonBinaryWriterBuilder.java
@@ -174,6 +174,27 @@ public abstract class IonBinaryWriterBuilder
     IonBinaryWriterBuilder withInitialSymbolTable(SymbolTable symtab);
 
 
+    /**
+     * Enables or disables writing local symbol tables that append symbols
+     * to the current symbol table.  This functionality is disabled by default.
+     */
+    public abstract void setLocalSymbolTableAppendEnabled(boolean enabled);
+
+
+    /**
+     * Enables writing local symbol tables that append symbols to the current
+     * symbol table.  This functionality is disabled by default.
+     */
+    public abstract IonBinaryWriterBuilder withLocalSymbolTableAppendEnabled();
+
+
+    /**
+     * Disables writing local symbol tables that append symbols to the current
+     * symbol table.  This functionality is disabled by default.
+     */
+    public abstract IonBinaryWriterBuilder withLocalSymbolTableAppendDisabled();
+
+
     /**
      * Enables or disables writing Binary32 (4-byte, single precision,
      * IEEE-754) values for floats when there would be no loss in precision.


Test patch:
diff --git a/test/com/amazon/ion/impl/BinaryWriterTest.java b/test/com/amazon/ion/impl/BinaryWriterTest.java
index 7110e152..8ab10fdc 100644
--- a/test/com/amazon/ion/impl/BinaryWriterTest.java
+++ b/test/com/amazon/ion/impl/BinaryWriterTest.java
@@ -28,6 +28,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import com.amazon.ion.system.IonBinaryWriterBuilder;
 import com.amazon.ion.system.IonReaderBuilder;
 import com.amazon.ion.system.SimpleCatalog;
 import org.junit.Assert;
@@ -41,7 +42,10 @@ public class BinaryWriterTest
         throws Exception
     {
         myOutputForm = OutputForm.BINARY;
-        return system().newBinaryWriter(out, imports);
+        IonBinaryWriterBuilder builder = IonBinaryWriterBuilder.standard()
+                .withImports(imports);
+        builder.setLocalSymbolTableAppendEnabled(myLstAppendEnabled);
+        return builder.build(out);
     }
 
     @Test
@@ -123,6 +127,29 @@ public class BinaryWriterTest
     public void testFlushingUnlockedSymtab()
     throws Exception
     {
+        byte[] bytes = flushUnlockedSymtab(false);
+        assertEquals(0, bytes.length);
+    }
+
+    @Test
+    public void testFlushingUnlockedSymtabWithLSTAppend()
+    throws Exception
+    {
+        byte[] bytes = flushUnlockedSymtab(true);
+
+        // iw.flush() should have caused an appended LST to be written before the next value.
+        IonReader reader = IonReaderBuilder.standard().build(bytes);
+        assertEquals(IonType.SYMBOL, reader.next());
+        assertEquals("force a local symtab", reader.stringValue());
+        assertEquals(IonType.SYMBOL, reader.next());
+        assertEquals("fred_1", reader.stringValue());
+        assertNull(reader.next());
+    }
+
+    private byte[] flushUnlockedSymtab(boolean lstAppendEnabled)
+    throws Exception
+    {
+        myLstAppendEnabled = lstAppendEnabled;
         iw = makeWriter();
         iw.writeSymbol("force a local symtab");
         SymbolTable symtab = iw.getSymbolTable();
@@ -130,14 +157,8 @@ public class BinaryWriterTest
         symtab.intern("fred_2");
 
         iw.writeSymbol("fred_1");
-        // This would cause an appended LST to be written before the next value.
         iw.flush();
-        IonReader reader = IonReaderBuilder.standard().build(myOutputStream.toByteArray());
-        assertEquals(IonType.SYMBOL, reader.next());
-        assertEquals("force a local symtab", reader.stringValue());
-        assertEquals(IonType.SYMBOL, reader.next());
-        assertEquals("fred_1", reader.stringValue());
-        assertNull(reader.next());
+        return myOutputStream.toByteArray();
     }
 
     @Test
@@ -145,15 +166,34 @@ public class BinaryWriterTest
     throws Exception
     {
         SimpleCatalog catalog = catalog();
+        byte[] bytes = flushUnlockedSymtabWithImports(catalog, false);
+        assertEquals(0, bytes.length);
+    }
+
+    @Test
+    public void testFlushingUnlockedSymtabWithImportsWithLSTAppend()
+    throws Exception
+    {
+        SimpleCatalog catalog = catalog();
+        byte[] bytes = flushUnlockedSymtabWithImports(catalog, true);
+
+        IonReader reader = IonReaderBuilder.standard().withCatalog(catalog).build(bytes);
+        assertEquals(IonType.SYMBOL, reader.next());
+        assertEquals("fred_1", reader.stringValue());
+        assertNull(reader.next());
+    }
+
+
+    private byte[] flushUnlockedSymtabWithImports(SimpleCatalog catalog, boolean lstAppendEnabled)
+    throws Exception
+    {
         SymbolTable fred1 = Symtabs.register("fred",   1, catalog);
+        myLstAppendEnabled = lstAppendEnabled;
         iw = makeWriter(fred1);
         iw.writeSymbol("fred_1");
         // This would cause an appended LST to be written before the next value.
         iw.flush();
-        IonReader reader = IonReaderBuilder.standard().withCatalog(catalog).build(myOutputStream.toByteArray());
-        assertEquals(IonType.SYMBOL, reader.next());
-        assertEquals("fred_1", reader.stringValue());
-        assertNull(reader.next());
+        return myOutputStream.toByteArray();
     }
 
     @Test
diff --git a/test/com/amazon/ion/impl/IonWriterTestCase.java b/test/com/amazon/ion/impl/IonWriterTestCase.java
index 505a756e..82f8e619 100644
--- a/test/com/amazon/ion/impl/IonWriterTestCase.java
+++ b/test/com/amazon/ion/impl/IonWriterTestCase.java
@@ -72,6 +72,8 @@ public abstract class IonWriterTestCase
 
     OutputForm myOutputForm;
 
+    boolean myLstAppendEnabled = false;
+
     protected IonWriter iw;
 
     @Rule
@@ -799,6 +801,21 @@ public abstract class IonWriterTestCase
     public void testFlushDoesNotReset()
     throws Exception
     {
+        flushDoesNotReset(false);
+    }
+
+    @Test
+    public void testFlushDoesNotResetWithLstAppend()
+    throws Exception
+    {
+        flushDoesNotReset(true);
+    }
+
+    private void flushDoesNotReset(boolean lstAppendEnabled)
+    throws Exception
+    {
+        myLstAppendEnabled = lstAppendEnabled;
+
         SymbolTable fred1 = Symtabs.register("fred",   1, catalog());
         iw = makeWriter(fred1);
         iw.writeSymbol("hey");
@@ -807,7 +824,7 @@ public abstract class IonWriterTestCase
         iw.close();
 
         IonDatagram dg = reload();
-        if (myOutputForm == OutputForm.BINARY && iw instanceof _Private_IonManagedWriter) {
+        if (myOutputForm == OutputForm.BINARY && iw instanceof _Private_IonManagedWriter && myLstAppendEnabled) {
             // Note: LST append will only be implemented in the "new" binary writer (which implements
             // _Private_IonMangedWriter)
             // Should have:  IVM SYMTAB hey SYMTAB_APPEND now
diff --git a/test/com/amazon/ion/impl/bin/IonManagedBinaryWriterTest.java b/test/com/amazon/ion/impl/bin/IonManagedBinaryWriterTest.java
index 416abc96..033ad91c 100644
--- a/test/com/amazon/ion/impl/bin/IonManagedBinaryWriterTest.java
+++ b/test/com/amazon/ion/impl/bin/IonManagedBinaryWriterTest.java
@@ -43,6 +43,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+
 import org.junit.Test;
 
 @SuppressWarnings("deprecation")
@@ -81,6 +82,21 @@ public class IonManagedBinaryWriterTest extends IonRawBinaryWriterTest
         SHARED_SYMBOL_LOCAL_SIDS = unmodifiableMap(sidMap);
     }
 
+    private enum LSTAppendMode
+    {
+        LST_APPEND_DISABLED,
+        LST_APPEND_ENABLED;
+        public boolean isEnabled() { return this == LST_APPEND_ENABLED; }
+    }
+
+    @Inject("lstAppendMode")
+    public static final LSTAppendMode[] LST_APPEND_ENABLED_DIMENSIONS = LSTAppendMode.values();
+    private LSTAppendMode lstAppendMode;
+    public void setLstAppendMode(final LSTAppendMode mode)
+    {
+        this.lstAppendMode = mode;
+    }
+
     private void checkSymbolTokenAgainstImport(final SymbolToken token)
     {
         final Integer sid = SHARED_SYMBOL_LOCAL_SIDS.get(token.getText());
@@ -139,12 +155,19 @@ public class IonManagedBinaryWriterTest extends IonRawBinaryWriterTest
             catalog.putTable(table);
         }
 
-        final IonWriter writer = _Private_IonManagedBinaryWriterBuilder
+        final _Private_IonManagedBinaryWriterBuilder builder = _Private_IonManagedBinaryWriterBuilder
             .create(AllocatorMode.POOLED)
             .withImports(importedSymbolResolverMode, symbolTables)
             .withPreallocationMode(preallocationMode)
-            .withFloatBinary32Enabled()
-            .newWriter(out);
+            .withFloatBinary32Enabled();
+
+        if (lstAppendMode.isEnabled()) {
+            builder.withLocalSymbolTableAppendEnabled();
+        } else {
+            builder.withLocalSymbolTableAppendDisabled();
+        }
+
+        final IonWriter writer = builder.newWriter(out);
 
         final SymbolTable locals = writer.getSymbolTable();
         assertEquals(14, locals.getImportedMaxId());
@@ -190,22 +213,34 @@ public class IonManagedBinaryWriterTest extends IonRawBinaryWriterTest
         writer.flush();
         writer.writeSymbol("burrito");
         writer.finish();
+
         IonReader reader = system().newReader(writer.getBytes());
         reader.next();
         assertEquals(reader.getSymbolTable().findSymbol("taco"), 15);
-        assertEquals(reader.getSymbolTable().findSymbol("burrito"), -1);
+        assertEquals(reader.getSymbolTable().findSymbol("burrito"), lstAppendMode.isEnabled() ? -1 : 16);
         reader.next();
         assertEquals(reader.getSymbolTable().findSymbol("taco"), 15);
         assertEquals(reader.getSymbolTable().findSymbol("burrito"), 16);
         assertNull(reader.next());
 
         IonDatagram dg = system().getLoader().load(writer.getBytes());
-        // Should be IVM SYMTAB taco SYMTAB burrito
-        assertEquals(5, dg.systemSize());
-        assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(1)).getTypeAnnotations()[0]);
-        assertEquals("taco", ((IonSymbol) dg.systemGet(2)).stringValue());
-        assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(3)).getTypeAnnotations()[0]);
-        assertEquals("burrito", ((IonSymbol) dg.systemGet(4)).stringValue());
+        if (lstAppendMode.isEnabled())
+        {
+            // Should be IVM SYMTAB taco SYMTAB burrito
+            assertEquals(5, dg.systemSize());
+            assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(1)).getTypeAnnotations()[0]);
+            assertEquals("taco", ((IonSymbol) dg.systemGet(2)).stringValue());
+            assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(3)).getTypeAnnotations()[0]);
+            assertEquals("burrito", ((IonSymbol) dg.systemGet(4)).stringValue());
+        }
+        else
+        {
+            // Should be IVM SYMTAB taco burrito
+            assertEquals(4, dg.systemSize());
+            assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(1)).getTypeAnnotations()[0]);
+            assertEquals("taco", ((IonSymbol) dg.systemGet(2)).stringValue());
+            assertEquals("burrito", ((IonSymbol) dg.systemGet(3)).stringValue());
+        }
     }
 
     @Test
@@ -259,22 +294,33 @@ public class IonManagedBinaryWriterTest extends IonRawBinaryWriterTest
         writer.writeSymbol("burrito");
         writer.finish();
 
-        IonDatagram dg = system().getLoader().load(writer.getBytes());
-        // Should be IVM SYMTAB taco SYMTAB burrito
-        assertEquals(5, dg.systemSize());
-        assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(1)).getTypeAnnotations()[0]);
-        assertEquals("taco", ((IonSymbol) dg.systemGet(2)).stringValue());
-        assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(3)).getTypeAnnotations()[0]);
-        assertEquals("burrito", ((IonSymbol) dg.systemGet(4)).stringValue());
-
         IonReader reader = system().newReader(writer.getBytes());
         reader.next();
         assertEquals(reader.getSymbolTable().findSymbol("taco"), 15);
-        assertEquals(reader.getSymbolTable().findSymbol("burrito"), -1);
+        assertEquals(reader.getSymbolTable().findSymbol("burrito"), lstAppendMode.isEnabled() ? -1 : 16);
         reader.next();
         assertEquals(reader.getSymbolTable().findSymbol("taco"), 15);
         assertEquals(reader.getSymbolTable().findSymbol("burrito"), 16);
         assertNull(reader.next());
+
+        IonDatagram dg = system().getLoader().load(writer.getBytes());
+        if (lstAppendMode.isEnabled())
+        {
+            // Should be IVM SYMTAB taco SYMTAB burrito
+            assertEquals(5, dg.systemSize());
+            assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(1)).getTypeAnnotations()[0]);
+            assertEquals("taco", ((IonSymbol) dg.systemGet(2)).stringValue());
+            assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(3)).getTypeAnnotations()[0]);
+            assertEquals("burrito", ((IonSymbol) dg.systemGet(4)).stringValue());
+        }
+        else
+        {
+            // Should be IVM SYMTAB taco burrito
+            assertEquals(4, dg.systemSize());
+            assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(1)).getTypeAnnotations()[0]);
+            assertEquals("taco", ((IonSymbol) dg.systemGet(2)).stringValue());
+            assertEquals("burrito", ((IonSymbol) dg.systemGet(3)).stringValue());
+        }
     }
 
     @Test
@@ -293,22 +339,33 @@ public class IonManagedBinaryWriterTest extends IonRawBinaryWriterTest
         writer.writeSymbol("burrito");
         writer.finish();
 
-        IonDatagram dg = system().getLoader().load(writer.getBytes());
-        // Should be IVM SYMTAB taco SYMTAB burrito
-        assertEquals(5, dg.systemSize());
-        assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(1)).getTypeAnnotations()[0]);
-        assertEquals("taco", ((IonSymbol) dg.systemGet(2)).stringValue());
-        assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(3)).getTypeAnnotations()[0]);
-        assertEquals("burrito", ((IonSymbol) dg.systemGet(4)).stringValue());
-
         IonReader reader = system().newReader(writer.getBytes());
         reader.next();
         assertEquals(reader.getSymbolTable().findSymbol("taco"), 15);
-        assertEquals(reader.getSymbolTable().findSymbol("burrito"), -1);
+        assertEquals(reader.getSymbolTable().findSymbol("burrito"), lstAppendMode.isEnabled() ? -1 : 16);
         reader.next();
         assertEquals(reader.getSymbolTable().findSymbol("taco"), 15);
         assertEquals(reader.getSymbolTable().findSymbol("burrito"), 16);
         assertNull(reader.next());
+
+        IonDatagram dg = system().getLoader().load(writer.getBytes());
+        if (lstAppendMode.isEnabled())
+        {
+            // Should be IVM SYMTAB taco SYMTAB burrito
+            assertEquals(5, dg.systemSize());
+            assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(1)).getTypeAnnotations()[0]);
+            assertEquals("taco", ((IonSymbol) dg.systemGet(2)).stringValue());
+            assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(3)).getTypeAnnotations()[0]);
+            assertEquals("burrito", ((IonSymbol) dg.systemGet(4)).stringValue());
+        }
+        else
+        {
+            // Should be IVM SYMTAB taco burrito
+            assertEquals(4, dg.systemSize());
+            assertEquals("$ion_symbol_table", ((IonStruct) dg.systemGet(1)).getTypeAnnotations()[0]);
+            assertEquals("taco", ((IonSymbol) dg.systemGet(2)).stringValue());
+            assertEquals("burrito", ((IonSymbol) dg.systemGet(3)).stringValue());
+        }
     }
 
     @Test