...

Source file src/github.com/mailru/easyjson/gen/decoder.go

Documentation: github.com/mailru/easyjson/gen

     1  package gen
     2  
     3  import (
     4  	"encoding"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"reflect"
     9  	"strings"
    10  	"unicode"
    11  
    12  	"github.com/mailru/easyjson"
    13  )
    14  
    15  // Target this byte size for initial slice allocation to reduce garbage collection.
    16  const minSliceBytes = 64
    17  
    18  func (g *Generator) getDecoderName(t reflect.Type) string {
    19  	return g.functionName("decode", t)
    20  }
    21  
    22  var primitiveDecoders = map[reflect.Kind]string{
    23  	reflect.String:  "in.String()",
    24  	reflect.Bool:    "in.Bool()",
    25  	reflect.Int:     "in.Int()",
    26  	reflect.Int8:    "in.Int8()",
    27  	reflect.Int16:   "in.Int16()",
    28  	reflect.Int32:   "in.Int32()",
    29  	reflect.Int64:   "in.Int64()",
    30  	reflect.Uint:    "in.Uint()",
    31  	reflect.Uint8:   "in.Uint8()",
    32  	reflect.Uint16:  "in.Uint16()",
    33  	reflect.Uint32:  "in.Uint32()",
    34  	reflect.Uint64:  "in.Uint64()",
    35  	reflect.Float32: "in.Float32()",
    36  	reflect.Float64: "in.Float64()",
    37  }
    38  
    39  var primitiveStringDecoders = map[reflect.Kind]string{
    40  	reflect.String:  "in.String()",
    41  	reflect.Int:     "in.IntStr()",
    42  	reflect.Int8:    "in.Int8Str()",
    43  	reflect.Int16:   "in.Int16Str()",
    44  	reflect.Int32:   "in.Int32Str()",
    45  	reflect.Int64:   "in.Int64Str()",
    46  	reflect.Uint:    "in.UintStr()",
    47  	reflect.Uint8:   "in.Uint8Str()",
    48  	reflect.Uint16:  "in.Uint16Str()",
    49  	reflect.Uint32:  "in.Uint32Str()",
    50  	reflect.Uint64:  "in.Uint64Str()",
    51  	reflect.Uintptr: "in.UintptrStr()",
    52  	reflect.Float32: "in.Float32Str()",
    53  	reflect.Float64: "in.Float64Str()",
    54  }
    55  
    56  var customDecoders = map[string]string{
    57  	"json.Number": "in.JsonNumber()",
    58  }
    59  
    60  // genTypeDecoder generates decoding code for the type t, but uses unmarshaler interface if implemented by t.
    61  func (g *Generator) genTypeDecoder(t reflect.Type, out string, tags fieldTags, indent int) error {
    62  	ws := strings.Repeat("  ", indent)
    63  
    64  	unmarshalerIface := reflect.TypeOf((*easyjson.Unmarshaler)(nil)).Elem()
    65  	if reflect.PtrTo(t).Implements(unmarshalerIface) {
    66  		fmt.Fprintln(g.out, ws+"("+out+").UnmarshalEasyJSON(in)")
    67  		return nil
    68  	}
    69  
    70  	unmarshalerIface = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
    71  	if reflect.PtrTo(t).Implements(unmarshalerIface) {
    72  		fmt.Fprintln(g.out, ws+"if data := in.Raw(); in.Ok() {")
    73  		fmt.Fprintln(g.out, ws+"  in.AddError( ("+out+").UnmarshalJSON(data) )")
    74  		fmt.Fprintln(g.out, ws+"}")
    75  		return nil
    76  	}
    77  
    78  	unmarshalerIface = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
    79  	if reflect.PtrTo(t).Implements(unmarshalerIface) {
    80  		fmt.Fprintln(g.out, ws+"if data := in.UnsafeBytes(); in.Ok() {")
    81  		fmt.Fprintln(g.out, ws+"  in.AddError( ("+out+").UnmarshalText(data) )")
    82  		fmt.Fprintln(g.out, ws+"}")
    83  		return nil
    84  	}
    85  
    86  	err := g.genTypeDecoderNoCheck(t, out, tags, indent)
    87  	return err
    88  }
    89  
    90  // returns true if the type t implements one of the custom unmarshaler interfaces
    91  func hasCustomUnmarshaler(t reflect.Type) bool {
    92  	t = reflect.PtrTo(t)
    93  	return t.Implements(reflect.TypeOf((*easyjson.Unmarshaler)(nil)).Elem()) ||
    94  		t.Implements(reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()) ||
    95  		t.Implements(reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem())
    96  }
    97  
    98  func hasUnknownsUnmarshaler(t reflect.Type) bool {
    99  	t = reflect.PtrTo(t)
   100  	return t.Implements(reflect.TypeOf((*easyjson.UnknownsUnmarshaler)(nil)).Elem())
   101  }
   102  
   103  func hasUnknownsMarshaler(t reflect.Type) bool {
   104  	t = reflect.PtrTo(t)
   105  	return t.Implements(reflect.TypeOf((*easyjson.UnknownsMarshaler)(nil)).Elem())
   106  }
   107  
   108  // genTypeDecoderNoCheck generates decoding code for the type t.
   109  func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags fieldTags, indent int) error {
   110  	ws := strings.Repeat("  ", indent)
   111  	// Check whether type is primitive, needs to be done after interface check.
   112  	if dec := customDecoders[t.String()]; dec != "" {
   113  		fmt.Fprintln(g.out, ws+out+" = "+dec)
   114  		return nil
   115  	} else if dec := primitiveStringDecoders[t.Kind()]; dec != "" && tags.asString {
   116  		if tags.intern && t.Kind() == reflect.String {
   117  			dec = "in.StringIntern()"
   118  		}
   119  		fmt.Fprintln(g.out, ws+out+" = "+g.getType(t)+"("+dec+")")
   120  		return nil
   121  	} else if dec := primitiveDecoders[t.Kind()]; dec != "" {
   122  		if tags.intern && t.Kind() == reflect.String {
   123  			dec = "in.StringIntern()"
   124  		}
   125  		if tags.noCopy && t.Kind() == reflect.String {
   126  			dec = "in.UnsafeString()"
   127  		}
   128  		fmt.Fprintln(g.out, ws+out+" = "+g.getType(t)+"("+dec+")")
   129  		return nil
   130  	}
   131  
   132  	switch t.Kind() {
   133  	case reflect.Slice:
   134  		tmpVar := g.uniqueVarName()
   135  		elem := t.Elem()
   136  
   137  		if elem.Kind() == reflect.Uint8 && elem.Name() == "uint8" {
   138  			fmt.Fprintln(g.out, ws+"if in.IsNull() {")
   139  			fmt.Fprintln(g.out, ws+"  in.Skip()")
   140  			fmt.Fprintln(g.out, ws+"  "+out+" = nil")
   141  			fmt.Fprintln(g.out, ws+"} else {")
   142  			if g.simpleBytes {
   143  				fmt.Fprintln(g.out, ws+"  "+out+" = []byte(in.String())")
   144  			} else {
   145  				fmt.Fprintln(g.out, ws+"  "+out+" = in.Bytes()")
   146  			}
   147  
   148  			fmt.Fprintln(g.out, ws+"}")
   149  
   150  		} else {
   151  
   152  			capacity := 1
   153  			if elem.Size() > 0 {
   154  				capacity = minSliceBytes / int(elem.Size())
   155  			}
   156  
   157  			fmt.Fprintln(g.out, ws+"if in.IsNull() {")
   158  			fmt.Fprintln(g.out, ws+"  in.Skip()")
   159  			fmt.Fprintln(g.out, ws+"  "+out+" = nil")
   160  			fmt.Fprintln(g.out, ws+"} else {")
   161  			fmt.Fprintln(g.out, ws+"  in.Delim('[')")
   162  			fmt.Fprintln(g.out, ws+"  if "+out+" == nil {")
   163  			fmt.Fprintln(g.out, ws+"    if !in.IsDelim(']') {")
   164  			fmt.Fprintln(g.out, ws+"      "+out+" = make("+g.getType(t)+", 0, "+fmt.Sprint(capacity)+")")
   165  			fmt.Fprintln(g.out, ws+"    } else {")
   166  			fmt.Fprintln(g.out, ws+"      "+out+" = "+g.getType(t)+"{}")
   167  			fmt.Fprintln(g.out, ws+"    }")
   168  			fmt.Fprintln(g.out, ws+"  } else { ")
   169  			fmt.Fprintln(g.out, ws+"    "+out+" = ("+out+")[:0]")
   170  			fmt.Fprintln(g.out, ws+"  }")
   171  			fmt.Fprintln(g.out, ws+"  for !in.IsDelim(']') {")
   172  			fmt.Fprintln(g.out, ws+"    var "+tmpVar+" "+g.getType(elem))
   173  
   174  			if err := g.genTypeDecoder(elem, tmpVar, tags, indent+2); err != nil {
   175  				return err
   176  			}
   177  
   178  			fmt.Fprintln(g.out, ws+"    "+out+" = append("+out+", "+tmpVar+")")
   179  			fmt.Fprintln(g.out, ws+"    in.WantComma()")
   180  			fmt.Fprintln(g.out, ws+"  }")
   181  			fmt.Fprintln(g.out, ws+"  in.Delim(']')")
   182  			fmt.Fprintln(g.out, ws+"}")
   183  		}
   184  
   185  	case reflect.Array:
   186  		iterVar := g.uniqueVarName()
   187  		elem := t.Elem()
   188  
   189  		if elem.Kind() == reflect.Uint8 && elem.Name() == "uint8" {
   190  			fmt.Fprintln(g.out, ws+"if in.IsNull() {")
   191  			fmt.Fprintln(g.out, ws+"  in.Skip()")
   192  			fmt.Fprintln(g.out, ws+"} else {")
   193  			fmt.Fprintln(g.out, ws+"  copy("+out+"[:], in.Bytes())")
   194  			fmt.Fprintln(g.out, ws+"}")
   195  
   196  		} else {
   197  
   198  			length := t.Len()
   199  
   200  			fmt.Fprintln(g.out, ws+"if in.IsNull() {")
   201  			fmt.Fprintln(g.out, ws+"  in.Skip()")
   202  			fmt.Fprintln(g.out, ws+"} else {")
   203  			fmt.Fprintln(g.out, ws+"  in.Delim('[')")
   204  			fmt.Fprintln(g.out, ws+"  "+iterVar+" := 0")
   205  			fmt.Fprintln(g.out, ws+"  for !in.IsDelim(']') {")
   206  			fmt.Fprintln(g.out, ws+"    if "+iterVar+" < "+fmt.Sprint(length)+" {")
   207  
   208  			if err := g.genTypeDecoder(elem, "("+out+")["+iterVar+"]", tags, indent+3); err != nil {
   209  				return err
   210  			}
   211  
   212  			fmt.Fprintln(g.out, ws+"      "+iterVar+"++")
   213  			fmt.Fprintln(g.out, ws+"    } else {")
   214  			fmt.Fprintln(g.out, ws+"      in.SkipRecursive()")
   215  			fmt.Fprintln(g.out, ws+"    }")
   216  			fmt.Fprintln(g.out, ws+"    in.WantComma()")
   217  			fmt.Fprintln(g.out, ws+"  }")
   218  			fmt.Fprintln(g.out, ws+"  in.Delim(']')")
   219  			fmt.Fprintln(g.out, ws+"}")
   220  		}
   221  
   222  	case reflect.Struct:
   223  		dec := g.getDecoderName(t)
   224  		g.addType(t)
   225  
   226  		if len(out) > 0 && out[0] == '*' {
   227  			// NOTE: In order to remove an extra reference to a pointer
   228  			fmt.Fprintln(g.out, ws+dec+"(in, "+out[1:]+")")
   229  		} else {
   230  			fmt.Fprintln(g.out, ws+dec+"(in, &"+out+")")
   231  		}
   232  
   233  	case reflect.Ptr:
   234  		fmt.Fprintln(g.out, ws+"if in.IsNull() {")
   235  		fmt.Fprintln(g.out, ws+"  in.Skip()")
   236  		fmt.Fprintln(g.out, ws+"  "+out+" = nil")
   237  		fmt.Fprintln(g.out, ws+"} else {")
   238  		fmt.Fprintln(g.out, ws+"  if "+out+" == nil {")
   239  		fmt.Fprintln(g.out, ws+"    "+out+" = new("+g.getType(t.Elem())+")")
   240  		fmt.Fprintln(g.out, ws+"  }")
   241  
   242  		if err := g.genTypeDecoder(t.Elem(), "*"+out, tags, indent+1); err != nil {
   243  			return err
   244  		}
   245  
   246  		fmt.Fprintln(g.out, ws+"}")
   247  
   248  	case reflect.Map:
   249  		key := t.Key()
   250  		keyDec, ok := primitiveStringDecoders[key.Kind()]
   251  		if !ok && !hasCustomUnmarshaler(key) {
   252  			return fmt.Errorf("map type %v not supported: only string and integer keys and types implementing json.Unmarshaler are allowed", key)
   253  		} // else assume the caller knows what they are doing and that the custom unmarshaler performs the translation from string or integer keys to the key type
   254  		elem := t.Elem()
   255  		tmpVar := g.uniqueVarName()
   256  		keepEmpty := tags.required || tags.noOmitEmpty || (!g.omitEmpty && !tags.omitEmpty)
   257  
   258  		fmt.Fprintln(g.out, ws+"if in.IsNull() {")
   259  		fmt.Fprintln(g.out, ws+"  in.Skip()")
   260  		fmt.Fprintln(g.out, ws+"} else {")
   261  		fmt.Fprintln(g.out, ws+"  in.Delim('{')")
   262  		if !keepEmpty {
   263  			fmt.Fprintln(g.out, ws+"  if !in.IsDelim('}') {")
   264  		}
   265  		fmt.Fprintln(g.out, ws+"  "+out+" = make("+g.getType(t)+")")
   266  		if !keepEmpty {
   267  			fmt.Fprintln(g.out, ws+"  } else {")
   268  			fmt.Fprintln(g.out, ws+"  "+out+" = nil")
   269  			fmt.Fprintln(g.out, ws+"  }")
   270  		}
   271  
   272  		fmt.Fprintln(g.out, ws+"  for !in.IsDelim('}') {")
   273  		// NOTE: extra check for TextUnmarshaler. It overrides default methods.
   274  		if reflect.PtrTo(key).Implements(reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()) {
   275  			fmt.Fprintln(g.out, ws+"    var key "+g.getType(key))
   276  			fmt.Fprintln(g.out, ws+"if data := in.UnsafeBytes(); in.Ok() {")
   277  			fmt.Fprintln(g.out, ws+"  in.AddError(key.UnmarshalText(data) )")
   278  			fmt.Fprintln(g.out, ws+"}")
   279  		} else if keyDec != "" {
   280  			fmt.Fprintln(g.out, ws+"    key := "+g.getType(key)+"("+keyDec+")")
   281  		} else {
   282  			fmt.Fprintln(g.out, ws+"    var key "+g.getType(key))
   283  			if err := g.genTypeDecoder(key, "key", tags, indent+2); err != nil {
   284  				return err
   285  			}
   286  		}
   287  
   288  		fmt.Fprintln(g.out, ws+"    in.WantColon()")
   289  		fmt.Fprintln(g.out, ws+"    var "+tmpVar+" "+g.getType(elem))
   290  
   291  		if err := g.genTypeDecoder(elem, tmpVar, tags, indent+2); err != nil {
   292  			return err
   293  		}
   294  
   295  		fmt.Fprintln(g.out, ws+"    ("+out+")[key] = "+tmpVar)
   296  		fmt.Fprintln(g.out, ws+"    in.WantComma()")
   297  		fmt.Fprintln(g.out, ws+"  }")
   298  		fmt.Fprintln(g.out, ws+"  in.Delim('}')")
   299  		fmt.Fprintln(g.out, ws+"}")
   300  
   301  	case reflect.Interface:
   302  		if t.NumMethod() != 0 {
   303  			if g.interfaceIsEasyjsonUnmarshaller(t) {
   304  				fmt.Fprintln(g.out, ws+out+".UnmarshalEasyJSON(in)")
   305  			} else if g.interfaceIsJsonUnmarshaller(t) {
   306  				fmt.Fprintln(g.out, ws+out+".UnmarshalJSON(in.Raw())")
   307  			} else {
   308  				return fmt.Errorf("interface type %v not supported: only interface{} and easyjson/json Unmarshaler are allowed", t)
   309  			}
   310  		} else {
   311  			fmt.Fprintln(g.out, ws+"if m, ok := "+out+".(easyjson.Unmarshaler); ok {")
   312  			fmt.Fprintln(g.out, ws+"m.UnmarshalEasyJSON(in)")
   313  			fmt.Fprintln(g.out, ws+"} else if m, ok := "+out+".(json.Unmarshaler); ok {")
   314  			fmt.Fprintln(g.out, ws+"_ = m.UnmarshalJSON(in.Raw())")
   315  			fmt.Fprintln(g.out, ws+"} else {")
   316  			fmt.Fprintln(g.out, ws+"  "+out+" = in.Interface()")
   317  			fmt.Fprintln(g.out, ws+"}")
   318  		}
   319  	default:
   320  		return fmt.Errorf("don't know how to decode %v", t)
   321  	}
   322  	return nil
   323  
   324  }
   325  
   326  func (g *Generator) interfaceIsEasyjsonUnmarshaller(t reflect.Type) bool {
   327  	return t.Implements(reflect.TypeOf((*easyjson.Unmarshaler)(nil)).Elem())
   328  }
   329  
   330  func (g *Generator) interfaceIsJsonUnmarshaller(t reflect.Type) bool {
   331  	return t.Implements(reflect.TypeOf((*json.Unmarshaler)(nil)).Elem())
   332  }
   333  
   334  func (g *Generator) genStructFieldDecoder(t reflect.Type, f reflect.StructField) error {
   335  	jsonName := g.fieldNamer.GetJSONFieldName(t, f)
   336  	tags := parseFieldTags(f)
   337  
   338  	if tags.omit {
   339  		return nil
   340  	}
   341  	if tags.intern && tags.noCopy {
   342  		return errors.New("Mutually exclusive tags are specified: 'intern' and 'nocopy'")
   343  	}
   344  
   345  	fmt.Fprintf(g.out, "    case %q:\n", jsonName)
   346  	if err := g.genTypeDecoder(f.Type, "out."+f.Name, tags, 3); err != nil {
   347  		return err
   348  	}
   349  
   350  	if tags.required {
   351  		fmt.Fprintf(g.out, "%sSet = true\n", f.Name)
   352  	}
   353  
   354  	return nil
   355  }
   356  
   357  func (g *Generator) genRequiredFieldSet(t reflect.Type, f reflect.StructField) {
   358  	tags := parseFieldTags(f)
   359  
   360  	if !tags.required {
   361  		return
   362  	}
   363  
   364  	fmt.Fprintf(g.out, "var %sSet bool\n", f.Name)
   365  }
   366  
   367  func (g *Generator) genRequiredFieldCheck(t reflect.Type, f reflect.StructField) {
   368  	jsonName := g.fieldNamer.GetJSONFieldName(t, f)
   369  	tags := parseFieldTags(f)
   370  
   371  	if !tags.required {
   372  		return
   373  	}
   374  
   375  	g.imports["fmt"] = "fmt"
   376  
   377  	fmt.Fprintf(g.out, "if !%sSet {\n", f.Name)
   378  	fmt.Fprintf(g.out, "    in.AddError(fmt.Errorf(\"key '%s' is required\"))\n", jsonName)
   379  	fmt.Fprintf(g.out, "}\n")
   380  }
   381  
   382  func mergeStructFields(fields1, fields2 []reflect.StructField) (fields []reflect.StructField) {
   383  	used := map[string]bool{}
   384  	for _, f := range fields2 {
   385  		used[f.Name] = true
   386  		fields = append(fields, f)
   387  	}
   388  
   389  	for _, f := range fields1 {
   390  		if !used[f.Name] {
   391  			fields = append(fields, f)
   392  		}
   393  	}
   394  	return
   395  }
   396  
   397  func getStructFields(t reflect.Type) ([]reflect.StructField, error) {
   398  	if t.Kind() != reflect.Struct {
   399  		return nil, fmt.Errorf("got %v; expected a struct", t)
   400  	}
   401  
   402  	var efields []reflect.StructField
   403  	var fields []reflect.StructField
   404  	for i := 0; i < t.NumField(); i++ {
   405  		f := t.Field(i)
   406  		tags := parseFieldTags(f)
   407  		if !f.Anonymous || tags.name != "" {
   408  			continue
   409  		}
   410  
   411  		t1 := f.Type
   412  		if t1.Kind() == reflect.Ptr {
   413  			t1 = t1.Elem()
   414  		}
   415  
   416  		if t1.Kind() == reflect.Struct {
   417  			fs, err := getStructFields(t1)
   418  			if err != nil {
   419  				return nil, fmt.Errorf("error processing embedded field: %v", err)
   420  			}
   421  			efields = mergeStructFields(efields, fs)
   422  		} else if (t1.Kind() >= reflect.Bool && t1.Kind() < reflect.Complex128) || t1.Kind() == reflect.String {
   423  			if strings.Contains(f.Name, ".") || unicode.IsUpper([]rune(f.Name)[0]) {
   424  				fields = append(fields, f)
   425  			}
   426  		}
   427  	}
   428  
   429  	for i := 0; i < t.NumField(); i++ {
   430  		f := t.Field(i)
   431  		tags := parseFieldTags(f)
   432  		if f.Anonymous && tags.name == "" {
   433  			continue
   434  		}
   435  
   436  		c := []rune(f.Name)[0]
   437  		if unicode.IsUpper(c) {
   438  			fields = append(fields, f)
   439  		}
   440  	}
   441  	return mergeStructFields(efields, fields), nil
   442  }
   443  
   444  func (g *Generator) genDecoder(t reflect.Type) error {
   445  	switch t.Kind() {
   446  	case reflect.Slice, reflect.Array, reflect.Map:
   447  		return g.genSliceArrayDecoder(t)
   448  	default:
   449  		return g.genStructDecoder(t)
   450  	}
   451  }
   452  
   453  func (g *Generator) genSliceArrayDecoder(t reflect.Type) error {
   454  	switch t.Kind() {
   455  	case reflect.Slice, reflect.Array, reflect.Map:
   456  	default:
   457  		return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice/array/map type", t)
   458  	}
   459  
   460  	fname := g.getDecoderName(t)
   461  	typ := g.getType(t)
   462  
   463  	fmt.Fprintln(g.out, "func "+fname+"(in *jlexer.Lexer, out *"+typ+") {")
   464  	fmt.Fprintln(g.out, " isTopLevel := in.IsStart()")
   465  	err := g.genTypeDecoderNoCheck(t, "*out", fieldTags{}, 1)
   466  	if err != nil {
   467  		return err
   468  	}
   469  	fmt.Fprintln(g.out, "  if isTopLevel {")
   470  	fmt.Fprintln(g.out, "    in.Consumed()")
   471  	fmt.Fprintln(g.out, "  }")
   472  	fmt.Fprintln(g.out, "}")
   473  
   474  	return nil
   475  }
   476  
   477  func (g *Generator) genStructDecoder(t reflect.Type) error {
   478  	if t.Kind() != reflect.Struct {
   479  		return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct type", t)
   480  	}
   481  
   482  	fname := g.getDecoderName(t)
   483  	typ := g.getType(t)
   484  
   485  	fmt.Fprintln(g.out, "func "+fname+"(in *jlexer.Lexer, out *"+typ+") {")
   486  	fmt.Fprintln(g.out, "  isTopLevel := in.IsStart()")
   487  	fmt.Fprintln(g.out, "  if in.IsNull() {")
   488  	fmt.Fprintln(g.out, "    if isTopLevel {")
   489  	fmt.Fprintln(g.out, "      in.Consumed()")
   490  	fmt.Fprintln(g.out, "    }")
   491  	fmt.Fprintln(g.out, "    in.Skip()")
   492  	fmt.Fprintln(g.out, "    return")
   493  	fmt.Fprintln(g.out, "  }")
   494  
   495  	// Init embedded pointer fields.
   496  	for i := 0; i < t.NumField(); i++ {
   497  		f := t.Field(i)
   498  		if !f.Anonymous || f.Type.Kind() != reflect.Ptr {
   499  			continue
   500  		}
   501  		fmt.Fprintln(g.out, "  out."+f.Name+" = new("+g.getType(f.Type.Elem())+")")
   502  	}
   503  
   504  	fs, err := getStructFields(t)
   505  	if err != nil {
   506  		return fmt.Errorf("cannot generate decoder for %v: %v", t, err)
   507  	}
   508  
   509  	for _, f := range fs {
   510  		g.genRequiredFieldSet(t, f)
   511  	}
   512  
   513  	fmt.Fprintln(g.out, "  in.Delim('{')")
   514  	fmt.Fprintln(g.out, "  for !in.IsDelim('}') {")
   515  	fmt.Fprintf(g.out, "    key := in.UnsafeFieldName(%v)\n", g.skipMemberNameUnescaping)
   516  	fmt.Fprintln(g.out, "    in.WantColon()")
   517  	fmt.Fprintln(g.out, "    if in.IsNull() {")
   518  	fmt.Fprintln(g.out, "       in.Skip()")
   519  	fmt.Fprintln(g.out, "       in.WantComma()")
   520  	fmt.Fprintln(g.out, "       continue")
   521  	fmt.Fprintln(g.out, "    }")
   522  
   523  	fmt.Fprintln(g.out, "    switch key {")
   524  	for _, f := range fs {
   525  		if err := g.genStructFieldDecoder(t, f); err != nil {
   526  			return err
   527  		}
   528  	}
   529  
   530  	fmt.Fprintln(g.out, "    default:")
   531  	if g.disallowUnknownFields {
   532  		fmt.Fprintln(g.out, `      in.AddError(&jlexer.LexerError{
   533            Offset: in.GetPos(),
   534            Reason: "unknown field",
   535            Data: key,
   536        })`)
   537  	} else if hasUnknownsUnmarshaler(t) {
   538  		fmt.Fprintln(g.out, "      out.UnmarshalUnknown(in, key)")
   539  	} else {
   540  		fmt.Fprintln(g.out, "      in.SkipRecursive()")
   541  	}
   542  	fmt.Fprintln(g.out, "    }")
   543  	fmt.Fprintln(g.out, "    in.WantComma()")
   544  	fmt.Fprintln(g.out, "  }")
   545  	fmt.Fprintln(g.out, "  in.Delim('}')")
   546  	fmt.Fprintln(g.out, "  if isTopLevel {")
   547  	fmt.Fprintln(g.out, "    in.Consumed()")
   548  	fmt.Fprintln(g.out, "  }")
   549  
   550  	for _, f := range fs {
   551  		g.genRequiredFieldCheck(t, f)
   552  	}
   553  
   554  	fmt.Fprintln(g.out, "}")
   555  
   556  	return nil
   557  }
   558  
   559  func (g *Generator) genStructUnmarshaler(t reflect.Type) error {
   560  	switch t.Kind() {
   561  	case reflect.Slice, reflect.Array, reflect.Map, reflect.Struct:
   562  	default:
   563  		return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice/array/map type", t)
   564  	}
   565  
   566  	fname := g.getDecoderName(t)
   567  	typ := g.getType(t)
   568  
   569  	if !g.noStdMarshalers {
   570  		fmt.Fprintln(g.out, "// UnmarshalJSON supports json.Unmarshaler interface")
   571  		fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalJSON(data []byte) error {")
   572  		fmt.Fprintln(g.out, "  r := jlexer.Lexer{Data: data}")
   573  		fmt.Fprintln(g.out, "  "+fname+"(&r, v)")
   574  		fmt.Fprintln(g.out, "  return r.Error()")
   575  		fmt.Fprintln(g.out, "}")
   576  	}
   577  
   578  	fmt.Fprintln(g.out, "// UnmarshalEasyJSON supports easyjson.Unmarshaler interface")
   579  	fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalEasyJSON(l *jlexer.Lexer) {")
   580  	fmt.Fprintln(g.out, "  "+fname+"(l, v)")
   581  	fmt.Fprintln(g.out, "}")
   582  
   583  	return nil
   584  }
   585  

View as plain text