Code Monkey home page Code Monkey logo

json5.java's Introduction

Latest Version: Download

Build Health:

Javadocs

Performance Note

I have a fork of the java-json-benchmark that adds support for Deserializing JSON with this library. Currently, this library is about 20x SLOWER than using Jackson. I'm investigating ways to improve the performance, but that may come with API changes. Specifically, when profiling, JSON5Parser has an annonymous inner class that implements JSON5Lexer.Visitor and the various methods called consume 50% of the processing time! My theory is that constructing all the lambdas necessary to implement the visitor/builder pattern is a major contributor to this slow speed. Therefore I'd like to change the code to use a more traditional reader/builder pattern.

JSON5 Library (using visitor pattern, SLOW!)

// Create a parser instance:
JSON5Parser parser = new JSON5Parser();

// Simple stack used for tree building.
List<Object> stack = new ArrayList<>();

// Specify a visitor used to build your AST (Abstract Syntax Tree),
// or perform validation. Note that all tokens of input are visited,
// which enables comments and spaces to be preserved.
parser.setVisitor(
    new JSON5Visitor() {
        @Override
        public void visit(Number val, int line, long offset) {
            if ( !(num instanceof Double) && !(num instanceof Long) ) {
                // Example of obtaining line-precise error messages:
                throw new JSON5ParseError("Unsupported numeric type", parser.getLocation(line, offset));
            }
            stack.add(val);
        }

        @Override
        public void visit(String val, int line, long offset) {
            stack.add(val);
        }

        @Override
        public void visitNull(int line, long offset) {

            stack.add(null);
        }

        @Override
        public void visit(boolean val, int line, long offset) {
            stack.add(val);
        }

        @Override
        public void startObject(int line, long offset) {
            stack.add(new HashMap<>());
        }

        @Override
        public void endObjectPair(String key, int line, long offset) {
            Object val = stack.remove(stack.size()-1);
            ((Map)stack.get(stack.size()-1)).put(key, val);
        }

        @Override
        public void startArray(int line, long offset) {
            stack.add(new ArrayList<>());
        }

        @Override
        public void endArrayValue(int line, long offset) {
            Object val = stack.remove(stack.size()-1);
            ((List)stack.get(stack.size()-1)).add(val);
        }
    });

// Parse a file:
parser.parse(Paths.get("example.json5"));

// Obtain the results of visiting the tree:
Object value = stack.remove(0);

Databind

If you prefer to avoid writing a visitor, you can use the databind library to parse a file as such:

import com.brimworks.json5.databind.JSON5DataBind;
import com.brimworks.databind.DataBind;

public class Config {
    public String string;
    public double number;
}

JSON5DataBind json5 = new JSON5DataBind(new DataBind.Builder().build());
Config config = json5.parse(Paths.get("config.json5"), Config.class);

...and if config.json5 looks like this:

{
    /* Greetings */
    string: "Hello",
    // PI:
    number: 3.14,
}

Then the Config class will be populated with the "Hello" string and 3.14 number as expected.

Future Plans?

When writing this, I thought the visitor/builder pattern would make type transformations easier. However, after working with this pattern for a bit I am coming around to the more prevalent builder/reader paradigm. One of the problems with visitor/builder pattern is all the lambdas necessary to set the types. It is also harder to adapt this visitor/builder pattern to existing json ecosystems.

What does this mean?

I'll experiment with adding new APIs to JSON5Parser which return a JSON5Reader and then tap into the gson and jackson databind ecosystems by writing simple adaptors. If you are interested in helping out, feel free to file an issue.

Release Notes

Version 2.0.0

More backwards incompatible changes in the databind library, but the only changes to the json5 parser was adding support for a new visitIndex() method which is the array analog to visitKey(). Also, a major bug was fixed where the string buffer was not cleared after visiting the "constant" tokens (true, false, null).

The databind library is more complete at this point, supporting all the primitive types.

Version 1.0.0

This was a major version bump since there was several backwards incompatible changes made. Specifically:

  • JSON5Visitor endObjectPair() is now passed in the key of the object pair, and added a visitKey() method which is called INSTEAD of visit(String). This should make it easier to implement custom visitors, sorry if this change broke your code, but it is the right thing to do in the long term.
  • Remove the Consumer wrapping of visitors. Specifically, ArrayVisitor.add() and ObjectVisitor.put(String) now return a TypeVisitor rather than taking a Consumer as input.
  • Added some methods to various interfaces: TypeBuilderContext and TypeRegistry. This is part of the databind code which is still early "alpha" code, so expect more changes here in the future.
  • Added a new json5-databind module. This will eventually make it easier to use JSON5 from arbitrary types, but this is still a work in progress.

json5.java's People

Contributors

brimworks avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.