168 lines
4.1 KiB
Go
168 lines
4.1 KiB
Go
package gen
|
|
|
|
import (
|
|
"bytes"
|
|
"path"
|
|
|
|
"github.com/gedex/inflector"
|
|
qtpl "github.com/valyala/quicktemplate"
|
|
|
|
. "github.com/knq/chromedp/cmd/chromedp-gen/internal"
|
|
. "github.com/knq/chromedp/cmd/chromedp-gen/templates"
|
|
)
|
|
|
|
// fileBuffers is a type to manage buffers for file data.
|
|
type fileBuffers map[string]*bytes.Buffer
|
|
|
|
// GenerateDomains generates domains for the Chrome Debugging Protocol domain
|
|
// definitions, returning generated file buffers.
|
|
func GenerateDomains(domains []*Domain) map[string]*bytes.Buffer {
|
|
fb := make(fileBuffers)
|
|
|
|
var w *qtpl.Writer
|
|
|
|
// determine base (also used for the domains manager type name)
|
|
pkgBase := path.Base(*FlagPkg)
|
|
DomainTypeSuffix = inflector.Singularize(ForceCamel(pkgBase))
|
|
|
|
// generate internal types
|
|
fb.generateInternalTypes(domains)
|
|
|
|
// generate util package
|
|
fb.generateUtilPackage(domains)
|
|
|
|
// do individual domain templates
|
|
for _, d := range domains {
|
|
pkgName := d.PackageName()
|
|
pkgOut := pkgName + "/" + pkgName + ".go"
|
|
|
|
// do command template
|
|
w = fb.get(pkgOut, pkgName, d)
|
|
StreamDomainTemplate(w, d, domains)
|
|
fb.release(w)
|
|
|
|
// generate domain types
|
|
if len(d.Types) != 0 {
|
|
fb.generateTypes(
|
|
pkgName+"/types.go",
|
|
d.Types, TypePrefix, TypeSuffix, d, domains,
|
|
"", "", "", "", "",
|
|
)
|
|
}
|
|
|
|
// generate domain event types
|
|
if len(d.Events) != 0 {
|
|
fb.generateTypes(
|
|
pkgName+"/events.go",
|
|
d.Events, EventTypePrefix, EventTypeSuffix, d, domains,
|
|
"EventTypes", "MethodType", EventMethodPrefix+d.String(), EventMethodSuffix,
|
|
"EventTypes is all event types in the domain.",
|
|
)
|
|
}
|
|
}
|
|
|
|
return map[string]*bytes.Buffer(fb)
|
|
}
|
|
|
|
// generateInternalTypes generates the internal types for domain d.
|
|
//
|
|
// because there are circular package dependencies, some types need to be moved
|
|
// to the shared internal package.
|
|
func (fb fileBuffers) generateInternalTypes(domains []*Domain) {
|
|
pkg := path.Base(*FlagPkg)
|
|
w := fb.get(pkg+".go", pkg, nil)
|
|
|
|
for _, d := range domains {
|
|
// process internal types
|
|
for _, t := range d.Types {
|
|
if IsInternalType(d.Domain, t.IdOrName()) {
|
|
StreamTypeTemplate(w, t, TypePrefix, TypeSuffix, d, domains, nil, false, false)
|
|
}
|
|
}
|
|
}
|
|
|
|
fb.release(w)
|
|
}
|
|
|
|
// generateUtilPackage generates the util package.
|
|
//
|
|
// currently only contains the message unmarshaler: if this wasn't in a
|
|
// separate package, there would be circular dependencies.
|
|
func (fb fileBuffers) generateUtilPackage(domains []*Domain) {
|
|
// generate imports
|
|
importMap := map[string]string{
|
|
*FlagPkg: ".",
|
|
}
|
|
for _, d := range domains {
|
|
importMap[*FlagPkg+"/"+d.PackageName()] = d.PackageImportAlias()
|
|
}
|
|
|
|
w := fb.get("util/util.go", "util", nil)
|
|
StreamFileImportTemplate(w, importMap)
|
|
StreamExtraUtilTemplate(w, domains)
|
|
fb.release(w)
|
|
}
|
|
|
|
// generateTypes generates the types.
|
|
func (fb fileBuffers) generateTypes(
|
|
path string,
|
|
types []*Type, prefix, suffix string, d *Domain, domains []*Domain,
|
|
emit, emitType, emitPrefix, emitSuffix, emitDesc string,
|
|
) {
|
|
w := fb.get(path, d.PackageName(), d)
|
|
|
|
// add internal import
|
|
StreamFileLocalImportTemplate(w, *FlagPkg)
|
|
StreamFileEmptyVarTemplate(w, InternalTypeList()...)
|
|
|
|
// process type list
|
|
var names []string
|
|
for _, t := range types {
|
|
if IsInternalType(d.Domain, t.IdOrName()) {
|
|
continue
|
|
}
|
|
StreamTypeTemplate(w, t, prefix, suffix, d, domains, nil, false, false)
|
|
names = append(names, t.TypeName(emitPrefix, emitSuffix))
|
|
}
|
|
|
|
// emit var
|
|
if emit != "" {
|
|
s := "[]" + emitType + "{"
|
|
for _, n := range names {
|
|
s += "\n" + n + ","
|
|
}
|
|
s += "\n}"
|
|
StreamFileVarTemplate(w, emit, s, emitDesc)
|
|
}
|
|
|
|
fb.release(w)
|
|
}
|
|
|
|
// get retrieves the file buffer for s, or creates it if it is not yet available.
|
|
func (fb fileBuffers) get(s string, pkgName string, d *Domain) *qtpl.Writer {
|
|
// check if it already exists
|
|
if b, ok := fb[s]; ok {
|
|
return qtpl.AcquireWriter(b)
|
|
}
|
|
|
|
// create buffer
|
|
b := new(bytes.Buffer)
|
|
fb[s] = b
|
|
w := qtpl.AcquireWriter(b)
|
|
|
|
v := d
|
|
if b := path.Base(s); b != pkgName+".go" {
|
|
v = nil
|
|
}
|
|
|
|
// add package header
|
|
StreamFileHeader(w, pkgName, v)
|
|
|
|
return w
|
|
}
|
|
|
|
// release releases a template writer.
|
|
func (fb fileBuffers) release(w *qtpl.Writer) {
|
|
qtpl.ReleaseWriter(w)
|
|
}
|