commit 28447855779c4df0f19d1840af686fe53b9e3838
parent c60a101913909d4969bb17bf7da824f2e197317d
Author: francoispqt <francois@parquet.ninja>
Date: Sat, 26 Jan 2019 01:38:53 +0800
add comments, refactor code for code generator
Diffstat:
9 files changed, 182 insertions(+), 155 deletions(-)
diff --git a/gojay/codegen/generator.go b/gojay/codegen/generator.go
@@ -11,6 +11,9 @@ import (
"github.com/viant/toolbox"
)
+const gojayPackage = "github.com/francoispqt/gojay"
+
+// Generator holds the content to generate the gojay code
type Generator struct {
fileInfo *toolbox.FileSetInfo
types map[string]string
@@ -27,14 +30,17 @@ type Generator struct {
options *Options
}
+// Returns the type from the the fileInfo
func (g *Generator) Type(typeName string) *toolbox.TypeInfo {
return g.fileInfo.Type(typeName)
}
+// addImport adds an import package to be printed on the generated code
func (g *Generator) addImport(pkg string) {
g.imports[`"`+pkg+`"`] = true
}
+// we initiate the variables containing the code to be generated
func (g *Generator) init() {
g.filedInit = []string{}
g.imports = map[string]bool{}
@@ -42,27 +48,41 @@ func (g *Generator) init() {
g.structTypes = map[string]string{}
g.sliceTypes = map[string]string{}
g.poolInit = map[string]string{}
- g.addImport("github.com/francoispqt/gojay")
+ g.addImport(gojayPackage)
+ // if we want pools, add the sync package right away
+ if g.options.PoolObjects {
+ g.addImport("sync")
+ }
}
-func (g *Generator) Generate(options *Options) error {
+// NewGenerator creates a new generator with the given options
+func NewGenerator(options *Options) *Generator {
+ var g = &Generator{}
+ // first we validate the flags
if err := options.Validate(); err != nil {
- return err
+ panic(err)
}
g.options = options
+ // we initiate the values on the generator
g.init()
+ return g
+}
- if options.PoolObjects {
- g.addImport("sync")
- }
- if err := g.readPackageCode(options.Source); err != nil {
+// Generate generates the gojay implementation code
+func (g *Generator) Generate() error {
+ // first we read the code from which we should find the types
+ if err := g.readPackageCode(g.options.Source); err != nil {
return err
}
- for _, rootType := range options.Types {
+
+ // then we generate code for the types given
+ for _, rootType := range g.options.Types {
if err := g.generateStructCode(rootType); err != nil {
return err
}
}
+
+ //
g.Imports = strings.Join(toolbox.MapKeysToStringSlice(g.imports), "\n")
return g.writeCode()
}
@@ -94,8 +114,6 @@ func (g *Generator) writeCode() error {
return err
}
- fmt.Println(string(expandedCode))
-
code, err := format.Source([]byte(expandedCode))
if err != nil {
@@ -222,5 +240,11 @@ func (g *Generator) readPackageCode(pkgPath string) error {
g.Pkg = filepath.Base(p)
g.fileInfo, err = toolbox.NewFileSetInfo(p)
}
+
+ // if Pkg flag is set use it
+ if g.options.Pkg != "" {
+ g.Pkg = g.options.Pkg
+ }
+
return err
}
diff --git a/gojay/codegen/generator_test.go b/gojay/codegen/generator_test.go
@@ -57,8 +57,8 @@ func TestGenerator_Generate(t *testing.T) {
}
for _, useCase := range useCases {
- gen := &Generator{}
- err := gen.Generate(useCase.options)
+ gen := NewGenerator(useCase.options)
+ err := gen.Generate()
if useCase.hasError {
assert.NotNil(t, err, useCase.description)
continue
diff --git a/gojay/codegen/options.go b/gojay/codegen/options.go
@@ -15,6 +15,7 @@ type Options struct {
Types []string
PoolObjects bool
TagName string
+ Pkg string
}
func (o *Options) Validate() error {
@@ -33,6 +34,7 @@ const (
optionKeyTypes = "t"
optionKeyTagName = "a"
optionKeyPoolObjects = "p"
+ optionKeyPkg = "pkg"
)
//NewOptionsWithFlagSet creates a new options for the supplide flagset
@@ -45,6 +47,7 @@ func NewOptionsWithFlagSet(set *flag.FlagSet) *Options {
result.PoolObjects = toolbox.AsBoolean(set.Lookup(optionKeyPoolObjects).Value.String())
result.TagName = set.Lookup(optionKeyTagName).Value.String()
result.Types = strings.Split(set.Lookup(optionKeyTypes).Value.String(), ",")
+ result.Pkg = set.Lookup(optionKeyPkg).Value.String()
if result.Source == "" {
result.Source = url.NewResource(".").ParsedURL.Path
}
diff --git a/gojay/codegen/struct.go b/gojay/codegen/struct.go
@@ -190,7 +190,6 @@ func (s *Struct) generateFieldDecoding(fields []*toolbox.FieldInfo) (string, []s
return "", nil, err
}
}
- // if is time.Time
} else if _, k, ok := s.typedFieldDecode(field, field.Type); ok {
templateKey = k
} else {
diff --git a/gojay/codegen/test/annotated_struct/encoding.go b/gojay/codegen/test/annotated_struct/encoding.go
@@ -6,6 +6,27 @@ import (
"time"
)
+type SubMessages []SubMessage
+
+func (s *SubMessages) UnmarshalJSONArray(dec *gojay.Decoder) error {
+ var value = SubMessage{}
+ if err := dec.Object(&value); err != nil {
+ return err
+ }
+ *s = append(*s, value)
+ return nil
+}
+
+func (s SubMessages) MarshalJSONArray(enc *gojay.Encoder) {
+ for i := range s {
+ enc.Object(&s[i])
+ }
+}
+
+func (s SubMessages) IsNil() bool {
+ return len(s) == 0
+}
+
type Ints []int
// UnmarshalJSONArray decodes JSON array elements into slice
@@ -75,27 +96,6 @@ func (s SubMessagesPtr) IsNil() bool {
return len(s) == 0
}
-type SubMessages []SubMessage
-
-func (s *SubMessages) UnmarshalJSONArray(dec *gojay.Decoder) error {
- var value = SubMessage{}
- if err := dec.Object(&value); err != nil {
- return err
- }
- *s = append(*s, value)
- return nil
-}
-
-func (s SubMessages) MarshalJSONArray(enc *gojay.Encoder) {
- for i := range s {
- enc.Object(&s[i])
- }
-}
-
-func (s SubMessages) IsNil() bool {
- return len(s) == 0
-}
-
// MarshalJSONObject implements MarshalerJSONObject
func (m *SubMessage) MarshalJSONObject(enc *gojay.Encoder) {
enc.IntKey("id", m.Id)
@@ -124,7 +124,7 @@ func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
case "startDate":
var format = "2006-01-02 15:04:05"
var value = time.Time{}
- err := dec.DecodeTime(&value, format)
+ err := dec.Time(&value, format)
if err == nil {
m.StartTime = value
}
@@ -133,7 +133,7 @@ func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
case "endDate":
var format = "2006-01-02 15:04:05"
var value = &time.Time{}
- err := dec.DecodeTime(value, format)
+ err := dec.Time(value, format)
if err == nil {
m.EndTime = value
}
diff --git a/gojay/codegen/test/basic_struct/encoding.go b/gojay/codegen/test/basic_struct/encoding.go
@@ -124,7 +124,7 @@ func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
case "StartTime":
var format = time.RFC3339
var value = time.Time{}
- err := dec.DecodeTime(&value, format)
+ err := dec.Time(&value, format)
if err == nil {
m.StartTime = value
}
@@ -133,7 +133,7 @@ func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
case "EndTime":
var format = time.RFC3339
var value = &time.Time{}
- err := dec.DecodeTime(value, format)
+ err := dec.Time(value, format)
if err == nil {
m.EndTime = value
}
diff --git a/gojay/codegen/test/embedded_struct/encoding.go b/gojay/codegen/test/embedded_struct/encoding.go
@@ -6,27 +6,6 @@ import (
"time"
)
-type SubMessages []SubMessage
-
-func (s *SubMessages) UnmarshalJSONArray(dec *gojay.Decoder) error {
- var value = SubMessage{}
- if err := dec.Object(&value); err != nil {
- return err
- }
- *s = append(*s, value)
- return nil
-}
-
-func (s SubMessages) MarshalJSONArray(enc *gojay.Encoder) {
- for i := range s {
- enc.Object(&s[i])
- }
-}
-
-func (s SubMessages) IsNil() bool {
- return len(s) == 0
-}
-
type Ints []int
// UnmarshalJSONArray decodes JSON array elements into slice
@@ -96,6 +75,55 @@ func (s SubMessagesPtr) IsNil() bool {
return len(s) == 0
}
+type SubMessages []SubMessage
+
+func (s *SubMessages) UnmarshalJSONArray(dec *gojay.Decoder) error {
+ var value = SubMessage{}
+ if err := dec.Object(&value); err != nil {
+ return err
+ }
+ *s = append(*s, value)
+ return nil
+}
+
+func (s SubMessages) MarshalJSONArray(enc *gojay.Encoder) {
+ for i := range s {
+ enc.Object(&s[i])
+ }
+}
+
+func (s SubMessages) IsNil() bool {
+ return len(s) == 0
+}
+
+// MarshalJSONObject implements MarshalerJSONObject
+func (i *BaseId) MarshalJSONObject(enc *gojay.Encoder) {
+ enc.IntKey("Id", i.Id)
+ enc.StringKey("Name", i.Name)
+}
+
+// IsNil checks if instance is nil
+func (i *BaseId) IsNil() bool {
+ return i == nil
+}
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (i *BaseId) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+
+ switch k {
+ case "Id":
+ return dec.Int(&i.Id)
+
+ case "Name":
+ return dec.String(&i.Name)
+
+ }
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (i *BaseId) NKeys() int { return 2 }
+
// MarshalJSONObject implements MarshalerJSONObject
func (m *SubMessage) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("Description", m.Description)
@@ -120,7 +148,7 @@ func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
case "StartTime":
var format = time.RFC3339
var value = time.Time{}
- err := dec.DecodeTime(&value, format)
+ err := dec.Time(&value, format)
if err == nil {
m.StartTime = value
}
@@ -129,7 +157,7 @@ func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
case "EndTime":
var format = time.RFC3339
var value = &time.Time{}
- err := dec.DecodeTime(value, format)
+ err := dec.Time(value, format)
if err == nil {
m.EndTime = value
}
@@ -192,7 +220,7 @@ func (m *Message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
case "StartTime":
var format = time.RFC3339
var value = time.Time{}
- err := dec.DecodeTime(&value, format)
+ err := dec.Time(&value, format)
if err == nil {
m.StartTime = value
}
@@ -201,7 +229,7 @@ func (m *Message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
case "EndTime":
var format = time.RFC3339
var value = &time.Time{}
- err := dec.DecodeTime(value, format)
+ err := dec.Time(value, format)
if err == nil {
m.EndTime = value
}
@@ -278,31 +306,3 @@ func (m *Message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
// NKeys returns the number of keys to unmarshal
func (m *Message) NKeys() int { return 14 }
-
-// MarshalJSONObject implements MarshalerJSONObject
-func (i *BaseId) MarshalJSONObject(enc *gojay.Encoder) {
- enc.IntKey("Id", i.Id)
- enc.StringKey("Name", i.Name)
-}
-
-// IsNil checks if instance is nil
-func (i *BaseId) IsNil() bool {
- return i == nil
-}
-
-// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
-func (i *BaseId) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
-
- switch k {
- case "Id":
- return dec.Int(&i.Id)
-
- case "Name":
- return dec.String(&i.Name)
-
- }
- return nil
-}
-
-// NKeys returns the number of keys to unmarshal
-func (i *BaseId) NKeys() int { return 2 }
diff --git a/gojay/codegen/test/pooled_struct/encoding.go b/gojay/codegen/test/pooled_struct/encoding.go
@@ -8,20 +8,20 @@ import (
)
func init() {
- MessagePool = &sync.Pool{
+ SubMessagePool = &sync.Pool{
New: func() interface{} {
- return &Message{}
+ return &SubMessage{}
},
}
- SubMessagePool = &sync.Pool{
+ MessagePool = &sync.Pool{
New: func() interface{} {
- return &SubMessage{}
+ return &Message{}
},
}
}
-var SubMessagePool *sync.Pool
var MessagePool *sync.Pool
+var SubMessagePool *sync.Pool
type Ints []int
@@ -114,6 +114,63 @@ func (s SubMessages) IsNil() bool {
}
// MarshalJSONObject implements MarshalerJSONObject
+func (m *SubMessage) MarshalJSONObject(enc *gojay.Encoder) {
+ enc.IntKey("Id", m.Id)
+ enc.StringKey("Description", m.Description)
+ enc.TimeKey("StartTime", &m.StartTime, time.RFC3339)
+ if m.EndTime != nil {
+ enc.TimeKey("EndTime", m.EndTime, time.RFC3339)
+ }
+}
+
+// IsNil checks if instance is nil
+func (m *SubMessage) IsNil() bool {
+ return m == nil
+}
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+
+ switch k {
+ case "Id":
+ return dec.Int(&m.Id)
+
+ case "Description":
+ return dec.String(&m.Description)
+
+ case "StartTime":
+ var format = time.RFC3339
+ var value = time.Time{}
+ err := dec.Time(&value, format)
+ if err == nil {
+ m.StartTime = value
+ }
+ return err
+
+ case "EndTime":
+ var format = time.RFC3339
+ var value = &time.Time{}
+ err := dec.Time(value, format)
+ if err == nil {
+ m.EndTime = value
+ }
+ return err
+
+ }
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (m *SubMessage) NKeys() int { return 4 }
+
+// Reset reset fields
+func (m *SubMessage) Reset() {
+ m.Id = 0
+ m.Description = ""
+ m.EndTime = nil
+}
+
+// MarshalJSONObject implements MarshalerJSONObject
func (m *Message) MarshalJSONObject(enc *gojay.Encoder) {
enc.IntKey("Id", m.Id)
enc.StringKey("Name", m.Name)
@@ -242,60 +299,3 @@ func (m *Message) Reset() {
m.IsTrue = nil
m.Payload = nil
}
-
-// MarshalJSONObject implements MarshalerJSONObject
-func (m *SubMessage) MarshalJSONObject(enc *gojay.Encoder) {
- enc.IntKey("Id", m.Id)
- enc.StringKey("Description", m.Description)
- enc.TimeKey("StartTime", &m.StartTime, time.RFC3339)
- if m.EndTime != nil {
- enc.TimeKey("EndTime", m.EndTime, time.RFC3339)
- }
-}
-
-// IsNil checks if instance is nil
-func (m *SubMessage) IsNil() bool {
- return m == nil
-}
-
-// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
-func (m *SubMessage) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
-
- switch k {
- case "Id":
- return dec.Int(&m.Id)
-
- case "Description":
- return dec.String(&m.Description)
-
- case "StartTime":
- var format = time.RFC3339
- var value = time.Time{}
- err := dec.DecodeTime(&value, format)
- if err == nil {
- m.StartTime = value
- }
- return err
-
- case "EndTime":
- var format = time.RFC3339
- var value = &time.Time{}
- err := dec.DecodeTime(value, format)
- if err == nil {
- m.EndTime = value
- }
- return err
-
- }
- return nil
-}
-
-// NKeys returns the number of keys to unmarshal
-func (m *SubMessage) NKeys() int { return 4 }
-
-// Reset reset fields
-func (m *SubMessage) Reset() {
- m.Id = 0
- m.Description = ""
- m.EndTime = nil
-}
diff --git a/gojay/gojaygen.go b/gojay/gojaygen.go
@@ -6,6 +6,7 @@ import (
"log"
)
+var pkg = flag.String("pkg", "", "the package name of the generated file")
var dst = flag.String("o", "", "destination file to output generated implementations")
var src = flag.String("s", "", "source dir or file (absolute or relative path)")
var types = flag.String("t", "", "types to generate")
@@ -15,8 +16,8 @@ var poolObjects = flag.String("p", "", "generate code to reuse objects using syn
func main() {
flag.Parse()
options := codegen.NewOptionsWithFlagSet(flag.CommandLine)
- gen := &codegen.Generator{}
- if err := gen.Generate(options); err != nil {
+ gen := codegen.NewGenerator(options)
+ if err := gen.Generate(); err != nil {
log.Fatal(err)
}
}