...

Source file src/github.com/gogo/protobuf/protoc-gen-combo/combo.go

Documentation: github.com/gogo/protobuf/protoc-gen-combo

     1  // Protocol Buffers for Go with Gadgets
     2  //
     3  // Copyright (c) 2013, The GoGo Authors. All rights reserved.
     4  // http://github.com/gogo/protobuf
     5  //
     6  // Redistribution and use in source and binary forms, with or without
     7  // modification, are permitted provided that the following conditions are
     8  // met:
     9  //
    10  //     * Redistributions of source code must retain the above copyright
    11  // notice, this list of conditions and the following disclaimer.
    12  //     * Redistributions in binary form must reproduce the above
    13  // copyright notice, this list of conditions and the following disclaimer
    14  // in the documentation and/or other materials provided with the
    15  // distribution.
    16  //
    17  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    18  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    19  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    20  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    21  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    22  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    23  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    24  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    25  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    26  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    27  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    28  
    29  package main
    30  
    31  import (
    32  	"bufio"
    33  	"bytes"
    34  	"flag"
    35  	"fmt"
    36  	"io/ioutil"
    37  	"os"
    38  	"os/exec"
    39  	"path/filepath"
    40  	"strings"
    41  
    42  	"github.com/gogo/protobuf/version"
    43  )
    44  
    45  type MixMatch struct {
    46  	Old      []string
    47  	Filename string
    48  	Args     []string
    49  }
    50  
    51  func (this MixMatch) Gen(folder string, news []string) {
    52  	if err := os.MkdirAll(folder, 0777); err != nil {
    53  		panic(err)
    54  	}
    55  	data, err := ioutil.ReadFile(this.Filename)
    56  	if err != nil {
    57  		panic(err)
    58  	}
    59  	content := string(data)
    60  	for i, old := range this.Old {
    61  		if !strings.Contains(content, old) {
    62  			panic(fmt.Errorf("could not find string {%s} to replace with {%s}", old, news[i]))
    63  		}
    64  		content = strings.Replace(content, old, news[i], 1)
    65  		if strings.Contains(content, old) && old != news[i] {
    66  			panic(fmt.Errorf("found another string {%s} after it was replaced with {%s}", old, news[i]))
    67  		}
    68  	}
    69  	if err = ioutil.WriteFile(filepath.Join(folder, this.Filename), []byte(content), 0666); err != nil {
    70  		panic(err)
    71  	}
    72  	args := append(this.Args, filepath.Join(folder, this.Filename))
    73  	var regenerate = exec.Command("protoc", args...)
    74  	out, err := regenerate.CombinedOutput()
    75  
    76  	failed := false
    77  	scanner := bufio.NewScanner(bytes.NewReader(out))
    78  	for scanner.Scan() {
    79  		text := scanner.Text()
    80  		fmt.Println("protoc-gen-combo: ", text)
    81  		if !strings.Contains(text, "WARNING") {
    82  			failed = true
    83  		}
    84  	}
    85  
    86  	if err != nil {
    87  		fmt.Print("protoc-gen-combo: error: ", err)
    88  		failed = true
    89  	}
    90  
    91  	if failed {
    92  		os.Exit(1)
    93  	}
    94  }
    95  
    96  func filter(ss []string, flag string) ([]string, string) {
    97  	s := make([]string, 0, len(ss))
    98  	var v string
    99  	for i := range ss {
   100  		if strings.Contains(ss[i], flag) {
   101  			vs := strings.Split(ss[i], "=")
   102  			v = vs[1]
   103  			continue
   104  		}
   105  		s = append(s, ss[i])
   106  	}
   107  	return s, v
   108  }
   109  
   110  func filterArgs(ss []string) ([]string, []string) {
   111  	var args []string
   112  	var flags []string
   113  	for i := range ss {
   114  		if strings.Contains(ss[i], "=") {
   115  			flags = append(flags, ss[i])
   116  			continue
   117  		}
   118  		args = append(args, ss[i])
   119  	}
   120  	return flags, args
   121  }
   122  
   123  func main() {
   124  	flag.String("version", "2.3.0", "minimum protoc version")
   125  	flag.Bool("default", true, "generate the case where everything is false")
   126  	flags, args := filterArgs(os.Args[1:])
   127  	var min string
   128  	flags, min = filter(flags, "-version")
   129  	if len(min) == 0 {
   130  		min = "2.3.1"
   131  	}
   132  	if !version.AtLeast(min) {
   133  		fmt.Printf("protoc version not high enough to parse this proto file\n")
   134  		return
   135  	}
   136  	if len(args) != 1 {
   137  		fmt.Printf("protoc-gen-combo expects a filename\n")
   138  		os.Exit(1)
   139  	}
   140  	filename := args[0]
   141  	var def string
   142  	flags, def = filter(flags, "-default")
   143  	if _, err := exec.LookPath("protoc"); err != nil {
   144  		panic("cannot find protoc in PATH")
   145  	}
   146  	m := MixMatch{
   147  		Old: []string{
   148  			"option (gogoproto.unmarshaler_all) = false;",
   149  			"option (gogoproto.marshaler_all) = false;",
   150  		},
   151  		Filename: filename,
   152  		Args:     flags,
   153  	}
   154  	if def != "false" {
   155  		m.Gen("./combos/neither/", []string{
   156  			"option (gogoproto.unmarshaler_all) = false;",
   157  			"option (gogoproto.marshaler_all) = false;",
   158  		})
   159  	}
   160  	m.Gen("./combos/marshaler/", []string{
   161  		"option (gogoproto.unmarshaler_all) = false;",
   162  		"option (gogoproto.marshaler_all) = true;",
   163  	})
   164  	m.Gen("./combos/unmarshaler/", []string{
   165  		"option (gogoproto.unmarshaler_all) = true;",
   166  		"option (gogoproto.marshaler_all) = false;",
   167  	})
   168  	m.Gen("./combos/both/", []string{
   169  		"option (gogoproto.unmarshaler_all) = true;",
   170  		"option (gogoproto.marshaler_all) = true;",
   171  	})
   172  }
   173  

View as plain text