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

JSON: retain original order of map entries? #1630

Open
kubukoz opened this issue Dec 24, 2024 · 4 comments
Open

JSON: retain original order of map entries? #1630

kubukoz opened this issue Dec 24, 2024 · 4 comments
Labels
question Further information is requested

Comments

@kubukoz
Copy link
Member

kubukoz commented Dec 24, 2024

I was trying to read a grammar.json file from tree-sitter: it looks like this

{
  "name": "smithyql",
  "rules": {
    "source_file": {
      "type": "SEQ",
      "members": ...
    },
    "prelude": {
      "type": "REPEAT1",
      "content": {
        "type": "SYMBOL",
        "name": "use_clause"
      }
    },
...

Notably, the first rule is supposed to be the entrypoint to parsing a file. However, when I tried to model this as Smithy:

structure Grammar {
    @required
    name: String

    @required
    rules: Rules
}

map Rules {
    key: TypeName
    value: Document
}

and read it as JSON:

val grammar =
  Json
    .read[Grammar](
      Blob(Files.readString(Paths.get("tree-sitter-smithyql/src/grammar.json")))
    )
    .toTry
    .get

grammar.rules.toList.map(_._1).foreach(println)

Then source_file was actually last - in any case, the ordering is not preserved.

Is this something we should support, maybe with an optional meta trait that'd turn the map into a ListMap? Or should it be the default?

Tested on 0.18.27.

@kubukoz kubukoz added the question Further information is requested label Dec 24, 2024
@Baccata
Copy link
Contributor

Baccata commented Jan 2, 2025

Yeah, an optional meta trait is gonna be the way to go, but this goes in with the question of abstracting over Map in the Schema GADT (the same way we've abstracted over collections via a tag to allow for IndexedSeq/Vector/etc). So I think this is a 0.19 concern.

As for the problem at hand, I think you can work around it by using the newly supported @jsonUnknown : if you know there's gonna be a source_file field, may as well model it in a structure and get the rest as an free-form map.

@kubukoz
Copy link
Member Author

kubukoz commented Jan 2, 2025

if you know there's gonna be a source_file field, may as well model it in a structure and get the rest as an free-form map.

I don't know that - the schema is supposed to work for any tree-sitter grammar out there. It just happens that source_file is the first rule (meaning the root) of my exact grammar.

Not sure if @jsonUnknown will give me the original ordering, I guess that depends on how Documents get decoded. I'll be back with info.

update: yeah @jsonUnknown gets placed on a shape targetting a Map[String, Document], so the result ends up with arbitrary ordering again. I guess the suggestion only applied with the assumption that source_file was known as a static entry.

@plokhotnyuk
Copy link
Contributor

How about using of LinkedHashMap that preserves ordering of inserts?

And, please, never use ListMap because its inserts and lookups have O(n) complexity.

@kubukoz
Copy link
Member Author

kubukoz commented Jan 2, 2025

there's no immutable variant, is there? :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants