Skip to content

Commit 37a33d2

Browse files
authored
Use default module instead of $ion_encoding (#1007)
1 parent 0a17f82 commit 37a33d2

16 files changed

+284
-180
lines changed

ion-tests

src/main/java/com/amazon/ion/SystemSymbols.java

+2-12
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,7 @@ private SystemSymbols() { }
121121
// Ion 1.1 Symbols
122122

123123
/**
124-
* The annotation that denotes an Ion encoding directive in Ion 1.1+.
124+
* The name of the default module in Ion 1.1
125125
*/
126-
public static final String ION_ENCODING = "$ion_encoding";
127-
128-
/**
129-
* The name of the symbol table s-expression within an Ion encoding directive.
130-
*/
131-
public static final String SYMBOL_TABLE = "symbol_table";
132-
133-
/**
134-
* The name of the macro table s-expression within an Ion encoding directive.
135-
*/
136-
public static final String MACRO_TABLE = "macro_table";
126+
public static final String DEFAULT_MODULE = "_";
137127
}

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

+56-16
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package com.amazon.ion.impl
44

55
import com.amazon.ion.*
6+
import com.amazon.ion.SystemSymbols.*
67
import com.amazon.ion.impl.macro.*
78
import com.amazon.ion.impl.macro.MacroRef.Companion.byId
89
import com.amazon.ion.impl.macro.MacroRef.Companion.byName
@@ -28,22 +29,39 @@ internal class EncodingDirectiveReader(private val reader: IonReader, private va
2829
var isMacroTableAlreadyClassified = false
2930

3031
private enum class State {
31-
IN_ION_ENCODING_SEXP,
32+
IN_DIRECTIVE_SEXP,
33+
IN_MODULE_DIRECTIVE_SEXP_AWAITING_MODULE_NAME,
34+
IN_MODULE_DIRECTIVE_SEXP,
3235
IN_SYMBOL_TABLE_SEXP,
3336
IN_SYMBOL_TABLE_LIST,
3437
IN_MACRO_TABLE_SEXP,
3538
COMPILING_MACRO,
3639
READING_VALUE
3740
}
3841

39-
private fun classifySexpWithinEncodingDirective() {
42+
private fun classifyDirective() {
43+
errorIf(reader.type != IonType.SYMBOL) { "Ion encoding directives must start with a directive keyword; found ${reader.type}" }
44+
val name: String = reader.stringValue()
45+
// TODO: Add support for `import` and `encoding` directives
46+
if (SystemSymbols_1_1.MODULE.text == name) {
47+
state = State.IN_MODULE_DIRECTIVE_SEXP_AWAITING_MODULE_NAME
48+
} else if (SystemSymbols_1_1.IMPORT.text == name) {
49+
throw IonException("'import' directive not yet supported")
50+
} else if (SystemSymbols_1_1.ENCODING.text == name) {
51+
throw IonException("'encoding' directive not yet supported")
52+
} else {
53+
throw IonException(String.format("'%s' is not a valid directive keyword", name))
54+
}
55+
}
56+
57+
private fun classifySexpWithinModuleDirective() {
4058
val name: String = reader.stringValue()
4159
state = if (SystemSymbols_1_1.SYMBOL_TABLE.text == name) {
4260
State.IN_SYMBOL_TABLE_SEXP
4361
} else if (SystemSymbols_1_1.MACRO_TABLE.text == name) {
4462
State.IN_MACRO_TABLE_SEXP
4563
} else {
46-
throw IonException(String.format("\$ion_encoding expressions '%s' not supported.", name))
64+
throw IonException("'$name' clause not supported in module definition")
4765
}
4866
}
4967

@@ -64,7 +82,7 @@ internal class EncodingDirectiveReader(private val reader: IonReader, private va
6482
}
6583
isSymbolTableAlreadyClassified = true
6684
if (IonType.isText(type)) {
67-
if (SystemSymbols.ION_ENCODING == reader.stringValue() && !isSymbolTableAppend) {
85+
if (DEFAULT_MODULE == reader.stringValue() && !isSymbolTableAppend) {
6886
isSymbolTableAppend = true
6987
if (reader.next() == null) {
7088
return true
@@ -73,10 +91,10 @@ internal class EncodingDirectiveReader(private val reader: IonReader, private va
7391
throw IonException("symbol_table s-expression must begin with a list.")
7492
}
7593
} else {
76-
throw IonException("symbol_table s-expression must begin with either \$ion_encoding or a list.")
94+
throw IonException("symbol_table s-expression must begin with either '_' or a list.")
7795
}
7896
} else if (type != IonType.LIST) {
79-
throw IonException("symbol_table s-expression must begin with either \$ion_encoding or a list.")
97+
throw IonException("symbol_table s-expression must begin with either '_' or a list.")
8098
}
8199
reader.stepIn()
82100
state = State.IN_SYMBOL_TABLE_LIST
@@ -98,7 +116,7 @@ internal class EncodingDirectiveReader(private val reader: IonReader, private va
98116
}
99117
isMacroTableAlreadyClassified = true
100118
if (IonType.isText(type)) {
101-
if (SystemSymbols.ION_ENCODING == reader.stringValue() && !isMacroTableAppend) {
119+
if (SystemSymbols.DEFAULT_MODULE == reader.stringValue() && !isMacroTableAppend) {
102120
isMacroTableAppend = true
103121
if (reader.next() == null) {
104122
return true
@@ -107,16 +125,27 @@ internal class EncodingDirectiveReader(private val reader: IonReader, private va
107125
throw IonException("macro_table s-expression must begin with s-expression(s).")
108126
}
109127
} else {
110-
throw IonException("macro_table s-expression must begin with either \$ion_encoding or s-expression(s).")
128+
throw IonException("macro_table s-expression must begin with either '_' or s-expression(s).")
111129
}
112130
} else if (type == IonType.SEXP) {
113131
localMacroMaxOffset = -1
114132
} else {
115-
throw IonException("macro_table s-expression must begin with either \$ion_encoding or s-expression(s).")
133+
throw IonException("macro_table s-expression must begin with either '_' or s-expression(s).")
116134
}
117135
return false
118136
}
119137

138+
/**
139+
* Utility function to make error cases more concise.
140+
* @param condition the condition under which an IonException should be thrown
141+
* @param lazyErrorMessage the message to use in the exception
142+
*/
143+
private inline fun errorIf(condition: Boolean, lazyErrorMessage: () -> String) {
144+
if (condition) {
145+
throw IonException(lazyErrorMessage())
146+
}
147+
}
148+
120149
/**
121150
* Reads an encoding directive. After this method returns, the caller should access this class's properties to
122151
* retrieve the symbols and macros declared within the directive.
@@ -126,30 +155,41 @@ internal class EncodingDirectiveReader(private val reader: IonReader, private va
126155
val macroCompiler = MacroCompiler({ key -> resolveMacro(encodingContext, key) }, readerAdapter)
127156

128157
reader.stepIn()
129-
state = State.IN_ION_ENCODING_SEXP
158+
state = State.IN_DIRECTIVE_SEXP
130159
while (true) {
131160
when (state) {
132161

133-
State.IN_ION_ENCODING_SEXP -> {
162+
State.IN_DIRECTIVE_SEXP -> {
163+
errorIf(reader.next() == null) { "invalid Ion directive; missing directive keyword" }
164+
classifyDirective()
165+
}
166+
State.IN_MODULE_DIRECTIVE_SEXP_AWAITING_MODULE_NAME -> {
167+
errorIf(reader.next() == null) { "invalid module directive; missing module name" }
168+
errorIf(reader.type != IonType.SYMBOL) { "invalid module directive; module name must be a symbol" }
169+
// TODO: Support other module names
170+
errorIf(DEFAULT_MODULE != reader.stringValue()) { "IonJava currently supports only the default module" }
171+
state = State.IN_MODULE_DIRECTIVE_SEXP
172+
}
173+
State.IN_MODULE_DIRECTIVE_SEXP -> {
134174
if (reader.next() == null) {
135175
reader.stepOut()
136176
state = State.READING_VALUE
137177
return
138178
}
139179
if (reader.type != IonType.SEXP) {
140-
throw IonException("Ion encoding directives must contain only s-expressions.")
180+
throw IonException("module definition must contain only s-expressions.")
141181
}
142182
reader.stepIn()
143183
if (reader.next() == null || !IonType.isText(reader.type)) {
144-
throw IonException("S-expressions within encoding directives must begin with a text token.")
184+
throw IonException("S-expressions within module definitions must begin with a text token.")
145185
}
146-
classifySexpWithinEncodingDirective()
186+
classifySexpWithinModuleDirective()
147187
}
148188

149189
State.IN_SYMBOL_TABLE_SEXP -> {
150190
if (reader.next() == null || classifySymbolTable()) {
151191
reader.stepOut()
152-
state = State.IN_ION_ENCODING_SEXP
192+
state = State.IN_MODULE_DIRECTIVE_SEXP
153193
continue
154194
}
155195
}
@@ -169,7 +209,7 @@ internal class EncodingDirectiveReader(private val reader: IonReader, private va
169209
State.IN_MACRO_TABLE_SEXP -> {
170210
if (reader.next() == null || classifyMacroTable()) {
171211
reader.stepOut()
172-
state = State.IN_ION_ENCODING_SEXP
212+
state = State.IN_MODULE_DIRECTIVE_SEXP
173213
continue
174214
}
175215
state = State.COMPILING_MACRO

src/main/java/com/amazon/ion/impl/IonCursorBinary.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -2115,7 +2115,7 @@ private void setCheckpointBeforeUnannotatedTypeId() {
21152115
*/
21162116
private void setMarker(long endIndex, Marker markerToSet) {
21172117
if (parent != null && endIndex > parent.endIndex && parent.endIndex > DELIMITED_MARKER) {
2118-
throw new IonException("Value exceeds the length of its parent container.");
2118+
throw new IonException(String.format("Value [%d:%d] exceeds the length of its parent container [%d:%d].", peekIndex, endIndex, parent.startIndex, parent.endIndex));
21192119
}
21202120
markerToSet.startIndex = peekIndex;
21212121
markerToSet.endIndex = endIndex;

0 commit comments

Comments
 (0)