blob: 8b5447d7a87aa7581864ee7527a7c36954f60b2e [file] [log] [blame] [edit]
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Codergen is a tool to parse go code and automatically generate encoders and
// decoders for the structs it finds.
package main
import (
"flag"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"android.googlesource.com/platform/tools/gpu/binary/generate"
"golang.org/x/tools/go/loader"
"golang.org/x/tools/go/types"
)
var (
golang = flag.String("go", "", "the go file to generate")
java = flag.String("java", "", "the java file to generate")
)
func filterStructs(pkg *loader.PackageInfo) []*types.TypeName {
result := []*types.TypeName{}
for _, def := range pkg.Defs {
name, ok := def.(*types.TypeName)
if !ok {
continue
}
t, ok := name.Type().(*types.Named)
if !ok {
continue
}
if _, ok := t.Underlying().(*types.Struct); !ok {
continue
}
result = append(result, name)
}
return result
}
func run() error {
flag.Parse()
config := loader.Config{SourceImports: true}
_, err := config.FromArgs(flag.Args(), false)
if err != nil {
return err
}
config.AllowErrors = true
info, err := config.Load()
if err != nil {
return err
}
file := generate.File{}
for _, pkg := range info.Created {
file.Package = pkg.Pkg.Name()
for _, name := range filterStructs(pkg) {
s := generate.FromTypename(pkg.Pkg, name)
if !s.Delegating {
file.Structs = append(file.Structs, s)
}
}
}
generate.Sort(file.Structs)
if *golang != "" {
file := file
file.Generated = fmt.Sprintf("codergen -go=%s", *golang)
result, err := generate.GoFile(&file)
if err != nil {
return err
}
err = ioutil.WriteFile(*golang, result, os.ModePerm)
if err != nil {
return err
}
}
if *java != "" {
file := file
file.Generated = fmt.Sprintf("codergen -java=%s", filepath.Base(*java))
// pick off the package part
smashed := strings.Split(*java, "/com/")
file.Package = "com." + strings.Replace(smashed[len(smashed)-1], "/", ".", -1)
filename := filepath.Join(*java, "ObjectFactory.java")
result, err := generate.JavaFile(&file)
if err != nil {
return err
}
err = ioutil.WriteFile(filename, result, os.ModePerm)
if err != nil {
return err
}
}
return nil
}
func main() {
if err := run(); err != nil {
fmt.Fprintf(os.Stderr, "codergen failed: %v\n", err)
os.Exit(1)
}
}