@@ -58,19 +58,20 @@ public class TomlMainDecoder(
5858 }
5959
6060 override fun decodeEnum (enumDescriptor : SerialDescriptor ): Int {
61- val value = decodeValue().toString()
61+ val node = decodeKeyValue()
62+ val value = node.value.content.toString()
6263 val index = enumDescriptor.getElementIndex(value)
6364
6465 if (index == CompositeDecoder .UNKNOWN_NAME ) {
65- throw InvalidEnumValueException (value, enumDescriptor)
66+ throw InvalidEnumValueException (value, enumDescriptor, node.lineNo )
6667 }
6768
6869 return index
6970 }
7071
7172 // the iteration will go through all elements that will be found in the input
7273 private fun isDecodingDone () =
73- if (rootNode is TomlFile ) true else elementIndex == rootNode.getNeighbourNodes().size
74+ if (rootNode is TomlFile ) true else elementIndex == rootNode.getNeighbourNodes().size
7475
7576 /* *
7677 * Getting the node with the value
@@ -103,7 +104,7 @@ public class TomlMainDecoder(
103104 // branch, we should throw an exception as it is not expected at all and we should catch this in tests
104105 else ->
105106 throw InternalDecodingException (
106- " Node of type [${node::class } ] should not be processed in TomlDecoder.decodeValue(): <${node.content} >"
107+ " Node of type [${node::class } ] should not be processed in TomlDecoder.decodeValue(): <${node.content} >. "
107108 )
108109 }
109110 }
@@ -189,9 +190,9 @@ public class TomlMainDecoder(
189190
190191 if (! descriptor.isElementOptional(index)) {
191192 throw MissingRequiredPropertyException (
192- " Invalid number of key-value arguments provided in the input for deserialization." +
193- " Missing required property " +
194- " < ${descriptor.getElementName(index)} > from class < ${descriptor.serialName} > in the input"
193+ " Invalid number of key-value arguments provided in the input for deserialization. Missing required property " +
194+ " < ${descriptor.getElementName(index)} > from class < ${descriptor.serialName} > in the input. " +
195+ " (In your deserialization class you have declared this field, but it is missing in the input) "
195196 )
196197 }
197198 }
@@ -201,63 +202,63 @@ public class TomlMainDecoder(
201202 * A hack that comes from a compiler plugin to process Inline (value) classes
202203 */
203204 override fun decodeInline (inlineDescriptor : SerialDescriptor ): Decoder =
204- iterateOverStructure(inlineDescriptor, true )
205+ iterateOverStructure(inlineDescriptor, true )
205206
206207 /* *
207208 * this method does all the iteration logic for processing code structures and collections
208209 * treat it as an !entry point! and the orchestrator of the decoding
209210 */
210211 override fun beginStructure (descriptor : SerialDescriptor ): CompositeDecoder =
211- iterateOverStructure(descriptor, false )
212+ iterateOverStructure(descriptor, false )
212213
213214 /* *
214215 * Entry Point into the logic, core logic of the structure traversal and linking the data from TOML AST
215216 * to the descriptor and vica-versa. Basically this logic is used to iterate through data structures and do processing.
216217 */
217218 private fun iterateOverStructure (descriptor : SerialDescriptor , inlineFunc : Boolean ): TomlAbstractDecoder =
218- if (rootNode is TomlFile ) {
219- checkMissingRequiredProperties(rootNode.children, descriptor)
220- val firstFileChild = getFirstChild(rootNode)
221-
222- // inline structures has a very specific logic for decoding. Kotlinx.serialization plugin generates specific code:
223- // 'decoder.decodeInline(this.getDescriptor()).decodeLong())'. So we need simply to increment
224- // our element index by 1 (0 is the default value), because value/inline classes are always a wrapper over some SINGLE value.
225- if (inlineFunc) TomlMainDecoder (firstFileChild, config, 1 ) else TomlMainDecoder (firstFileChild, config, 0 )
226- } else {
227- // this is a tricky index calculation, suggest not to change. We are using the previous node to get all neighbour nodes:
228- // | (parentNode)
229- // |--- neighbourNodes: (current rootNode) (next node which we would like to process now)
230- val nextProcessingNode = rootNode
231- .getNeighbourNodes()
232- .elementAt(elementIndex - 1 )
233-
234- when (nextProcessingNode) {
235- is TomlKeyValueArray -> TomlArrayDecoder (nextProcessingNode, config)
236- is TomlKeyValuePrimitive , is TomlStubEmptyNode -> TomlMainDecoder (nextProcessingNode, config)
237- is TomlTablePrimitive -> {
238- val firstTableChild = nextProcessingNode.getFirstChild() ? : throw InternalDecodingException (
239- " Decoding process failed due to invalid structure of parsed AST tree: missing children" +
240- " in a table <${nextProcessingNode.fullTableKey} >"
241- )
242- checkMissingRequiredProperties(firstTableChild.getNeighbourNodes(), descriptor)
243- TomlMainDecoder (firstTableChild, config)
244- }
245- else -> throw InternalDecodingException (
246- " Incorrect decoding state in the beginStructure()" +
247- " with $nextProcessingNode ($nextProcessingNode )[${nextProcessingNode.name} ]"
219+ if (rootNode is TomlFile ) {
220+ checkMissingRequiredProperties(rootNode.children, descriptor)
221+ val firstFileChild = getFirstChild(rootNode)
222+
223+ // inline structures has a very specific logic for decoding. Kotlinx.serialization plugin generates specific code:
224+ // 'decoder.decodeInline(this.getDescriptor()).decodeLong())'. So we need simply to increment
225+ // our element index by 1 (0 is the default value), because value/inline classes are always a wrapper over some SINGLE value.
226+ if (inlineFunc) TomlMainDecoder (firstFileChild, config, 1 ) else TomlMainDecoder (firstFileChild, config, 0 )
227+ } else {
228+ // this is a tricky index calculation, suggest not to change. We are using the previous node to get all neighbour nodes:
229+ // | (parentNode)
230+ // |--- neighbourNodes: (current rootNode) (next node which we would like to process now)
231+ val nextProcessingNode = rootNode
232+ .getNeighbourNodes()
233+ .elementAt(elementIndex - 1 )
234+
235+ when (nextProcessingNode) {
236+ is TomlKeyValueArray -> TomlArrayDecoder (nextProcessingNode, config)
237+ is TomlKeyValuePrimitive , is TomlStubEmptyNode -> TomlMainDecoder (nextProcessingNode, config)
238+ is TomlTablePrimitive -> {
239+ val firstTableChild = nextProcessingNode.getFirstChild() ? : throw InternalDecodingException (
240+ " Decoding process has failed due to invalid structure of parsed AST tree: missing children" +
241+ " in a table <${nextProcessingNode.fullTableKey} >"
248242 )
243+ checkMissingRequiredProperties(firstTableChild.getNeighbourNodes(), descriptor)
244+ TomlMainDecoder (firstTableChild, config)
249245 }
246+ else -> throw InternalDecodingException (
247+ " Incorrect decoding state in the beginStructure()" +
248+ " with $nextProcessingNode ($nextProcessingNode )[${nextProcessingNode.name} ]"
249+ )
250250 }
251+ }
251252
252253 private fun getFirstChild (node : TomlNode ) =
253- node.getFirstChild() ? : if (! config.allowEmptyToml) {
254- throw InternalDecodingException (
255- " Missing child nodes (tables, key-values) for TomlFile." +
256- " Was empty toml provided to the input?"
257- )
258- } else {
259- node
260- }
254+ node.getFirstChild() ? : if (! config.allowEmptyToml) {
255+ throw InternalDecodingException (
256+ " Missing child nodes (tables, key-values) for TomlFile." +
257+ " May be an empty toml was provided to the input?"
258+ )
259+ } else {
260+ node
261+ }
261262
262263 public companion object {
263264 /* *
0 commit comments