easyjson icon indicating copy to clipboard operation
easyjson copied to clipboard

dynamically generate easyjson files

Open steevehook opened this issue 4 years ago • 0 comments

Hi guys, first of all. Amazing work and awesome lib:

Wanted to suggest a few improvements in regards to generating _easyjson.go files dynamically. So our company recently started to use this library due to default json.Unmarshal issues. And this library seams to increase the performance on some modules significantly.


So at the end of implementation we wanted to automate things and generate these files somehow dynamically on CI/CD without committing these giant files every time.

The approach was pretty simple, parse the files that need to have generated marshallers/unmarshallers:

grep --include="*.go" -iRl "easyjson:json" ./ | tr '\n' ' ' | xargs easyjson


However there some problems with this dynamic approach:

  • Every time a _easyjson.go file is generated is parsed against the Go Compiler and thus errors if it has any errors.
  • Not every time we want to generate _easyjson.go file the file is inside a models.go of sorts file, which simply contains the struct.
  • Sometimes we practice to place the structs next to where they are used, which means they are next to where the call to UnmarshalJSON method is made, which leads to an error, since that method does not exist when we dynamically generate these files
  • A workaround for this is to move the structs containing the easyjson:json comment away
  • Or simply give up this approach and commit these big files

However would be nice if there is an option for ignoring the STDERR and generating the marshallers/unmarshallers without erroring. Maybe this is not the best approach, hence I did not look deeply into the source code.

But it would be a nice feature to be able to dynamically use the lib like this


Also speaking of parsing and checking. If I have an error in a different file of the same package it will not error and generate the _easyjson.go file successfully 😄

The current approach is to use a custom Unmarshaler and use that instead

func Unmarshal(bs []byte, v interface{}) error {
	unMarshaller, ok := v.(json.Unmarshaler)
	if ok {
		return unMarshaller.UnmarshalJSON(bs)
	}
	return json.Unmarshal(bs, v)
}

steevehook avatar Jul 07 '20 04:07 steevehook