Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
573107b
Copy byte array when unmarshalling RawMessage
niallnsec Dec 8, 2022
37cdbe9
chore: use ret.String() instead of string(ret.Bytes())
testwill Jun 29, 2023
3bd36b7
Make current token kind public and accessible via Lexer.CurrentToken
iamtakingiteasy Jan 6, 2024
141f9c7
Merge pull request #393 from iamtakingiteasy/master
rvasily Jan 9, 2024
34d2f3a
Only add tags to run command if set
niallnsec Jan 28, 2024
3229627
Fix null key in map
SolidShake Apr 19, 2024
46715aa
Fix Unmarshaler interface description
IakovLeven Nov 21, 2024
d48874a
Merge pull request #381 from niallnsec/master
rvasily Dec 14, 2024
c2f6bad
Merge pull request #405 from IakovLeven/patch-1
rvasily Dec 14, 2024
8ef38d7
upd test version
Dec 14, 2024
0e683d5
only default tests
Dec 14, 2024
907f46a
up go version to 1.20
Dec 14, 2024
78171e8
Merge pull request #396 from SolidShake/fix-null-map-key
rvasily Dec 14, 2024
5e854fb
Merge pull request #388 from testwill/string
rvasily Dec 14, 2024
529b1f6
Fix unmarshal null to existing value
neal Dec 19, 2024
8580601
Merge pull request #407 from Neal/bugfix/unmarshal-null
rvasily Dec 21, 2024
baefa5c
Fix decoding null values on non-pointer fields
neal Jan 9, 2025
fe2707c
Merge pull request #411 from neal/bugfix/unmarshal-unexpected-null
rvasily Jan 11, 2025
31b2360
Return error if trying to marshal +Inf, -Inf or NaN
dmitrybarsukov May 25, 2025
9b7ae67
fix null after MarshalText work
AndreiBerezin Jun 6, 2025
ffa0b23
feat: Add version and commit information to easyjson generator
stickpro Sep 15, 2025
58eb6f5
Merge pull request #424 from stickpro/issue-415
rvasily Sep 15, 2025
ef22ec5
Merge pull request #421 from dmitrybarsukov/bugfix/invalid-json-on-Na…
rvasily Sep 15, 2025
7dcf687
Merge pull request #423 from AndreiBerezin/fix-null-string
rvasily Sep 15, 2025
a50dd0f
[skip ci] Adding CODEOWNERS file
jeeves-form3 Apr 5, 2022
d041e25
[skip ci] Updating CODEOWNERS file
jeeves-form3 Jun 21, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# automatically generated by terraform - please do not edit here
* @form3tech-oss/contributors-codeowners
58 changes: 29 additions & 29 deletions .github/workflows/easyjson.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
fail-fast: false
matrix:
go: [ 1.17, 1.16, 1.15 ]
go: [ 1.23 ]
steps:
- uses: actions/checkout@v2

Expand All @@ -33,31 +33,31 @@ jobs:
- name: Build and Run tests
run: make

test-non-amd64:
runs-on: ubuntu-latest
name: Test on ${{ matrix.distro }} ${{ matrix.arch }}
strategy:
matrix:
include:
- arch: ppc64le
distro: ubuntu20.04
steps:
- uses: actions/checkout@v2
- uses: uraimo/run-on-arch-action@master
with:
arch: ${{ matrix.arch }}
distro: ${{ matrix.distro }}
install: |
apt-get update
apt install -y curl wget make gcc
latestGo=$(curl "https://golang.org/VERSION?m=text")
wget --quiet "https://dl.google.com/go/${latestGo}.linux-${{ matrix.arch }}.tar.gz"
rm -f $(which go)
rm -rf /usr/local/go
tar -C /usr/local -xzf "${latestGo}.linux-${{ matrix.arch }}.tar.gz"
run: |
export PATH=/usr/local/go/bin:$PATH
export PATH=~/go/bin:$PATH
printf "Go Version: $(go version)\n"
go install golang.org/x/lint/golint@latest
make
# test-arm64:
# runs-on: ubuntu-latest
# name: Test on ${{ matrix.distro }} ${{ matrix.arch }}
# strategy:
# matrix:
# include:
# - arch: arm64
# distro: ubuntu24.04
# steps:
# - uses: actions/checkout@v2
# - uses: uraimo/run-on-arch-action@master
# with:
# arch: ${{ matrix.arch }}
# distro: ${{ matrix.distro }}
# install: |
# apt-get update
# apt install -y curl wget make gcc
# latestGo=$(curl "https://golang.org/VERSION?m=text")
# wget --quiet "https://dl.google.com/go/${latestGo}.linux-${{ matrix.arch }}.tar.gz"
# rm -f $(which go)
# rm -rf /usr/local/go
# tar -C /usr/local -xzf "${latestGo}.linux-${{ matrix.arch }}.tar.gz"
# run: |
# export PATH=/usr/local/go/bin:$PATH
# export PATH=~/go/bin:$PATH
# printf "Go Version: $(go version)\n"
# go install golang.org/x/lint/golint@latest
# make
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
VERSION := $(shell git describe --tags --always --dirty)
COMMIT := $(shell git rev-parse --short HEAD)

all: test

clean:
Expand All @@ -6,7 +9,8 @@ clean:
rm -rf benchmark/*_easyjson.go

build:
go build -o ./bin/easyjson ./easyjson
go build -ldflags="-s -w -X 'main.Version=$(VERSION)' -X 'main.Commit=$(COMMIT)'" -o ./bin/easyjson ./easyjson


generate: build
bin/easyjson -stubs \
Expand Down Expand Up @@ -46,7 +50,8 @@ generate: build
./tests/intern.go \
./tests/nocopy.go \
./tests/escaping.go \
./tests/nested_marshaler.go
./tests/nested_marshaler.go \
./tests/text_marshaler.go
bin/easyjson -snake_case ./tests/snake.go
bin/easyjson -omit_empty ./tests/omitempty.go
bin/easyjson -build_tags=use_easyjson -disable_members_unescape ./benchmark/data.go
Expand Down
5 changes: 4 additions & 1 deletion bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,10 @@ func (g *Generator) Run() error {
buildFlags := buildFlagsRegexp.FindAllString(g.GenBuildFlags, -1)
execArgs = append(execArgs, buildFlags...)
}
execArgs = append(execArgs, "-tags", g.BuildTags, filepath.Base(path))
if len(g.BuildTags) > 0 {
execArgs = append(execArgs, "-tags", g.BuildTags)
}
execArgs = append(execArgs, filepath.Base(path))
cmd := exec.Command("go", execArgs...)

cmd.Stdout = f
Expand Down
11 changes: 11 additions & 0 deletions easyjson/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ import (
"github.com/mailru/easyjson/parser"
)

var (
Version = "dev" //
Commit = "none"
)

var buildTags = flag.String("build_tags", "", "build tags to add to generated file")
var genBuildFlags = flag.String("gen_build_flags", "", "build flags when running the generator while bootstrapping")
var snakeCase = flag.Bool("snake_case", false, "use snake_case names instead of CamelCase by default")
Expand All @@ -31,6 +36,7 @@ var specifiedName = flag.String("output_filename", "", "specify the filename of
var processPkg = flag.Bool("pkg", false, "process the whole package instead of just the given file")
var disallowUnknownFields = flag.Bool("disallow_unknown_fields", false, "return error if any unknown field in json appeared")
var skipMemberNameUnescaping = flag.Bool("disable_members_unescape", false, "don't perform unescaping of member names to improve performance")
var showVersion = flag.Bool("version", false, "print version and exit")

func generate(fname string) (err error) {
fInfo, err := os.Stat(fname)
Expand Down Expand Up @@ -98,6 +104,11 @@ func main() {

files := flag.Args()

if *showVersion {
fmt.Printf("easyjson generator\nversion: %s\ncommit: %s\n", Version, Commit)
os.Exit(0)
}

gofile := os.Getenv("GOFILE")
if *processPkg {
gofile = filepath.Dir(gofile)
Expand Down
46 changes: 32 additions & 14 deletions gen/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,34 @@ func (g *Generator) genTypeDecoder(t reflect.Type, out string, tags fieldTags, i

unmarshalerIface := reflect.TypeOf((*easyjson.Unmarshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(unmarshalerIface) {
fmt.Fprintln(g.out, ws+"("+out+").UnmarshalEasyJSON(in)")
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" ("+out+").UnmarshalEasyJSON(in)")
fmt.Fprintln(g.out, ws+"}")
return nil
}

unmarshalerIface = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(unmarshalerIface) {
fmt.Fprintln(g.out, ws+"if data := in.Raw(); in.Ok() {")
fmt.Fprintln(g.out, ws+" in.AddError( ("+out+").UnmarshalJSON(data) )")
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" if data := in.Raw(); in.Ok() {")
fmt.Fprintln(g.out, ws+" in.AddError( ("+out+").UnmarshalJSON(data) )")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+"}")
return nil
}

unmarshalerIface = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(unmarshalerIface) {
fmt.Fprintln(g.out, ws+"if data := in.UnsafeBytes(); in.Ok() {")
fmt.Fprintln(g.out, ws+" in.AddError( ("+out+").UnmarshalText(data) )")
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" if data := in.UnsafeBytes(); in.Ok() {")
fmt.Fprintln(g.out, ws+" in.AddError( ("+out+").UnmarshalText(data) )")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+"}")
return nil
}
Expand Down Expand Up @@ -110,13 +122,21 @@ func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags field
ws := strings.Repeat(" ", indent)
// Check whether type is primitive, needs to be done after interface check.
if dec := customDecoders[t.String()]; dec != "" {
fmt.Fprintln(g.out, ws+out+" = "+dec)
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" "+out+" = "+dec)
fmt.Fprintln(g.out, ws+"}")
return nil
} else if dec := primitiveStringDecoders[t.Kind()]; dec != "" && tags.asString {
if tags.intern && t.Kind() == reflect.String {
dec = "in.StringIntern()"
}
fmt.Fprintln(g.out, ws+out+" = "+g.getType(t)+"("+dec+")")
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" "+out+" = "+g.getType(t)+"("+dec+")")
fmt.Fprintln(g.out, ws+"}")
return nil
} else if dec := primitiveDecoders[t.Kind()]; dec != "" {
if tags.intern && t.Kind() == reflect.String {
Expand All @@ -125,7 +145,11 @@ func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags field
if tags.noCopy && t.Kind() == reflect.String {
dec = "in.UnsafeString()"
}
fmt.Fprintln(g.out, ws+out+" = "+g.getType(t)+"("+dec+")")
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" "+out+" = "+g.getType(t)+"("+dec+")")
fmt.Fprintln(g.out, ws+"}")
return nil
}

Expand Down Expand Up @@ -320,7 +344,6 @@ func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags field
return fmt.Errorf("don't know how to decode %v", t)
}
return nil

}

func (g *Generator) interfaceIsEasyjsonUnmarshaller(t reflect.Type) bool {
Expand Down Expand Up @@ -514,11 +537,6 @@ func (g *Generator) genStructDecoder(t reflect.Type) error {
fmt.Fprintln(g.out, " for !in.IsDelim('}') {")
fmt.Fprintf(g.out, " key := in.UnsafeFieldName(%v)\n", g.skipMemberNameUnescaping)
fmt.Fprintln(g.out, " in.WantColon()")
fmt.Fprintln(g.out, " if in.IsNull() {")
fmt.Fprintln(g.out, " in.Skip()")
fmt.Fprintln(g.out, " in.WantComma()")
fmt.Fprintln(g.out, " continue")
fmt.Fprintln(g.out, " }")

fmt.Fprintln(g.out, " switch key {")
for _, f := range fs {
Expand Down
2 changes: 1 addition & 1 deletion gen/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ func camelToSnake(name string) string {
if lastUpper != 0 {
ret.WriteRune(unicode.ToLower(lastUpper))
}
return string(ret.Bytes())
return ret.String()
}

func (SnakeCaseFieldNamer) GetJSONFieldName(t reflect.Type, f reflect.StructField) string {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module github.com/mailru/easyjson

go 1.12
go 1.20

require github.com/josharian/intern v1.0.0
2 changes: 1 addition & 1 deletion helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type Marshaler interface {
MarshalEasyJSON(w *jwriter.Writer)
}

// Marshaler is an easyjson-compatible unmarshaler interface.
// Unmarshaler is an easyjson-compatible unmarshaler interface.
type Unmarshaler interface {
UnmarshalEasyJSON(w *jlexer.Lexer)
}
Expand Down
Loading