Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use default module instead of $ion_encoding #1007

Merged
merged 3 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ion-tests
14 changes: 2 additions & 12 deletions src/main/java/com/amazon/ion/SystemSymbols.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,7 @@ private SystemSymbols() { }
// Ion 1.1 Symbols

/**
* The annotation that denotes an Ion encoding directive in Ion 1.1+.
* The name of the default module in Ion 1.1
*/
public static final String ION_ENCODING = "$ion_encoding";

/**
* The name of the symbol table s-expression within an Ion encoding directive.
*/
public static final String SYMBOL_TABLE = "symbol_table";

/**
* The name of the macro table s-expression within an Ion encoding directive.
*/
public static final String MACRO_TABLE = "macro_table";
public static final String DEFAULT_MODULE = "_";
}
72 changes: 56 additions & 16 deletions src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package com.amazon.ion.impl

import com.amazon.ion.*
import com.amazon.ion.SystemSymbols.*
import com.amazon.ion.impl.macro.*
import com.amazon.ion.impl.macro.MacroRef.Companion.byId
import com.amazon.ion.impl.macro.MacroRef.Companion.byName
Expand All @@ -28,22 +29,39 @@
var isMacroTableAlreadyClassified = false

private enum class State {
IN_ION_ENCODING_SEXP,
IN_DIRECTIVE_SEXP,
IN_MODULE_DIRECTIVE_SEXP_AWAITING_MODULE_NAME,
IN_MODULE_DIRECTIVE_SEXP,
IN_SYMBOL_TABLE_SEXP,
IN_SYMBOL_TABLE_LIST,
IN_MACRO_TABLE_SEXP,
COMPILING_MACRO,
READING_VALUE
}

private fun classifySexpWithinEncodingDirective() {
private fun classifyDirective() {
errorIf(reader.type != IonType.SYMBOL) { "Ion encoding directives must start with a directive keyword; found ${reader.type}" }
val name: String = reader.stringValue()
// TODO: Add support for `import` and `encoding` directives
if (SystemSymbols_1_1.MODULE.text == name) {
state = State.IN_MODULE_DIRECTIVE_SEXP_AWAITING_MODULE_NAME
} else if (SystemSymbols_1_1.IMPORT.text == name) {
throw IonException("'import' directive not yet supported")

Check warning on line 49 in src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt#L49

Added line #L49 was not covered by tests
} else if (SystemSymbols_1_1.ENCODING.text == name) {
throw IonException("'encoding' directive not yet supported")

Check warning on line 51 in src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt#L51

Added line #L51 was not covered by tests
} else {
throw IonException(String.format("'%s' is not a valid directive keyword", name))

Check warning on line 53 in src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt#L53

Added line #L53 was not covered by tests
}
}

private fun classifySexpWithinModuleDirective() {
val name: String = reader.stringValue()
state = if (SystemSymbols_1_1.SYMBOL_TABLE.text == name) {
State.IN_SYMBOL_TABLE_SEXP
} else if (SystemSymbols_1_1.MACRO_TABLE.text == name) {
State.IN_MACRO_TABLE_SEXP
} else {
throw IonException(String.format("\$ion_encoding expressions '%s' not supported.", name))
throw IonException("'$name' clause not supported in module definition")

Check warning on line 64 in src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt#L64

Added line #L64 was not covered by tests
}
}

Expand All @@ -64,7 +82,7 @@
}
isSymbolTableAlreadyClassified = true
if (IonType.isText(type)) {
if (SystemSymbols.ION_ENCODING == reader.stringValue() && !isSymbolTableAppend) {
if (DEFAULT_MODULE == reader.stringValue() && !isSymbolTableAppend) {
isSymbolTableAppend = true
if (reader.next() == null) {
return true
Expand All @@ -73,10 +91,10 @@
throw IonException("symbol_table s-expression must begin with a list.")
}
} else {
throw IonException("symbol_table s-expression must begin with either \$ion_encoding or a list.")
throw IonException("symbol_table s-expression must begin with either '_' or a list.")

Check warning on line 94 in src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt#L94

Added line #L94 was not covered by tests
}
} else if (type != IonType.LIST) {
throw IonException("symbol_table s-expression must begin with either \$ion_encoding or a list.")
throw IonException("symbol_table s-expression must begin with either '_' or a list.")

Check warning on line 97 in src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt#L97

Added line #L97 was not covered by tests
}
reader.stepIn()
state = State.IN_SYMBOL_TABLE_LIST
Expand All @@ -98,7 +116,7 @@
}
isMacroTableAlreadyClassified = true
if (IonType.isText(type)) {
if (SystemSymbols.ION_ENCODING == reader.stringValue() && !isMacroTableAppend) {
if (SystemSymbols.DEFAULT_MODULE == reader.stringValue() && !isMacroTableAppend) {
isMacroTableAppend = true
if (reader.next() == null) {
return true
Expand All @@ -107,16 +125,27 @@
throw IonException("macro_table s-expression must begin with s-expression(s).")
}
} else {
throw IonException("macro_table s-expression must begin with either \$ion_encoding or s-expression(s).")
throw IonException("macro_table s-expression must begin with either '_' or s-expression(s).")
}
} else if (type == IonType.SEXP) {
localMacroMaxOffset = -1
} else {
throw IonException("macro_table s-expression must begin with either \$ion_encoding or s-expression(s).")
throw IonException("macro_table s-expression must begin with either '_' or s-expression(s).")
}
return false
}

/**
* Utility function to make error cases more concise.
* @param condition the condition under which an IonException should be thrown
* @param lazyErrorMessage the message to use in the exception
*/
private inline fun errorIf(condition: Boolean, lazyErrorMessage: () -> String) {
if (condition) {
throw IonException(lazyErrorMessage())

Check warning on line 145 in src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt#L145

Added line #L145 was not covered by tests
}
}

Check warning on line 147 in src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt#L147

Added line #L147 was not covered by tests

/**
* Reads an encoding directive. After this method returns, the caller should access this class's properties to
* retrieve the symbols and macros declared within the directive.
Expand All @@ -126,30 +155,41 @@
val macroCompiler = MacroCompiler({ key -> resolveMacro(encodingContext, key) }, readerAdapter)

reader.stepIn()
state = State.IN_ION_ENCODING_SEXP
state = State.IN_DIRECTIVE_SEXP
while (true) {
when (state) {

State.IN_ION_ENCODING_SEXP -> {
State.IN_DIRECTIVE_SEXP -> {
errorIf(reader.next() == null) { "invalid Ion directive; missing directive keyword" }
classifyDirective()
}
State.IN_MODULE_DIRECTIVE_SEXP_AWAITING_MODULE_NAME -> {
errorIf(reader.next() == null) { "invalid module directive; missing module name" }
errorIf(reader.type != IonType.SYMBOL) { "invalid module directive; module name must be a symbol" }
// TODO: Support other module names
errorIf(DEFAULT_MODULE != reader.stringValue()) { "IonJava currently supports only the default module" }
state = State.IN_MODULE_DIRECTIVE_SEXP
}
State.IN_MODULE_DIRECTIVE_SEXP -> {
if (reader.next() == null) {
reader.stepOut()
state = State.READING_VALUE
return
}
if (reader.type != IonType.SEXP) {
throw IonException("Ion encoding directives must contain only s-expressions.")
throw IonException("module definition must contain only s-expressions.")

Check warning on line 180 in src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt#L180

Added line #L180 was not covered by tests
}
reader.stepIn()
if (reader.next() == null || !IonType.isText(reader.type)) {
throw IonException("S-expressions within encoding directives must begin with a text token.")
throw IonException("S-expressions within module definitions must begin with a text token.")

Check warning on line 184 in src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/amazon/ion/impl/EncodingDirectiveReader.kt#L184

Added line #L184 was not covered by tests
}
classifySexpWithinEncodingDirective()
classifySexpWithinModuleDirective()
}

State.IN_SYMBOL_TABLE_SEXP -> {
if (reader.next() == null || classifySymbolTable()) {
reader.stepOut()
state = State.IN_ION_ENCODING_SEXP
state = State.IN_MODULE_DIRECTIVE_SEXP
continue
}
}
Expand All @@ -169,7 +209,7 @@
State.IN_MACRO_TABLE_SEXP -> {
if (reader.next() == null || classifyMacroTable()) {
reader.stepOut()
state = State.IN_ION_ENCODING_SEXP
state = State.IN_MODULE_DIRECTIVE_SEXP
continue
}
state = State.COMPILING_MACRO
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/amazon/ion/impl/IonCursorBinary.java
Original file line number Diff line number Diff line change
Expand Up @@ -2115,7 +2115,7 @@ private void setCheckpointBeforeUnannotatedTypeId() {
*/
private void setMarker(long endIndex, Marker markerToSet) {
if (parent != null && endIndex > parent.endIndex && parent.endIndex > DELIMITED_MARKER) {
throw new IonException("Value exceeds the length of its parent container.");
throw new IonException(String.format("Value [%d:%d] exceeds the length of its parent container [%d:%d].", peekIndex, endIndex, parent.startIndex, parent.endIndex));
}
markerToSet.startIndex = peekIndex;
markerToSet.endIndex = endIndex;
Expand Down
Loading
Loading