Skip to content

Commit

Permalink
Reorganize Code Generation flags and Delete ygen.GeneratorConfig (#706
Browse files Browse the repository at this point in the history
)

* ygen now only has `IROptions`.
* `CodeGenerator` in gogen/protogen now carry IROptions and their language-specific post-IR generation options.
* Code generation specific flags that are not used during IR generation are moved to `gogen` and `protogen`, duplicating if used by both (e.g. CallerName).
* `SkipEnumDeduplication` is moved from ParseOptions to TransformationOptions.
  • Loading branch information
wenovus authored Jun 9, 2022
1 parent e27d9ba commit c2b34d5
Show file tree
Hide file tree
Showing 17 changed files with 944 additions and 806 deletions.
20 changes: 10 additions & 10 deletions demo/getting_started/interfaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,23 @@ var TestRoot string
func TestGenerateCode(t *testing.T) {
tests := []struct {
name string
inConfig *ygen.GeneratorConfig
inGoOpts *gogen.GoOpts
inIROpts ygen.IROptions
inGoOpts gogen.GoOpts
inFiles []string
inPaths []string
}{{
name: "openconfig interfaces",
inConfig: &ygen.GeneratorConfig{
inIROpts: ygen.IROptions{
ParseOptions: ygen.ParseOpts{
ExcludeModules: []string{"ietf-interfaces"},
},
TransformationOptions: ygen.TransformationOpts{
CompressBehaviour: genutil.PreferIntendedConfig,
GenerateFakeRoot: true,
},
GenerateJSONSchema: true,
},
inGoOpts: &gogen.GoOpts{
inGoOpts: gogen.GoOpts{
GenerateJSONSchema: true,
GenerateSimpleUnions: true,
},
inFiles: []string{
Expand All @@ -48,16 +48,16 @@ func TestGenerateCode(t *testing.T) {
inPaths: []string{filepath.Join(TestRoot, "yang")},
}, {
name: "openconfig interfaces with no compression",
inConfig: &ygen.GeneratorConfig{
inIROpts: ygen.IROptions{
ParseOptions: ygen.ParseOpts{
ExcludeModules: []string{"ietf-interfaces"},
},
TransformationOptions: ygen.TransformationOpts{
GenerateFakeRoot: true,
},
GenerateJSONSchema: true,
},
inGoOpts: &gogen.GoOpts{
inGoOpts: gogen.GoOpts{
GenerateJSONSchema: true,
GenerateSimpleUnions: true,
},
inFiles: []string{
Expand All @@ -68,10 +68,10 @@ func TestGenerateCode(t *testing.T) {
}}

for _, tt := range tests {
cg := gogen.NewCodeGenerator(tt.inConfig, tt.inGoOpts)
cg := gogen.New("", tt.inIROpts, tt.inGoOpts)
got, err := cg.Generate(tt.inFiles, tt.inPaths)
if err != nil {
t.Errorf("%s: Generate(%v, %v): Config: %v, got unexpected error: %v", tt.name, tt.inFiles, tt.inPaths, tt.inConfig, err)
t.Errorf("%s: Generate(%v, %v): Config: %v, got unexpected error: %v", tt.name, tt.inFiles, tt.inPaths, tt.inIROpts, err)
continue
}

Expand Down
44 changes: 23 additions & 21 deletions generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,29 +325,30 @@ func main() {
}

// Perform the code generation.
cg := gogen.NewCodeGenerator(&ygen.GeneratorConfig{
ParseOptions: ygen.ParseOpts{
ExcludeModules: modsExcluded,
SkipEnumDeduplication: *skipEnumDedup,
YANGParseOptions: yang.Options{
IgnoreSubmoduleCircularDependencies: *ignoreCircDeps,
cg := gogen.New(
"",
ygen.IROptions{
ParseOptions: ygen.ParseOpts{
ExcludeModules: modsExcluded,
YANGParseOptions: yang.Options{
IgnoreSubmoduleCircularDependencies: *ignoreCircDeps,
},
},
TransformationOptions: ygen.TransformationOpts{
CompressBehaviour: compressBehaviour,
GenerateFakeRoot: *generateFakeRoot,
FakeRootName: *fakeRootName,
SkipEnumDeduplication: *skipEnumDedup,
ShortenEnumLeafNames: *shortenEnumLeafNames,
EnumOrgPrefixesToTrim: enumOrgPrefixesToTrim,
UseDefiningModuleForTypedefEnumNames: *useDefiningModuleForTypedefEnumNames,
EnumerationsUseUnderscores: true,
},
},
TransformationOptions: ygen.TransformationOpts{
CompressBehaviour: compressBehaviour,
IgnoreShadowSchemaPaths: *ignoreShadowSchemaPaths,
GenerateFakeRoot: *generateFakeRoot,
FakeRootName: *fakeRootName,
ShortenEnumLeafNames: *shortenEnumLeafNames,
EnumOrgPrefixesToTrim: enumOrgPrefixesToTrim,
UseDefiningModuleForTypedefEnumNames: *useDefiningModuleForTypedefEnumNames,
EnumerationsUseUnderscores: true,
},
PackageName: *packageName,
GenerateJSONSchema: *generateSchema,
IncludeDescriptions: *includeDescriptions,
},
&gogen.GoOpts{
gogen.GoOpts{
PackageName: *packageName,
GenerateJSONSchema: *generateSchema,
IncludeDescriptions: *includeDescriptions,
YgotImportPath: *ygotImportPath,
YtypesImportPath: *ytypesImportPath,
GoyangImportPath: *goyangImportPath,
Expand All @@ -364,6 +365,7 @@ func main() {
GenerateSimpleUnions: *generateSimpleUnions,
IncludeModelData: *includeModelData,
AppendEnumSuffixForSimpleUnionEnums: *appendEnumSuffixForSimpleUnionEnums,
IgnoreShadowSchemaPaths: *ignoreShadowSchemaPaths,
},
)

Expand Down
57 changes: 34 additions & 23 deletions gogen/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,31 @@ import (
// CodeGenerator is a structure that is used to pass arguments as to
// how the output Go code should be generated.
type CodeGenerator struct {
// Config stores the configuration parameters used for code generation.
Config ygen.GeneratorConfig
// Caller is the name of the binary calling the generator library, it is
// included in the header of output files for debugging purposes. If a
// string is not specified, the location of the library is utilised.
Caller string
// IROptions stores the configuration parameters used for IR generation.
IROptions ygen.IROptions
// GoOptions stores a struct which stores Go code generation specific
// options for the code generaton.
// options for code generaton post IR generation.
GoOptions GoOpts
}

// GoOpts stores Go specific options for the code generation library.
type GoOpts struct {
// PackageName is the name that should be used for the generating package.
PackageName string
// GenerateJSONSchema stores a boolean which defines whether to generate
// the JSON corresponding to the YANG schema parsed to generate the
// output code.
GenerateJSONSchema bool
// IncludeDescriptions specifies that YANG entry descriptions are added
// to the JSON schema. Is false by default, to reduce the size of generated schema
IncludeDescriptions bool
// SchemaVarName is the name for the variable which stores the compressed
// JSON schema in the generated Go code. JSON schema output is only
// produced if the GenerateJSONSchema YANGCodeGenerator field is set to
// true.
// produced if the GenerateJSONSchema field is set to true.
SchemaVarName string
// GoyangImportPath specifies the path that should be used in the generated
// code for importing the goyang/pkg/yang package.
Expand Down Expand Up @@ -100,6 +112,10 @@ type GoOpts struct {
// only applies when useDefiningModuleForTypedefEnumNames is also set
// to true.
AppendEnumSuffixForSimpleUnionEnums bool
// IgnoreShadowSchemaPaths indicates whether when OpenConfig path
// compression is enabled, that the shadowed paths are to be ignored
// while while unmarshalling.
IgnoreShadowSchemaPaths bool
}

// GeneratedCode contains generated code snippets that can be processed by the calling
Expand Down Expand Up @@ -138,19 +154,14 @@ type GeneratedCode struct {
EnumTypeMap string
}

// NewCodeGenerator returns a new instance of the CodeGenerator
// New returns a new instance of the CodeGenerator
// struct to the calling function.
func NewCodeGenerator(c *ygen.GeneratorConfig, goopts *GoOpts) *CodeGenerator {
cg := &CodeGenerator{}

if c != nil {
cg.Config = *c
}
if goopts != nil {
cg.GoOptions = *goopts
func New(callerName string, opts ygen.IROptions, goOpts GoOpts) *CodeGenerator {
return &CodeGenerator{
Caller: callerName,
IROptions: opts,
GoOptions: goOpts,
}

return cg
}

// checkForBinaryKeys returns a non-empty list of errors if the input directory
Expand Down Expand Up @@ -186,8 +197,8 @@ func checkForBinaryKeys(dir *ygen.ParsedDirectory) []error {
// If errors are encountered during code generation, an error is returned.
func (cg *CodeGenerator) Generate(yangFiles, includePaths []string) (*GeneratedCode, util.Errors) {
opts := ygen.IROptions{
ParseOptions: cg.Config.ParseOptions,
TransformationOptions: cg.Config.TransformationOptions,
ParseOptions: cg.IROptions.ParseOptions,
TransformationOptions: cg.IROptions.TransformationOptions,
NestedDirectories: false,
AbsoluteMapPaths: false,
AppendEnumSuffixForSimpleUnionEnums: cg.GoOptions.AppendEnumSuffixForSimpleUnionEnums,
Expand All @@ -200,8 +211,8 @@ func (cg *CodeGenerator) Generate(yangFiles, includePaths []string) (*GeneratedC
}

var rootName string
if cg.Config.TransformationOptions.GenerateFakeRoot {
rootName = cg.Config.TransformationOptions.FakeRootName
if cg.IROptions.TransformationOptions.GenerateFakeRoot {
rootName = cg.IROptions.TransformationOptions.FakeRootName
if rootName == "" {
rootName = igenutil.DefaultRootName
}
Expand Down Expand Up @@ -239,7 +250,7 @@ func (cg *CodeGenerator) Generate(yangFiles, includePaths []string) (*GeneratedC
codegenErr = util.AppendErrs(codegenErr, errs)
continue
}
structOut, errs := writeGoStruct(dir, ir.Directories, generatedUnions, opts.TransformationOptions.IgnoreShadowSchemaPaths, cg.GoOptions, cg.Config.GenerateJSONSchema)
structOut, errs := writeGoStruct(dir, ir.Directories, generatedUnions, cg.GoOptions)
if errs != nil {
codegenErr = util.AppendErrs(codegenErr, errs)
continue
Expand Down Expand Up @@ -300,9 +311,9 @@ func (cg *CodeGenerator) Generate(yangFiles, includePaths []string) (*GeneratedC
var rawSchema []byte
var jsonSchema string
var enumTypeMapCode string
if cg.Config.GenerateJSONSchema {
if cg.GoOptions.GenerateJSONSchema {
var err error
rawSchema, err = ir.SchemaTree(cg.Config.IncludeDescriptions)
rawSchema, err = ir.SchemaTree(cg.GoOptions.IncludeDescriptions)
if err != nil {
codegenErr = util.AppendErr(codegenErr, fmt.Errorf("error marshalling JSON schema: %v", err))
}
Expand Down
Loading

0 comments on commit c2b34d5

Please sign in to comment.