Add vendor folder to git

This commit is contained in:
Lucas Käldström 2017-06-26 19:23:05 +03:00
parent 66cf5eaafb
commit 183585f56f
No known key found for this signature in database
GPG key ID: 600FEFBBD0D40D21
6916 changed files with 2629581 additions and 1 deletions

385
vendor/github.com/mailru/easyjson/gen/decoder.go generated vendored Normal file
View file

@ -0,0 +1,385 @@
package gen
import (
"encoding/json"
"fmt"
"reflect"
"strings"
"unicode"
"github.com/mailru/easyjson"
)
// Target this byte size for initial slice allocation to reduce garbage collection.
const minSliceBytes = 64
func (g *Generator) getDecoderName(t reflect.Type) string {
return g.functionName("decode", t)
}
var primitiveDecoders = map[reflect.Kind]string{
reflect.String: "in.String()",
reflect.Bool: "in.Bool()",
reflect.Int: "in.Int()",
reflect.Int8: "in.Int8()",
reflect.Int16: "in.Int16()",
reflect.Int32: "in.Int32()",
reflect.Int64: "in.Int64()",
reflect.Uint: "in.Uint()",
reflect.Uint8: "in.Uint8()",
reflect.Uint16: "in.Uint16()",
reflect.Uint32: "in.Uint32()",
reflect.Uint64: "in.Uint64()",
reflect.Float32: "in.Float32()",
reflect.Float64: "in.Float64()",
}
var primitiveStringDecoders = map[reflect.Kind]string{
reflect.Int: "in.IntStr()",
reflect.Int8: "in.Int8Str()",
reflect.Int16: "in.Int16Str()",
reflect.Int32: "in.Int32Str()",
reflect.Int64: "in.Int64Str()",
reflect.Uint: "in.UintStr()",
reflect.Uint8: "in.Uint8Str()",
reflect.Uint16: "in.Uint16Str()",
reflect.Uint32: "in.Uint32Str()",
reflect.Uint64: "in.Uint64Str()",
}
// genTypeDecoder generates decoding code for the type t, but uses unmarshaler interface if implemented by t.
func (g *Generator) genTypeDecoder(t reflect.Type, out string, tags fieldTags, indent int) error {
ws := strings.Repeat(" ", indent)
unmarshalerIface := reflect.TypeOf((*easyjson.Unmarshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(unmarshalerIface) {
fmt.Fprintln(g.out, ws+"("+out+").UnmarshalEasyJSON(in)")
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+"}")
return nil
}
err := g.genTypeDecoderNoCheck(t, out, tags, indent)
return err
}
// genTypeDecoderNoCheck generates decoding code for the type t.
func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags fieldTags, indent int) error {
ws := strings.Repeat(" ", indent)
// Check whether type is primitive, needs to be done after interface check.
if dec := primitiveStringDecoders[t.Kind()]; dec != "" && tags.asString {
fmt.Fprintln(g.out, ws+out+" = "+g.getType(t)+"("+dec+")")
return nil
} else if dec := primitiveDecoders[t.Kind()]; dec != "" {
fmt.Fprintln(g.out, ws+out+" = "+g.getType(t)+"("+dec+")")
return nil
}
switch t.Kind() {
case reflect.Slice:
tmpVar := g.uniqueVarName()
elem := t.Elem()
capacity := minSliceBytes / elem.Size()
if capacity == 0 {
capacity = 1
}
fmt.Fprintln(g.out, ws+"in.Delim('[')")
fmt.Fprintln(g.out, ws+"if !in.IsDelim(']') {")
fmt.Fprintln(g.out, ws+" "+out+" = make("+g.getType(t)+", 0, "+fmt.Sprint(capacity)+")")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" "+out+" = nil")
fmt.Fprintln(g.out, ws+"}")
fmt.Fprintln(g.out, ws+"for !in.IsDelim(']') {")
fmt.Fprintln(g.out, ws+" var "+tmpVar+" "+g.getType(elem))
g.genTypeDecoder(elem, tmpVar, tags, indent+1)
fmt.Fprintln(g.out, ws+" "+out+" = append("+out+", "+tmpVar+")")
fmt.Fprintln(g.out, ws+" in.WantComma()")
fmt.Fprintln(g.out, ws+"}")
fmt.Fprintln(g.out, ws+"in.Delim(']')")
case reflect.Struct:
dec := g.getDecoderName(t)
g.addType(t)
fmt.Fprintln(g.out, ws+dec+"(in, &"+out+")")
case reflect.Ptr:
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+" "+out+" = nil")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" "+out+" = new("+g.getType(t.Elem())+")")
g.genTypeDecoder(t.Elem(), "*"+out, tags, indent+1)
fmt.Fprintln(g.out, ws+"}")
case reflect.Map:
key := t.Key()
if key.Kind() != reflect.String {
return fmt.Errorf("map type %v not supported: only string keys are allowed", key)
}
elem := t.Elem()
tmpVar := g.uniqueVarName()
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+" in.Delim('{')")
fmt.Fprintln(g.out, ws+" if !in.IsDelim('}') {")
fmt.Fprintln(g.out, ws+" "+out+" = make("+g.getType(t)+")")
fmt.Fprintln(g.out, ws+" } else {")
fmt.Fprintln(g.out, ws+" "+out+" = nil")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" for !in.IsDelim('}') {")
fmt.Fprintln(g.out, ws+" key := "+g.getType(t.Key())+"(in.String())")
fmt.Fprintln(g.out, ws+" in.WantColon()")
fmt.Fprintln(g.out, ws+" var "+tmpVar+" "+g.getType(elem))
g.genTypeDecoder(elem, tmpVar, tags, indent+2)
fmt.Fprintln(g.out, ws+" ("+out+")[key] = "+tmpVar)
fmt.Fprintln(g.out, ws+" in.WantComma()")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" in.Delim('}')")
fmt.Fprintln(g.out, ws+"}")
case reflect.Interface:
if t.NumMethod() != 0 {
return fmt.Errorf("interface type %v not supported: only interface{} is allowed", t)
}
fmt.Fprintln(g.out, ws+out+" = in.Interface()")
default:
return fmt.Errorf("don't know how to decode %v", t)
}
return nil
}
func (g *Generator) genStructFieldDecoder(t reflect.Type, f reflect.StructField) error {
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
tags := parseFieldTags(f)
if tags.omit {
return nil
}
fmt.Fprintf(g.out, " case %q:\n", jsonName)
if err := g.genTypeDecoder(f.Type, "out."+f.Name, tags, 3); err != nil {
return err
}
if tags.required {
fmt.Fprintf(g.out, "%sSet = true\n", f.Name)
}
return nil
}
func (g *Generator) genRequiredFieldSet(t reflect.Type, f reflect.StructField) {
tags := parseFieldTags(f)
if !tags.required {
return
}
fmt.Fprintf(g.out, "var %sSet bool\n", f.Name)
}
func (g *Generator) genRequiredFieldCheck(t reflect.Type, f reflect.StructField) {
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
tags := parseFieldTags(f)
if !tags.required {
return
}
g.imports["fmt"] = "fmt"
fmt.Fprintf(g.out, "if !%sSet {\n", f.Name)
fmt.Fprintf(g.out, " in.AddError(fmt.Errorf(\"key '%s' is required\"))\n", jsonName)
fmt.Fprintf(g.out, "}\n")
}
func mergeStructFields(fields1, fields2 []reflect.StructField) (fields []reflect.StructField) {
used := map[string]bool{}
for _, f := range fields2 {
used[f.Name] = true
fields = append(fields, f)
}
for _, f := range fields1 {
if !used[f.Name] {
fields = append(fields, f)
}
}
return
}
func getStructFields(t reflect.Type) ([]reflect.StructField, error) {
if t.Kind() != reflect.Struct {
return nil, fmt.Errorf("got %v; expected a struct", t)
}
var efields []reflect.StructField
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if !f.Anonymous {
continue
}
t1 := f.Type
if t1.Kind() == reflect.Ptr {
t1 = t1.Elem()
}
fs, err := getStructFields(t1)
if err != nil {
return nil, fmt.Errorf("error processing embedded field: %v", err)
}
efields = mergeStructFields(efields, fs)
}
var fields []reflect.StructField
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if f.Anonymous {
continue
}
c := []rune(f.Name)[0]
if unicode.IsUpper(c) {
fields = append(fields, f)
}
}
return mergeStructFields(efields, fields), nil
}
func (g *Generator) genDecoder(t reflect.Type) error {
switch t.Kind() {
case reflect.Slice:
return g.genSliceDecoder(t)
default:
return g.genStructDecoder(t)
}
}
func (g *Generator) genSliceDecoder(t reflect.Type) error {
if t.Kind() != reflect.Slice {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice type", t)
}
fname := g.getDecoderName(t)
typ := g.getType(t)
fmt.Fprintln(g.out, "func "+fname+"(in *jlexer.Lexer, out *"+typ+") {")
err := g.genTypeDecoderNoCheck(t, "*out", fieldTags{}, 1)
if err != nil {
return err
}
fmt.Fprintln(g.out, "}")
return nil
}
func (g *Generator) genStructDecoder(t reflect.Type) error {
if t.Kind() != reflect.Struct {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct type", t)
}
fname := g.getDecoderName(t)
typ := g.getType(t)
fmt.Fprintln(g.out, "func "+fname+"(in *jlexer.Lexer, out *"+typ+") {")
fmt.Fprintln(g.out, " if in.IsNull() {")
fmt.Fprintln(g.out, " in.Skip()")
fmt.Fprintln(g.out, " return")
fmt.Fprintln(g.out, " }")
// Init embedded pointer fields.
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if !f.Anonymous || f.Type.Kind() != reflect.Ptr {
continue
}
fmt.Fprintln(g.out, " out."+f.Name+" = new("+g.getType(f.Type.Elem())+")")
}
fs, err := getStructFields(t)
if err != nil {
return fmt.Errorf("cannot generate decoder for %v: %v", t, err)
}
for _, f := range fs {
g.genRequiredFieldSet(t, f)
}
fmt.Fprintln(g.out, " in.Delim('{')")
fmt.Fprintln(g.out, " for !in.IsDelim('}') {")
fmt.Fprintln(g.out, " key := in.UnsafeString()")
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 {
if err := g.genStructFieldDecoder(t, f); err != nil {
return err
}
}
fmt.Fprintln(g.out, " default:")
fmt.Fprintln(g.out, " in.SkipRecursive()")
fmt.Fprintln(g.out, " }")
fmt.Fprintln(g.out, " in.WantComma()")
fmt.Fprintln(g.out, " }")
fmt.Fprintln(g.out, " in.Delim('}')")
for _, f := range fs {
g.genRequiredFieldCheck(t, f)
}
fmt.Fprintln(g.out, "}")
return nil
}
func (g *Generator) genStructUnmarshaller(t reflect.Type) error {
if t.Kind() != reflect.Struct && t.Kind() != reflect.Slice {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice type", t)
}
fname := g.getDecoderName(t)
typ := g.getType(t)
if !g.noStdMarshalers {
fmt.Fprintln(g.out, "// UnmarshalJSON supports json.Unmarshaler interface")
fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalJSON(data []byte) error {")
fmt.Fprintln(g.out, " r := jlexer.Lexer{Data: data}")
fmt.Fprintln(g.out, " "+fname+"(&r, v)")
fmt.Fprintln(g.out, " return r.Error()")
fmt.Fprintln(g.out, "}")
}
fmt.Fprintln(g.out, "// UnmarshalEasyJSON supports easyjson.Unmarshaler interface")
fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalEasyJSON(l *jlexer.Lexer) {")
fmt.Fprintln(g.out, " "+fname+"(l, v)")
fmt.Fprintln(g.out, "}")
return nil
}

313
vendor/github.com/mailru/easyjson/gen/encoder.go generated vendored Normal file
View file

@ -0,0 +1,313 @@
package gen
import (
"encoding/json"
"fmt"
"reflect"
"strconv"
"strings"
"github.com/mailru/easyjson"
)
func (g *Generator) getEncoderName(t reflect.Type) string {
return g.functionName("encode", t)
}
var primitiveEncoders = map[reflect.Kind]string{
reflect.String: "out.String(string(%v))",
reflect.Bool: "out.Bool(bool(%v))",
reflect.Int: "out.Int(int(%v))",
reflect.Int8: "out.Int8(int8(%v))",
reflect.Int16: "out.Int16(int16(%v))",
reflect.Int32: "out.Int32(int32(%v))",
reflect.Int64: "out.Int64(int64(%v))",
reflect.Uint: "out.Uint(uint(%v))",
reflect.Uint8: "out.Uint8(uint8(%v))",
reflect.Uint16: "out.Uint16(uint16(%v))",
reflect.Uint32: "out.Uint32(uint32(%v))",
reflect.Uint64: "out.Uint64(uint64(%v))",
reflect.Float32: "out.Float32(float32(%v))",
reflect.Float64: "out.Float64(float64(%v))",
}
var primitiveStringEncoders = map[reflect.Kind]string{
reflect.Int: "out.IntStr(int(%v))",
reflect.Int8: "out.Int8Str(int8(%v))",
reflect.Int16: "out.Int16Str(int16(%v))",
reflect.Int32: "out.Int32Str(int32(%v))",
reflect.Int64: "out.Int64Str(int64(%v))",
reflect.Uint: "out.UintStr(uint(%v))",
reflect.Uint8: "out.Uint8Str(uint8(%v))",
reflect.Uint16: "out.Uint16Str(uint16(%v))",
reflect.Uint32: "out.Uint32Str(uint32(%v))",
reflect.Uint64: "out.Uint64Str(uint64(%v))",
}
// fieldTags contains parsed version of json struct field tags.
type fieldTags struct {
name string
omit bool
omitEmpty bool
noOmitEmpty bool
asString bool
required bool
}
// parseFieldTags parses the json field tag into a structure.
func parseFieldTags(f reflect.StructField) fieldTags {
var ret fieldTags
for i, s := range strings.Split(f.Tag.Get("json"), ",") {
switch {
case i == 0 && s == "-":
ret.omit = true
case i == 0:
ret.name = s
case s == "omitempty":
ret.omitEmpty = true
case s == "!omitempty":
ret.noOmitEmpty = true
case s == "string":
ret.asString = true
case s == "required":
ret.required = true
}
}
return ret
}
// genTypeEncoder generates code that encodes in of type t into the writer, but uses marshaler interface if implemented by t.
func (g *Generator) genTypeEncoder(t reflect.Type, in string, tags fieldTags, indent int) error {
ws := strings.Repeat(" ", indent)
marshalerIface := reflect.TypeOf((*easyjson.Marshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(marshalerIface) {
fmt.Fprintln(g.out, ws+"("+in+").MarshalEasyJSON(out)")
return nil
}
marshalerIface = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
if reflect.PtrTo(t).Implements(marshalerIface) {
fmt.Fprintln(g.out, ws+"out.Raw( ("+in+").MarshalJSON() )")
return nil
}
err := g.genTypeEncoderNoCheck(t, in, tags, indent)
return err
}
// genTypeEncoderNoCheck generates code that encodes in of type t into the writer.
func (g *Generator) genTypeEncoderNoCheck(t reflect.Type, in string, tags fieldTags, indent int) error {
ws := strings.Repeat(" ", indent)
// Check whether type is primitive, needs to be done after interface check.
if enc := primitiveStringEncoders[t.Kind()]; enc != "" && tags.asString {
fmt.Fprintf(g.out, ws+enc+"\n", in)
return nil
} else if enc := primitiveEncoders[t.Kind()]; enc != "" {
fmt.Fprintf(g.out, ws+enc+"\n", in)
return nil
}
switch t.Kind() {
case reflect.Slice:
elem := t.Elem()
iVar := g.uniqueVarName()
vVar := g.uniqueVarName()
fmt.Fprintln(g.out, ws+"out.RawByte('[')")
fmt.Fprintln(g.out, ws+"for "+iVar+", "+vVar+" := range "+in+" {")
fmt.Fprintln(g.out, ws+" if "+iVar+" > 0 {")
fmt.Fprintln(g.out, ws+" out.RawByte(',')")
fmt.Fprintln(g.out, ws+" }")
g.genTypeEncoder(elem, vVar, tags, indent+1)
fmt.Fprintln(g.out, ws+"}")
fmt.Fprintln(g.out, ws+"out.RawByte(']')")
case reflect.Struct:
enc := g.getEncoderName(t)
g.addType(t)
fmt.Fprintln(g.out, ws+enc+"(out, "+in+")")
case reflect.Ptr:
fmt.Fprintln(g.out, ws+"if "+in+" == nil {")
fmt.Fprintln(g.out, ws+` out.RawString("null")`)
fmt.Fprintln(g.out, ws+"} else {")
g.genTypeEncoder(t.Elem(), "*"+in, tags, indent+1)
fmt.Fprintln(g.out, ws+"}")
case reflect.Map:
key := t.Key()
if key.Kind() != reflect.String {
return fmt.Errorf("map type %v not supported: only string keys are allowed", key)
}
tmpVar := g.uniqueVarName()
fmt.Fprintln(g.out, ws+"if "+in+" == nil {")
fmt.Fprintln(g.out, ws+" out.RawString(`null`)")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" out.RawByte('{')")
fmt.Fprintln(g.out, ws+" "+tmpVar+"First := true")
fmt.Fprintln(g.out, ws+" for "+tmpVar+"Name, "+tmpVar+"Value := range "+in+" {")
fmt.Fprintln(g.out, ws+" if !"+tmpVar+"First { out.RawByte(',') }")
fmt.Fprintln(g.out, ws+" "+tmpVar+"First = false")
fmt.Fprintln(g.out, ws+" out.String(string("+tmpVar+"Name))")
fmt.Fprintln(g.out, ws+" out.RawByte(':')")
g.genTypeEncoder(t.Elem(), tmpVar+"Value", tags, indent+2)
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" out.RawByte('}')")
fmt.Fprintln(g.out, ws+"}")
case reflect.Interface:
if t.NumMethod() != 0 {
return fmt.Errorf("interface type %v not supported: only interface{} is allowed", t)
}
fmt.Fprintln(g.out, ws+"out.Raw(json.Marshal("+in+"))")
default:
return fmt.Errorf("don't know how to encode %v", t)
}
return nil
}
func (g *Generator) notEmptyCheck(t reflect.Type, v string) string {
optionalIface := reflect.TypeOf((*easyjson.Optional)(nil)).Elem()
if reflect.PtrTo(t).Implements(optionalIface) {
return "(" + v + ").IsDefined()"
}
switch t.Kind() {
case reflect.Slice, reflect.Map:
return "len(" + v + ") != 0"
case reflect.Interface, reflect.Ptr:
return v + " != nil"
case reflect.Bool:
return v
case reflect.String:
return v + ` != ""`
case reflect.Float32, reflect.Float64,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return v + " != 0"
default:
return "true"
}
}
func (g *Generator) genStructFieldEncoder(t reflect.Type, f reflect.StructField) error {
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
tags := parseFieldTags(f)
if tags.omit {
return nil
}
if !tags.omitEmpty && !g.omitEmpty || tags.noOmitEmpty {
fmt.Fprintln(g.out, " if !first { out.RawByte(',') }")
fmt.Fprintln(g.out, " first = false")
fmt.Fprintf(g.out, " out.RawString(%q)\n", strconv.Quote(jsonName)+":")
return g.genTypeEncoder(f.Type, "in."+f.Name, tags, 1)
}
fmt.Fprintln(g.out, " if", g.notEmptyCheck(f.Type, "in."+f.Name), "{")
fmt.Fprintln(g.out, " if !first { out.RawByte(',') }")
fmt.Fprintln(g.out, " first = false")
fmt.Fprintf(g.out, " out.RawString(%q)\n", strconv.Quote(jsonName)+":")
if err := g.genTypeEncoder(f.Type, "in."+f.Name, tags, 2); err != nil {
return err
}
fmt.Fprintln(g.out, " }")
return nil
}
func (g *Generator) genEncoder(t reflect.Type) error {
switch t.Kind() {
case reflect.Slice:
return g.genSliceEncoder(t)
default:
return g.genStructEncoder(t)
}
}
func (g *Generator) genSliceEncoder(t reflect.Type) error {
if t.Kind() != reflect.Slice {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice type", t)
}
fname := g.getEncoderName(t)
typ := g.getType(t)
fmt.Fprintln(g.out, "func "+fname+"(out *jwriter.Writer, in "+typ+") {")
err := g.genTypeEncoderNoCheck(t, "in", fieldTags{}, 1)
if err != nil {
return err
}
fmt.Fprintln(g.out, "}")
return nil
}
func (g *Generator) genStructEncoder(t reflect.Type) error {
if t.Kind() != reflect.Struct {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct type")
}
fname := g.getEncoderName(t)
typ := g.getType(t)
fmt.Fprintln(g.out, "func "+fname+"(out *jwriter.Writer, in "+typ+") {")
fmt.Fprintln(g.out, " out.RawByte('{')")
fmt.Fprintln(g.out, " first := true")
fmt.Fprintln(g.out, " _ = first")
fs, err := getStructFields(t)
if err != nil {
return fmt.Errorf("cannot generate encoder for %v: %v", t, err)
}
for _, f := range fs {
if err := g.genStructFieldEncoder(t, f); err != nil {
return err
}
}
fmt.Fprintln(g.out, " out.RawByte('}')")
fmt.Fprintln(g.out, "}")
return nil
}
func (g *Generator) genStructMarshaller(t reflect.Type) error {
if t.Kind() != reflect.Struct && t.Kind() != reflect.Slice {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice type", t)
}
fname := g.getEncoderName(t)
typ := g.getType(t)
if !g.noStdMarshalers {
fmt.Fprintln(g.out, "// MarshalJSON supports json.Marshaler interface")
fmt.Fprintln(g.out, "func (v "+typ+") MarshalJSON() ([]byte, error) {")
fmt.Fprintln(g.out, " w := jwriter.Writer{}")
fmt.Fprintln(g.out, " "+fname+"(&w, v)")
fmt.Fprintln(g.out, " return w.Buffer.BuildBytes(), w.Error")
fmt.Fprintln(g.out, "}")
}
fmt.Fprintln(g.out, "// MarshalEasyJSON supports easyjson.Marshaler interface")
fmt.Fprintln(g.out, "func (v "+typ+") MarshalEasyJSON(w *jwriter.Writer) {")
fmt.Fprintln(g.out, " "+fname+"(w, v)")
fmt.Fprintln(g.out, "}")
return nil
}

395
vendor/github.com/mailru/easyjson/gen/generator.go generated vendored Normal file
View file

@ -0,0 +1,395 @@
package gen
import (
"bytes"
"fmt"
"hash/fnv"
"io"
"path"
"reflect"
"sort"
"strings"
"unicode"
)
const pkgWriter = "github.com/mailru/easyjson/jwriter"
const pkgLexer = "github.com/mailru/easyjson/jlexer"
// FieldNamer defines a policy for generating names for struct fields.
type FieldNamer interface {
GetJSONFieldName(t reflect.Type, f reflect.StructField) string
}
// Generator generates the requested marshallers/unmarshallers.
type Generator struct {
out *bytes.Buffer
pkgName string
pkgPath string
buildTags string
hashString string
varCounter int
noStdMarshalers bool
omitEmpty bool
fieldNamer FieldNamer
// package path to local alias map for tracking imports
imports map[string]string
// types that marshallers were requested for by user
marshallers map[reflect.Type]bool
// types that encoders were already generated for
typesSeen map[reflect.Type]bool
// types that encoders were requested for (e.g. by encoders of other types)
typesUnseen []reflect.Type
// function name to relevant type maps to track names of de-/encoders in
// case of a name clash or unnamed structs
functionNames map[string]reflect.Type
}
// NewGenerator initializes and returns a Generator.
func NewGenerator(filename string) *Generator {
ret := &Generator{
imports: map[string]string{
pkgWriter: "jwriter",
pkgLexer: "jlexer",
"encoding/json": "json",
},
fieldNamer: DefaultFieldNamer{},
marshallers: make(map[reflect.Type]bool),
typesSeen: make(map[reflect.Type]bool),
functionNames: make(map[string]reflect.Type),
}
// Use a file-unique prefix on all auxiliary functions to avoid
// name clashes.
hash := fnv.New32()
hash.Write([]byte(filename))
ret.hashString = fmt.Sprintf("%x", hash.Sum32())
return ret
}
// SetPkg sets the name and path of output package.
func (g *Generator) SetPkg(name, path string) {
g.pkgName = name
g.pkgPath = path
}
// SetBuildTags sets build tags for the output file.
func (g *Generator) SetBuildTags(tags string) {
g.buildTags = tags
}
// SetFieldNamer sets field naming strategy.
func (g *Generator) SetFieldNamer(n FieldNamer) {
g.fieldNamer = n
}
// UseSnakeCase sets snake_case field naming strategy.
func (g *Generator) UseSnakeCase() {
g.fieldNamer = SnakeCaseFieldNamer{}
}
// NoStdMarshalers instructs not to generate standard MarshalJSON/UnmarshalJSON
// methods (only the custom interface).
func (g *Generator) NoStdMarshalers() {
g.noStdMarshalers = true
}
// OmitEmpty triggers `json=",omitempty"` behaviour by default.
func (g *Generator) OmitEmpty() {
g.omitEmpty = true
}
// addTypes requests to generate en-/decoding functions for the given type.
func (g *Generator) addType(t reflect.Type) {
if g.typesSeen[t] {
return
}
for _, t1 := range g.typesUnseen {
if t1 == t {
return
}
}
g.typesUnseen = append(g.typesUnseen, t)
}
// Add requests to generate (un-)marshallers and en-/decoding functions for the type of given object.
func (g *Generator) Add(obj interface{}) {
t := reflect.TypeOf(obj)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
g.addType(t)
g.marshallers[t] = true
}
// printHeader prints package declaration and imports.
func (g *Generator) printHeader() {
if g.buildTags != "" {
fmt.Println("// +build ", g.buildTags)
fmt.Println()
}
fmt.Println("// AUTOGENERATED FILE: easyjson marshaller/unmarshallers.")
fmt.Println()
fmt.Println("package ", g.pkgName)
fmt.Println()
byAlias := map[string]string{}
var aliases []string
for path, alias := range g.imports {
aliases = append(aliases, alias)
byAlias[alias] = path
}
sort.Strings(aliases)
fmt.Println("import (")
for _, alias := range g.imports {
fmt.Printf(" %s %q\n", alias, byAlias[alias])
}
fmt.Println(")")
fmt.Println("")
fmt.Println("// suppress unused package warning")
fmt.Println("var (")
fmt.Println(" _ = json.RawMessage{}")
fmt.Println(" _ = jlexer.Lexer{}")
fmt.Println(" _ = jwriter.Writer{}")
fmt.Println(")")
fmt.Println()
}
// Run runs the generator and outputs generated code to out.
func (g *Generator) Run(out io.Writer) error {
g.out = &bytes.Buffer{}
for len(g.typesUnseen) > 0 {
t := g.typesUnseen[len(g.typesUnseen)-1]
g.typesUnseen = g.typesUnseen[:len(g.typesUnseen)-1]
g.typesSeen[t] = true
if err := g.genDecoder(t); err != nil {
return err
}
if err := g.genEncoder(t); err != nil {
return err
}
if !g.marshallers[t] {
continue
}
if err := g.genStructMarshaller(t); err != nil {
return err
}
if err := g.genStructUnmarshaller(t); err != nil {
return err
}
}
g.printHeader()
_, err := out.Write(g.out.Bytes())
return err
}
// pkgAlias creates and returns and import alias for a given package.
func (g *Generator) pkgAlias(pkgPath string) string {
if alias := g.imports[pkgPath]; alias != "" {
return alias
}
for i := 0; ; i++ {
alias := path.Base(pkgPath)
if i > 0 {
alias += fmt.Sprint(i)
}
exists := false
for _, v := range g.imports {
if v == alias {
exists = true
break
}
}
if !exists {
g.imports[pkgPath] = alias
return alias
}
}
}
// getType return the textual type name of given type that can be used in generated code.
func (g *Generator) getType(t reflect.Type) string {
if t.Name() == "" {
switch t.Kind() {
case reflect.Ptr:
return "*" + g.getType(t.Elem())
case reflect.Slice:
return "[]" + g.getType(t.Elem())
case reflect.Map:
return "map[" + g.getType(t.Key()) + "]" + g.getType(t.Elem())
}
}
if t.Name() == "" || t.PkgPath() == "" {
return t.String()
} else if t.PkgPath() == g.pkgPath {
return t.Name()
}
// TODO: unnamed structs.
return g.pkgAlias(t.PkgPath()) + "." + t.Name()
}
// uniqueVarName returns a file-unique name that can be used for generated variables.
func (g *Generator) uniqueVarName() string {
g.varCounter++
return fmt.Sprint("v", g.varCounter)
}
// safeName escapes unsafe characters in pkg/type name and returns a string that can be used
// in encoder/decoder names for the type.
func (g *Generator) safeName(t reflect.Type) string {
name := t.PkgPath()
if t.Name() == "" {
name += "anonymous"
} else {
name += "." + t.Name()
}
parts := []string{}
part := []rune{}
for _, c := range name {
if unicode.IsLetter(c) || unicode.IsDigit(c) {
part = append(part, c)
} else if len(part) > 0 {
parts = append(parts, string(part))
part = []rune{}
}
}
return joinFunctionNameParts(false, parts...)
}
// functionName returns a function name for a given type with a given prefix. If a function
// with this prefix already exists for a type, it is returned.
//
// Method is used to track encoder/decoder names for the type.
func (g *Generator) functionName(prefix string, t reflect.Type) string {
prefix = joinFunctionNameParts(true, "easyjson", g.hashString, prefix)
name := joinFunctionNameParts(true, prefix, g.safeName(t))
// Most of the names will be unique, try a shortcut first.
if e, ok := g.functionNames[name]; !ok || e == t {
g.functionNames[name] = t
return name
}
// Search if the function already exists.
for name1, t1 := range g.functionNames {
if t1 == t && strings.HasPrefix(name1, prefix) {
return name1
}
}
// Create a new name in the case of a clash.
for i := 1; ; i++ {
nm := fmt.Sprint(name, i)
if _, ok := g.functionNames[nm]; ok {
continue
}
g.functionNames[nm] = t
return nm
}
}
// DefaultFieldsNamer implements trivial naming policy equivalent to encoding/json.
type DefaultFieldNamer struct{}
func (DefaultFieldNamer) GetJSONFieldName(t reflect.Type, f reflect.StructField) string {
jsonName := strings.Split(f.Tag.Get("json"), ",")[0]
if jsonName != "" {
return jsonName
} else {
return f.Name
}
}
// SnakeCaseFieldNamer implements CamelCase to snake_case conversion for fields names.
type SnakeCaseFieldNamer struct{}
func camelToSnake(name string) string {
var ret bytes.Buffer
multipleUpper := false
var lastUpper rune
var beforeUpper rune
for _, c := range name {
// Non-lowercase character after uppercase is considered to be uppercase too.
isUpper := (unicode.IsUpper(c) || (lastUpper != 0 && !unicode.IsLower(c)))
if lastUpper != 0 {
// Output a delimiter if last character was either the first uppercase character
// in a row, or the last one in a row (e.g. 'S' in "HTTPServer").
// Do not output a delimiter at the beginning of the name.
firstInRow := !multipleUpper
lastInRow := !isUpper
if ret.Len() > 0 && (firstInRow || lastInRow) && beforeUpper != '_' {
ret.WriteByte('_')
}
ret.WriteRune(unicode.ToLower(lastUpper))
}
// Buffer uppercase char, do not output it yet as a delimiter may be required if the
// next character is lowercase.
if isUpper {
multipleUpper = (lastUpper != 0)
lastUpper = c
continue
}
ret.WriteRune(c)
lastUpper = 0
beforeUpper = c
multipleUpper = false
}
if lastUpper != 0 {
ret.WriteRune(unicode.ToLower(lastUpper))
}
return string(ret.Bytes())
}
func (SnakeCaseFieldNamer) GetJSONFieldName(t reflect.Type, f reflect.StructField) string {
jsonName := strings.Split(f.Tag.Get("json"), ",")[0]
if jsonName != "" {
return jsonName
}
return camelToSnake(f.Name)
}
func joinFunctionNameParts(keepFirst bool, parts ...string) string {
buf := bytes.NewBufferString("")
for i, part := range parts {
if i == 0 && keepFirst {
buf.WriteString(part)
} else {
if len(part) > 0 {
buf.WriteString(strings.ToUpper(string(part[0])))
}
if len(part) > 1 {
buf.WriteString(part[1:])
}
}
}
return buf.String()
}

View file

@ -0,0 +1,49 @@
package gen
import (
"testing"
)
func TestCamelToSnake(t *testing.T) {
for i, test := range []struct {
In, Out string
}{
{"", ""},
{"A", "a"},
{"SimpleExample", "simple_example"},
{"internalField", "internal_field"},
{"SomeHTTPStuff", "some_http_stuff"},
{"WriteJSON", "write_json"},
{"HTTP2Server", "http2_server"},
{"Some_Mixed_Case", "some_mixed_case"},
{"do_nothing", "do_nothing"},
{"JSONHTTPRPCServer", "jsonhttprpc_server"}, // nothing can be done here without a dictionary
} {
got := camelToSnake(test.In)
if got != test.Out {
t.Errorf("[%d] camelToSnake(%s) = %s; want %s", i, test.In, got, test.Out)
}
}
}
func TestJoinFunctionNameParts(t *testing.T) {
for i, test := range []struct {
keepFirst bool
parts []string
out string
}{
{false, []string{}, ""},
{false, []string{"a"}, "A"},
{false, []string{"simple", "example"}, "SimpleExample"},
{true, []string{"first", "example"}, "firstExample"},
{false, []string{"some", "UPPER", "case"}, "SomeUPPERCase"},
{false, []string{"number", "123"}, "Number123"},
} {
got := joinFunctionNameParts(test.keepFirst, test.parts...)
if got != test.out {
t.Errorf("[%d] joinFunctionNameParts(%v) = %s; want %s", i, test.parts, got, test.out)
}
}
}