From 3f92b949117ab41d4da4b78bf59b3a3cf54c7945 Mon Sep 17 00:00:00 2001 From: Tyler Gregg Date: Mon, 21 Oct 2024 14:18:03 -0700 Subject: [PATCH] Fixes reading of macro table appends. (#979) --- .../com/amazon/ion/impl/IonCursorBinary.java | 1 + .../amazon/ion/impl/macro/EncodingContext.kt | 9 ++- .../EncodingDirectiveCompilationTest.java | 61 +++++++++++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/amazon/ion/impl/IonCursorBinary.java b/src/main/java/com/amazon/ion/impl/IonCursorBinary.java index c5f3ae9ad..faa80f595 100644 --- a/src/main/java/com/amazon/ion/impl/IonCursorBinary.java +++ b/src/main/java/com/amazon/ion/impl/IonCursorBinary.java @@ -2417,6 +2417,7 @@ private boolean slowReadHeader(final int typeIdByte, final boolean isAnnotated, } if (minorVersion == 1) { if (valueTid.isMacroInvocation) { + setCheckpointAfterValueHeader(); return true; } if (valueTid.isNull && valueTid.length > 0) { diff --git a/src/main/java/com/amazon/ion/impl/macro/EncodingContext.kt b/src/main/java/com/amazon/ion/impl/macro/EncodingContext.kt index 13a52251c..2f6293f75 100644 --- a/src/main/java/com/amazon/ion/impl/macro/EncodingContext.kt +++ b/src/main/java/com/amazon/ion/impl/macro/EncodingContext.kt @@ -1,12 +1,15 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazon.ion.impl.macro /** * When we implement modules, this will likely need to be replaced. * For now, it is a placeholder for what is to come and a container for the macro table. */ -class EncodingContext( - val macroTable: Map -) { +class EncodingContext(macroTable: Map) { + + val macroTable = macroTable.toMutableMap() + companion object { // TODO: Replace this with a DEFAULT encoding context that includes system macros. @JvmStatic diff --git a/src/test/java/com/amazon/ion/impl/EncodingDirectiveCompilationTest.java b/src/test/java/com/amazon/ion/impl/EncodingDirectiveCompilationTest.java index 29ba9a6a1..b437ac7af 100644 --- a/src/test/java/com/amazon/ion/impl/EncodingDirectiveCompilationTest.java +++ b/src/test/java/com/amazon/ion/impl/EncodingDirectiveCompilationTest.java @@ -1321,6 +1321,67 @@ public void multipleListsWithinSymbolTableDeclaration(InputType inputType, Strea } } + @ParameterizedTest(name = "{0},{1}") + @MethodSource("allCombinations") + public void emptyMacroAppendToEmptyTable(InputType inputType, StreamType streamType) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + IonRawWriter_1_1 writer = streamType.newWriter(out); + writer.writeIVM(); + + startEncodingDirective(writer); + startMacroTable(writer); + writer.writeSymbol(SystemSymbols_1_1.ION_ENCODING); + endMacroTable(writer); + endEncodingDirective(writer); + + byte[] data = getBytes(writer, out); + try (IonReader reader = inputType.newReader(data)) { + assertNull(reader.next()); + } + } + + @ParameterizedTest(name = "{0},{1}") + @MethodSource("allCombinations") + public void emptyMacroAppendToNonEmptyTable(InputType inputType, StreamType streamType) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + IonRawWriter_1_1 writer = streamType.newWriter(out); + writer.writeIVM(); + + SortedMap macroTable = new TreeMap<>(); + macroTable.put("foo", new TemplateMacro( + Collections.singletonList(new Macro.Parameter("foo", Macro.ParameterEncoding.Tagged, Macro.ParameterCardinality.ExactlyOne)), + Collections.singletonList(new Expression.VariableRef(0)) + )); + Map symbols = Collections.emptyMap(); + + startEncodingDirective(writer); { + startMacroTable(writer); { + startMacro(writer, symbols, "foo"); { + writeMacroSignature(writer, symbols, "x"); + writeVariableExpansion(writer, symbols, "x"); + } endMacro(writer); + } endMacroTable(writer); + } endEncodingDirective(writer); + + + startEncodingDirective(writer); { + startMacroTable(writer); { + writer.writeSymbol(SystemSymbols_1_1.ION_ENCODING); + } endMacroTable(writer); + writeEncodingDirectiveSymbolTable(writer, true, "bar"); + } endEncodingDirective(writer); + + writer.stepInEExp(0, true, macroTable.get("foo")); { + writer.writeSymbol(1); + } writer.stepOut(); + + byte[] data = getBytes(writer, out); + try (IonReader reader = inputType.newReader(data)) { + assertEquals(IonType.SYMBOL, reader.next()); + assertEquals("bar", reader.stringValue()); + } + } + // TODO cover every Ion type // TODO annotations in macro definition (using 'annotate' system macro) // TODO test error conditions